The only available way to detect if an App is running in UWP:
const long APPMODEL_ERROR_NO_PACKAGE = 15700L;
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int GetCurrentPackageFullName(ref int packageFullNameLength, StringBuilder packageFullName);
public bool IsRunningAsUwp()
{
if (IsWindows7OrLower)
{
return false;
}
else
{
int length = 0;
StringBuilder sb = new StringBuilder(0);
int result = GetCurrentPackageFullName(ref length, sb);
sb = new StringBuilder(length);
result = GetCurrentPackageFullName(ref length, sb);
return result != APPMODEL_ERROR_NO_PACKAGE;
}
}
private bool IsWindows7OrLower
{
get
{
int versionMajor = Environment.OSVersion.Version.Major;
int versionMinor = Environment.OSVersion.Version.Minor;
double version = versionMajor + (double)versionMinor / 10;
return version <= 6.1;
}
}
Works in Debug builds, but fails in Release/.NET Native builds with a runtime TypeLoadException in the latest stable VS.NET 17.6 and now fails with a build time Exception with the latest VS.NET 17.8 Preview:
Microsoft SDKs\UWPNuGetPackages\microsoft.net.native.compiler\2.1.8\tools\Microsoft.NetNative.targets(788,5): warning : MCG : warning MCG0007: Unresolved P/Invoke method 'kernel32.dll!GetCurrentPackageFullName' for method 'System.Int32 ServiceStack.Text.Env.GetCurrentPackageFullName(System.Int32, System.Text.StringBuilder)'. Calling this method would throw exception at runtime. Please make sure the P/Invoke either points to a Windows API allowed in UWP applications, or a native DLL that is part of the package. If for some reason your P/Invoke does not satisfy those requirements, please use [DllImport(ExactSpelling=true) to indicate that you understand the implications of using non-UWP APIs.
What is the recommended way within a .NET Standard 2.0 .dll to determine if an App is running in UWP that works in both Debug and Release/.NET Native builds?
As the recommendation is to use .NET Standard 2.0 builds for creating compatible libraries across different platforms we need a reliable way to determine at runtime which platform the library is running on. Whilst this issue is for trying to detect UWP, we also need a way to detect if running on iOS/Android.
Although this issue doesn't specifically address being able to determine the running platform (e.g. iOS/Android/UWP), it covers why we need to detect Platform at runtime in platform-agnostic .NET Standard 2.0 builds:
Look at PlatformDetection.*.cs in this repo: you can check for both.NET Native and for whether you are in AppContainer (assuming that's good enough)
Can confirm the PlatformDetection works, thanks.
Note: the APIs to detect different platforms should be part of a .NET Standard 2.x as everyone has to come up with their own fragile heuristics which can fail over time. Only MS is going to know when new releases change internal behavior who would then be able to update their internal APIs accordingly, whilst the rest of us have to hope the fragile heuristics hold with each new Release on every platform.
Most helpful comment
Can confirm the PlatformDetection works, thanks.
Note: the APIs to detect different platforms should be part of a .NET Standard 2.x as everyone has to come up with their own fragile heuristics which can fail over time. Only MS is going to know when new releases change internal behavior who would then be able to update their internal APIs accordingly, whilst the rest of us have to hope the fragile heuristics hold with each new Release on every platform.