3

I'm writing a shared library in c++ that needs to work in both standard Win32 apps and Windows Store apps.

However for a particular bit of code I need to know if the DLL is loaded inside of a Windows Store app or not so that I can create a temporary file in the appropriate way.

I'm aware of several compile-time checks using code like #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) and the like, but is there a way to make this check at runtime?

lfalin
  • 4,219
  • 5
  • 31
  • 57

1 Answers1

2

Assuming by "Windows Store apps" you mean UWP apps

If you are going to use Win32 desktop APIs in the DLL, you cannot do the check at runtime. The WACK Windows Store submission tool examines the exports and imports for all EXEs and DLLs and will fail any use of APIs that are not in the Windows Store API partition.

You should read this article for recommendations on handling this kind of multi-targeting problem.

Ideally you'll get most of your DLL code to work 'as is' for Windows Store and then can use the same code for the Win32 desktop version, but likely you are also concerned about 'down-level' versions of the OS as well which necessitates using _WIN32_WINNT version guards in some cases. For example, you can't use CreateFile for Windows Store, and you can't use CreateFile2 on Windows 7.

 #if (_WIN32_WINNT >= 0x0602)
 HANDLE hFile = CreateFile2( szFile, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, nullptr );
 #else
 HANDLE hFile = CreateFile( szFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, nullptr );
 #endif
 if ( !hFile )
 {
     return HRESULT_FROM_WIN32( GetLastError() );
 }

Or you can use the CRT functions like fopen_s which abstracts this.

You can take a look at DirectXTex, DirectXTK, and DirectXMesh as code samples that utilize these techniques to build code for Windows Store for Windows 8.0, Windows Store for Windows 8.1, Windows Phone 8.0, Windows Phone 8.1, and Xbox One as well as Win32 desktop for Windows 8.x, Windows 7, and Windows Vista.

Remember also that Windows Store apps have a strict CRT requirement. Windows Store apps for Windows 8.0 must use VS 2012 CRT, and Windows Store apps for Windows 8.1 must use VS 2013 CRT.

Universal Windows Platform apps are similar to Windows Store, but have a few more APIs added back and some new alternatives for older Windows desktop functionality. You must use VS 2015 CRT, specifically the Universal CRT.

Assuming by "Windows Store apps" you mean a Win32 desktop application using the Desktop Bridge packaging for the Windows Store

See Microsoft Docs.

I would still suggest using the code pattern above in your source so as you move your minimum platform requirements over time, you prefer to use the API supported across multiple API families.

Chuck Walbourn
  • 38,259
  • 2
  • 58
  • 81
  • Note that it's possible to use any Windows API in a Windows Store application, including the mentioned CreateFile; you can publish native apps to the store. The reasons to detect if this app (DLL) runs (is loaded) from Store could be different - e.g., removing a UI that is not relevant to the store-packaged app (say, store package has own means to add itself to system Startup Apps applet, so the in-application UI that attempts to create shortcuts in shell:startup should be hidden). – Mike Kaganski Feb 25 '23 at 19:09
  • I was assuming the question was about targeting both Win32 desktop and UWP for Windows Store. There is a [Win32 desktop for Windows Store](https://developer.microsoft.com/en-us/microsoft-store/desktop-apps) solution as well (formerly known as "Project Centennial"), but the above code snippet is robust for all scenarios. – Chuck Walbourn Feb 25 '23 at 20:17
  • https://stackoverflow.com/a/52210994/1397376 looks to be a good solution. – Mike Kaganski Feb 25 '23 at 21:03
  • If it's a UWP application, then by definition the call to any unsupported API by the "Shared DLL" like ``CreateFile`` is going to fail to pass WACK, and can't be used in a UWP store app. – Chuck Walbourn Feb 26 '23 at 05:37
  • Chuck: yes. Still: 1. The question did not state "UWP" (the "appropriate way of creating a temporary file" is ambiguous, and might not only refer to the proper API, but also to proper places, etc.); 2. Having the reference to the other applicable topic with an answer could benefit people (like myself) who look for solutions of similar, but not identical, problems, arriving here from the search. – Mike Kaganski Feb 26 '23 at 08:53
  • Fair enough. The other thread is itself confusing calling it a "UWP app with legacy support". There's no such thing because if it's a UWP, it doesn't run on Windows 7 at all. That question is about how to tell from a Win32 desktop app if it's running as a "Windows Store packaged app" or not which is more properly called a "Desktop Bridge" app these days. – Chuck Walbourn Feb 26 '23 at 20:30