@@ -13,11 +13,30 @@ internal enum OperatingSystemType
1313 internal static class Platform
1414 {
1515 public static string ProcessorArchitecture => IntPtr . Size == 8 ? "x64" : "x86" ;
16+ #if NETFRAMEWORK
17+ private static bool ? _isRunningOnMac ;
18+ private static bool IsRunningOnMac ( ) => _isRunningOnMac ?? ( _isRunningOnMac = TryGetIsRunningOnMac ( ) ) ?? false ;
19+ #endif
1620
1721 public static OperatingSystemType OperatingSystem
1822 {
1923 get
2024 {
25+ #if NETFRAMEWORK
26+ var platform = ( int ) Environment . OSVersion . Platform ;
27+ if ( platform <= 3 || platform == 5 )
28+ {
29+ return OperatingSystemType . Windows ;
30+ }
31+ if ( IsRunningOnMac ( ) )
32+ {
33+ return OperatingSystemType . MacOSX ;
34+ }
35+ if ( platform == 4 || platform == 6 || platform == 128 )
36+ {
37+ return OperatingSystemType . Unix ;
38+ }
39+ #else
2140 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
2241 {
2342 return OperatingSystemType . Windows ;
@@ -32,7 +51,7 @@ public static OperatingSystemType OperatingSystem
3251 {
3352 return OperatingSystemType . MacOSX ;
3453 }
35-
54+ #endif
3655 throw new PlatformNotSupportedException ( ) ;
3756 }
3857 }
@@ -71,5 +90,70 @@ public static bool IsRunningOnNetFramework()
7190 /// </summary>
7291 public static bool IsRunningOnNetCore ( )
7392 => typeof ( object ) . Assembly . GetName ( ) . Name != "mscorlib" ;
93+
94+ #if NETFRAMEWORK
95+ #pragma warning disable IDE1006 // Naming Styles
96+ [ DllImport ( "libc" ) ]
97+ private static extern int sysctlbyname (
98+ [ MarshalAs ( UnmanagedType . LPStr ) ] string property ,
99+ IntPtr output ,
100+ IntPtr oldLen ,
101+ IntPtr newp ,
102+ uint newlen ) ;
103+ #pragma warning restore IDE1006 // Naming Styles
104+
105+ private static bool TryGetIsRunningOnMac ( )
106+ {
107+ const string OsType = "kern.ostype" ;
108+ const string MacOsType = "Darwin" ;
109+
110+ return MacOsType == GetOsType ( ) ;
111+
112+ string GetOsType ( )
113+ {
114+ try
115+ {
116+ IntPtr
117+ pointerLength = IntPtr . Zero ,
118+ pointerString = IntPtr . Zero ;
119+
120+ try
121+ {
122+ pointerLength = Marshal . AllocHGlobal ( sizeof ( int ) ) ;
123+
124+ sysctlbyname ( OsType , IntPtr . Zero , pointerLength , IntPtr . Zero , 0 ) ;
125+
126+ var length = Marshal . ReadInt32 ( pointerLength ) ;
127+
128+ if ( length <= 0 )
129+ {
130+ return string . Empty ;
131+ }
132+
133+ pointerString = Marshal . AllocHGlobal ( length ) ;
134+
135+ sysctlbyname ( OsType , pointerString , pointerLength , IntPtr . Zero , 0 ) ;
136+
137+ return Marshal . PtrToStringAnsi ( pointerString ) ;
138+ }
139+ finally
140+ {
141+ if ( pointerLength != IntPtr . Zero )
142+ {
143+ Marshal . FreeHGlobal ( pointerLength ) ;
144+ }
145+ if ( pointerString != IntPtr . Zero )
146+ {
147+ Marshal . FreeHGlobal ( pointerString ) ;
148+ }
149+ }
150+ }
151+ catch
152+ {
153+ return null ;
154+ }
155+ }
156+ }
157+ #endif
74158 }
75159}
0 commit comments