@@ -15,7 +15,11 @@ static Env()
1515 throw new ArgumentException ( "PclExport.Instance needs to be initialized" ) ;
1616
1717 var platformName = PclExport . Instance . PlatformName ;
18+
19+ #if NETSTANDARD2_0
1820 IsUWP = IsRunningAsUwp ( ) ;
21+ #endif
22+
1923 if ( ! IsUWP )
2024 {
2125 IsMono = AssemblyUtils . FindType ( "Mono.Runtime" ) != null ;
@@ -55,8 +59,7 @@ static Env()
5559 IsIOS = runtimeDir . StartsWith ( "/private/var" ) ||
5660 runtimeDir . Contains ( "/CoreSimulator/Devices/" ) ;
5761 }
58- IsNetNative = fxDesc . Contains ( ".NET Native" ) ;
59- IsNetCore = fxDesc . Contains ( ".NET Core" ) ;
62+ IsNetCore = fxDesc . StartsWith ( ".NET Core" , StringComparison . OrdinalIgnoreCase ) ;
6063 }
6164 catch ( Exception ) { } //throws PlatformNotSupportedException in AWS lambda
6265 IsUnix = IsOSX || IsLinux ;
@@ -68,14 +71,16 @@ static Env()
6871 IsLinux = IsUnix ;
6972 if ( Environment . GetEnvironmentVariable ( "OS" ) ? . IndexOf ( "Windows" , StringComparison . OrdinalIgnoreCase ) >= 0 )
7073 IsWindows = true ;
74+ SupportsDynamic = true ;
7175#elif NETCORE2_1
7276 IsNetCore = true ;
77+ SupportsDynamic = true ;
7378#endif
7479
75- SupportsExpressions = ! IsIOS ;
76- SupportsEmit = ! IsIOS && ! IsUWP ;
80+ SupportsExpressions = true ;
81+ SupportsEmit = ! ( IsUWP || IsIOS ) ;
7782
78- if ( IsNetNative || IsIOS )
83+ if ( ! SupportsEmit )
7984 {
8085 ReflectionOptimizer . Instance = ExpressionReflectionOptimizer . Provider ;
8186 }
@@ -110,7 +115,7 @@ static Env()
110115
111116 public static bool IsNetNative { get ; set ; }
112117
113- public static bool IsUWP { get ; set ; }
118+ public static bool IsUWP { get ; private set ; }
114119
115120 public static bool IsNetStandard { get ; set ; }
116121
@@ -122,6 +127,8 @@ static Env()
122127
123128 public static bool SupportsEmit { get ; private set ; }
124129
130+ public static bool SupportsDynamic { get ; private set ; }
131+
125132 public static bool StrictMode { get ; set ; }
126133
127134 public static string ServerUserAgent { get ; set ; }
@@ -177,26 +184,18 @@ public static string ReferenceAssembyPath
177184 set => referenceAssembyPath = value ;
178185 }
179186
187+ #if NETSTANDARD2_0
180188 private static bool IsRunningAsUwp ( )
181189 {
182- //TODO: find a more reliable way to detect UWP https://github.com/dotnet/corefx/issues/31599
183- #if NETSTANDARD2_0
184190 try
185191 {
186- if ( IsWindows7OrLower )
187- return false ;
188-
189- var isWin = System . Runtime . InteropServices . RuntimeInformation . IsOSPlatform ( System . Runtime . InteropServices . OSPlatform . Windows ) ;
190- var fxDesc = System . Runtime . InteropServices . RuntimeInformation . FrameworkDescription ;
191- var isNetNative = fxDesc . Contains ( ".NET Native" ) ;
192- var onlyInDebugType = Type . GetType ( "System.Runtime.InteropServices.WindowsRuntime.IActivationFactory,System.Runtime.InteropServices.WindowsRuntime" ) ;
193- return isWin && ( isNetNative || onlyInDebugType != null ) ;
192+ IsNetNative = System . Runtime . InteropServices . RuntimeInformation . FrameworkDescription . StartsWith ( ".NET Native" , StringComparison . OrdinalIgnoreCase ) ;
193+ return IsInAppContainer || IsNetNative ;
194194 }
195- catch ( Exception ) { } //throws PlatformNotSupportedException in AWS lambda
196- #endif
195+ catch ( Exception ) { }
197196 return false ;
198197 }
199-
198+
200199 private static bool IsWindows7OrLower
201200 {
202201 get
@@ -207,42 +206,70 @@ private static bool IsWindows7OrLower
207206 return version <= 6.1 ;
208207 }
209208 }
210-
211- /* Only way to determine if .NET Standard 2.0 .dll is running in UWP is now a build error from VS.NET 15.8 Preview
212-
213- //https://blogs.msdn.microsoft.com/appconsult/2016/11/03/desktop-bridge-identify-the-applications-context/
214- //https://github.com/qmatteoq/DesktopBridgeHelpers/blob/master/DesktopBridge.Helpers/Helpers.cs
215- const long APPMODEL_ERROR_NO_PACKAGE = 15700L;
216-
217- [System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode, SetLastError = true, ExactSpelling = true)]
218- static extern int GetCurrentPackageFullName(ref int packageFullNameLength, System.Text.StringBuilder packageFullName);
219-
220- private static bool IsRunningAsUwp()
209+
210+ // From: https://github.com/dotnet/corefx/blob/master/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs
211+ private static int s_isInAppContainer = - 1 ;
212+ private static bool IsInAppContainer
221213 {
222- try
214+ // This actually checks whether code is running in a modern app.
215+ // Currently this is the only situation where we run in app container.
216+ // If we want to distinguish the two cases in future,
217+ // EnvironmentHelpers.IsAppContainerProcess in desktop code shows how to check for the AC token.
218+ get
223219 {
224- if (IsWindows7OrLower )
225- return false ;
220+ if ( s_isInAppContainer != - 1 )
221+ return s_isInAppContainer == 1 ;
226222
227- int length = 0;
228- var sb = new System.Text.StringBuilder(0);
229- int result = GetCurrentPackageFullName(ref length, sb);
223+ if ( ! IsWindows || IsWindows7OrLower )
224+ {
225+ s_isInAppContainer = 0 ;
226+ return false ;
227+ }
230228
231- sb = new System.Text.StringBuilder(length);
232- result = GetCurrentPackageFullName(ref length, sb);
229+ byte [ ] buffer = TypeConstants . EmptyByteArray ;
230+ uint bufferSize = 0 ;
231+ try
232+ {
233+ int result = GetCurrentApplicationUserModelId ( ref bufferSize , buffer ) ;
234+ switch ( result )
235+ {
236+ case 15703 : // APPMODEL_ERROR_NO_APPLICATION
237+ s_isInAppContainer = 0 ;
238+ break ;
239+ case 0 : // ERROR_SUCCESS
240+ case 122 : // ERROR_INSUFFICIENT_BUFFER
241+ // Success is actually insufficent buffer as we're really only looking for
242+ // not NO_APPLICATION and we're not actually giving a buffer here. The
243+ // API will always return NO_APPLICATION if we're not running under a
244+ // WinRT process, no matter what size the buffer is.
245+ s_isInAppContainer = 1 ;
246+ break ;
247+ default :
248+ throw new InvalidOperationException ( $ "Failed to get AppId, result was { result } .") ;
249+ }
250+ }
251+ catch ( Exception e )
252+ {
253+ // We could catch this here, being friendly with older portable surface area should we
254+ // desire to use this method elsewhere.
255+ if ( e . GetType ( ) . FullName . Equals ( "System.EntryPointNotFoundException" , StringComparison . Ordinal ) )
256+ {
257+ // API doesn't exist, likely pre Win8
258+ s_isInAppContainer = 0 ;
259+ }
260+ else
261+ {
262+ throw ;
263+ }
264+ }
233265
234- return result != APPMODEL_ERROR_NO_PACKAGE;
235- }
236- catch (TypeLoadException e) //of course the recommended code to detect UWP fails in .NET Native UWP
237- {
238- return IsWindows && IsNetNative;
239- }
240- catch (Exception e)
241- {
242- return false;
266+ return s_isInAppContainer == 1 ;
243267 }
244268 }
245- */
269+
270+ [ System . Runtime . InteropServices . DllImport ( "kernel32.dll" , ExactSpelling = true ) ]
271+ private static extern int GetCurrentApplicationUserModelId ( ref uint applicationUserModelIdLength , byte [ ] applicationUserModelId ) ;
272+ #endif
246273
247274 }
248275}
0 commit comments