1 //------------------------------------------------------------------------------
3 // System.Environment.cs
5 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
7 // Author: Jim Richardson, develop@wtfo-guru.com
8 // Dan Lewis (dihlewis@yahoo.co.uk)
9 // Created: Saturday, August 11, 2001
11 //------------------------------------------------------------------------------
13 // Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
36 using System.Collections;
37 using System.Runtime.CompilerServices;
38 using System.Security;
39 using System.Security.Permissions;
41 using System.Runtime.InteropServices;
42 using System.Threading;
47 public static partial class Environment {
50 * This is the version number of the corlib-runtime interface. When
51 * making changes to this interface (by changing the layout
52 * of classes the runtime knows about, changing icall signature or
53 * semantics etc), increment this variable. Also increment the
54 * pair of this variable in the runtime in metadata/appdomain.c.
55 * Changes which are already detected at runtime, like the addition
56 * of icalls, do not require an increment.
58 #pragma warning disable 169
59 private const int mono_corlib_version = 113;
60 #pragma warning restore 169
63 public enum SpecialFolder
76 DesktopDirectory = 0x10,
78 ApplicationData = 0x1a,
79 LocalApplicationData = 0x1c,
83 CommonApplicationData = 0x23,
87 CommonProgramFiles = 0x2b,
89 NetworkShortcuts = 0x13,
91 CommonStartMenu = 0x16,
92 CommonPrograms = 0x17,
94 CommonDesktopDirectory = 0x19,
95 PrinterShortcuts = 0x1b,
99 ProgramFilesX86 = 0x2a,
100 CommonProgramFilesX86 = 0x2c,
101 CommonTemplates = 0x2d,
102 CommonDocuments = 0x2e,
103 CommonAdminTools = 0x2f,
106 CommonPictures = 0x36,
109 LocalizedResources = 0x39,
110 CommonOemLinks = 0x3a,
115 enum SpecialFolderOption {
117 DoNotVerify = 0x4000,
122 /// Gets the command line for this process
124 public static string CommandLine {
125 // note: security demand inherited from calling GetCommandLineArgs
127 StringBuilder sb = new StringBuilder ();
128 foreach (string str in GetCommandLineArgs ()) {
132 for (int i = 0; i < s.Length; i++) {
133 if (quote.Length == 0 && Char.IsWhiteSpace (s [i])) {
135 } else if (s [i] == '"') {
139 if (escape && quote.Length != 0) {
140 s = s.Replace ("\"", "\\\"");
142 sb.AppendFormat ("{0}{1}{0} ", quote, s);
146 return sb.ToString ();
151 /// Gets or sets the current directory. Actually this is supposed to get
152 /// and/or set the process start directory acording to the documentation
153 /// but actually test revealed at beta2 it is just Getting/Setting the CurrentDirectory
155 public static string CurrentDirectory
158 return Directory.GetCurrentDirectory ();
161 Directory.SetCurrentDirectory (value);
166 public static int CurrentManagedThreadId {
168 return Thread.CurrentThread.ManagedThreadId;
174 /// Gets or sets the exit code of this process
176 public extern static int ExitCode
178 [MethodImplAttribute (MethodImplOptions.InternalCall)]
180 [MethodImplAttribute (MethodImplOptions.InternalCall)]
184 static public extern bool HasShutdownStarted
186 [MethodImplAttribute (MethodImplOptions.InternalCall)]
192 /// Gets the name of the local computer
194 public extern static string MachineName {
195 [MethodImplAttribute (MethodImplOptions.InternalCall)]
196 [EnvironmentPermission (SecurityAction.Demand, Read="COMPUTERNAME")]
197 [SecurityPermission (SecurityAction.Demand, UnmanagedCode=true)]
201 [MethodImplAttribute (MethodImplOptions.InternalCall)]
202 extern static string GetNewLine ();
206 /// Gets the standard new line value
208 public static string NewLine {
219 // Support methods and fields for OSVersion property
221 static OperatingSystem os;
223 static extern PlatformID Platform {
224 [MethodImplAttribute (MethodImplOptions.InternalCall)]
228 [MethodImplAttribute (MethodImplOptions.InternalCall)]
229 internal static extern string GetOSVersionString ();
232 /// Gets the current OS version information
234 public static OperatingSystem OSVersion {
237 Version v = Version.CreateFromString (GetOSVersionString ());
238 PlatformID p = Platform;
239 if (p == PlatformID.MacOSX)
241 os = new OperatingSystem (p, v);
250 public static string StackTrace {
251 [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
253 System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace (0, true);
254 return trace.ToString ();
259 /// Get a fully qualified path to the system directory
261 public static string SystemDirectory {
263 return GetFolderPath (SpecialFolder.System);
268 /// Get the number of milliseconds that have elapsed since the system was booted
270 public extern static int TickCount {
271 [MethodImplAttribute (MethodImplOptions.InternalCall)]
276 /// Get UserDomainName
278 public static string UserDomainName {
279 // FIXME: this variable doesn't exist (at least not on WinXP) - reported to MS as FDBK20562
280 [EnvironmentPermission (SecurityAction.Demand, Read="USERDOMAINNAME")]
287 /// Gets a flag indicating whether the process is in interactive mode
289 [MonoTODO ("Currently always returns false, regardless of interactive state")]
290 public static bool UserInteractive {
297 /// Get the user name of current process is running under
299 public extern static string UserName {
300 [MethodImplAttribute (MethodImplOptions.InternalCall)]
301 [EnvironmentPermission (SecurityAction.Demand, Read="USERNAME;USER")]
306 /// Get the version of the common language runtime
308 public static Version Version {
310 return new Version (Consts.FxFileVersion);
315 /// Get the amount of physical memory mapped to process
317 [MonoTODO ("Currently always returns zero")]
318 public static long WorkingSet {
319 [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
323 [MethodImplAttribute (MethodImplOptions.InternalCall)]
324 [SecurityPermission (SecurityAction.Demand, UnmanagedCode=true)]
325 public extern static void Exit (int exitCode);
328 /// Substitute environment variables in the argument "name"
330 public static string ExpandEnvironmentVariables (string name)
333 throw new ArgumentNullException ("name");
335 int off1 = name.IndexOf ('%');
339 int len = name.Length;
341 if (off1 == len - 1 || (off2 = name.IndexOf ('%', off1 + 1)) == -1)
344 StringBuilder result = new StringBuilder ();
345 result.Append (name, 0, off1);
346 Hashtable tbl = null;
348 string var = name.Substring (off1 + 1, off2 - off1 - 1);
349 string value = GetEnvironmentVariable (var);
350 if (value == null && Environment.IsRunningOnWindows) {
351 // On windows, env. vars. are case insensitive
353 tbl = GetEnvironmentVariablesNoCase ();
355 value = tbl [var] as string;
358 // If value not found, add %FOO to stream,
359 // and use the closing % for the next iteration.
360 // If value found, expand it in place of %FOO%
361 int realOldOff2 = off2;
367 result.Append (value);
370 off1 = name.IndexOf ('%', off2 + 1);
371 // If no % found for off1, don't look for one for off2
372 off2 = (off1 == -1 || off2 > len-1)? -1 :name.IndexOf ('%', off1 + 1);
373 // textLen is the length of text between the closing % of current iteration
374 // and the starting % of the next iteration if any. This text is added to output
376 // If no new % found, use all the remaining text
377 if (off1 == -1 || off2 == -1)
378 textLen = len - oldOff2 - 1;
379 // If value found in current iteration, use text after current closing % and next %
380 else if(value != null)
381 textLen = off1 - oldOff2 - 1;
382 // If value not found in current iteration, but a % was found for next iteration,
383 // use text from current closing % to the next %.
385 textLen = off1 - realOldOff2;
386 if(off1 >= oldOff2 || off1 == -1)
387 result.Append (name, oldOff2+1, textLen);
388 } while (off2 > -1 && off2 < len);
390 return result.ToString ();
395 /// Return an array of the command line arguments of the current process
397 [MethodImplAttribute (MethodImplOptions.InternalCall)]
398 [EnvironmentPermissionAttribute (SecurityAction.Demand, Read = "PATH")]
399 public extern static string[] GetCommandLineArgs ();
401 [MethodImplAttribute (MethodImplOptions.InternalCall)]
402 internal extern static string internalGetEnvironmentVariable (string variable);
405 /// Return a string containing the value of the environment
406 /// variable identifed by parameter "variable"
408 public static string GetEnvironmentVariable (string variable)
411 if (SecurityManager.SecurityEnabled) {
412 new EnvironmentPermission (EnvironmentPermissionAccess.Read, variable).Demand ();
415 return internalGetEnvironmentVariable (variable);
418 static Hashtable GetEnvironmentVariablesNoCase ()
420 Hashtable vars = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
421 CaseInsensitiveComparer.Default);
423 foreach (string name in GetEnvironmentVariableNames ()) {
424 vars [name] = internalGetEnvironmentVariable (name);
431 /// Return a set of all environment variables and their values
434 public static IDictionary GetEnvironmentVariables ()
436 StringBuilder sb = null;
437 if (SecurityManager.SecurityEnabled) {
438 // we must have access to each variable to get the lot
439 sb = new StringBuilder ();
440 // but (performance-wise) we do not want a stack-walk
441 // for each of them so we concatenate them
444 Hashtable vars = new Hashtable ();
445 foreach (string name in GetEnvironmentVariableNames ()) {
446 vars [name] = internalGetEnvironmentVariable (name);
454 new EnvironmentPermission (EnvironmentPermissionAccess.Read, sb.ToString ()).Demand ();
459 [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
460 public static IDictionary GetEnvironmentVariables ()
462 Hashtable vars = new Hashtable ();
463 foreach (string name in GetEnvironmentVariableNames ()) {
464 vars [name] = internalGetEnvironmentVariable (name);
471 /// Returns the fully qualified path of the
472 /// folder specified by the "folder" parameter
474 public static string GetFolderPath (SpecialFolder folder)
476 return GetFolderPath (folder, SpecialFolderOption.None);
479 // for monotouch, not monotouch_runtime
480 #if !(MONOTOUCH && FULL_AOT_RUNTIME)
481 [MethodImplAttribute (MethodImplOptions.InternalCall)]
482 private extern static string GetWindowsFolderPath (int folder);
485 static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option)
487 SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
491 if (Environment.IsRunningOnWindows)
492 dir = GetWindowsFolderPath ((int) folder);
494 dir = UnixGetFolderPath (folder, option);
497 if ((dir != null) && (dir.Length > 0) && SecurityManager.SecurityEnabled) {
498 new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dir).Demand ();
504 private static string ReadXdgUserDir (string config_dir, string home_dir, string key, string fallback)
506 string env_path = internalGetEnvironmentVariable (key);
507 if (env_path != null && env_path != String.Empty) {
511 string user_dirs_path = Path.Combine (config_dir, "user-dirs.dirs");
513 if (!File.Exists (user_dirs_path)) {
514 return Path.Combine (home_dir, fallback);
518 using(StreamReader reader = new StreamReader (user_dirs_path)) {
520 while ((line = reader.ReadLine ()) != null) {
522 int delim_index = line.IndexOf ('=');
523 if(delim_index > 8 && line.Substring (0, delim_index) == key) {
524 string path = line.Substring (delim_index + 1).Trim ('"');
525 bool relative = false;
527 if (path.StartsWithOrdinalUnchecked ("$HOME/")) {
529 path = path.Substring (6);
530 } else if (!path.StartsWithOrdinalUnchecked ("/")) {
534 return relative ? Path.Combine (home_dir, path) : path;
538 } catch (FileNotFoundException) {
541 return Path.Combine (home_dir, fallback);
545 // the security runtime (and maybe other parts of corlib) needs the
546 // information to initialize themselves before permissions can be checked
547 internal static string UnixGetFolderPath (SpecialFolder folder, SpecialFolderOption option)
549 string home = internalGetHome ();
551 // http://freedesktop.org/Standards/basedir-spec/basedir-spec-0.6.html
553 // note: skip security check for environment variables
554 string data = internalGetEnvironmentVariable ("XDG_DATA_HOME");
555 if ((data == null) || (data == String.Empty)) {
556 data = Path.Combine (home, ".local");
557 data = Path.Combine (data, "share");
560 // note: skip security check for environment variables
561 string config = internalGetEnvironmentVariable ("XDG_CONFIG_HOME");
562 if ((config == null) || (config == String.Empty)) {
563 config = Path.Combine (home, ".config");
567 // MyComputer is a virtual directory
568 case SpecialFolder.MyComputer:
572 case SpecialFolder.Personal:
575 // use FDO's CONFIG_HOME. This data will be synced across a network like the windows counterpart.
576 case SpecialFolder.ApplicationData:
579 //use FDO's DATA_HOME. This is *NOT* synced
580 case SpecialFolder.LocalApplicationData:
583 case SpecialFolder.Desktop:
584 case SpecialFolder.DesktopDirectory:
585 return ReadXdgUserDir (config, home, "XDG_DESKTOP_DIR", "Desktop");
587 case SpecialFolder.MyMusic:
588 if (Platform == PlatformID.MacOSX)
589 return Path.Combine (home, "Music");
591 return ReadXdgUserDir (config, home, "XDG_MUSIC_DIR", "Music");
593 case SpecialFolder.MyPictures:
594 if (Platform == PlatformID.MacOSX)
595 return Path.Combine (home, "Pictures");
597 return ReadXdgUserDir (config, home, "XDG_PICTURES_DIR", "Pictures");
599 case SpecialFolder.Templates:
600 return ReadXdgUserDir (config, home, "XDG_TEMPLATES_DIR", "Templates");
601 case SpecialFolder.MyVideos:
602 return ReadXdgUserDir (config, home, "XDG_VIDEOS_DIR", "Videos");
603 case SpecialFolder.CommonTemplates:
604 return "/usr/share/templates";
605 case SpecialFolder.Fonts:
606 if (Platform == PlatformID.MacOSX)
607 return Path.Combine (home, "Library", "Fonts");
609 return Path.Combine (home, ".fonts");
610 // these simply dont exist on Linux
611 // The spec says if a folder doesnt exist, we
613 case SpecialFolder.Favorites:
614 if (Platform == PlatformID.MacOSX)
615 return Path.Combine (home, "Library", "Favorites");
619 case SpecialFolder.ProgramFiles:
620 if (Platform == PlatformID.MacOSX)
621 return "/Applications";
625 case SpecialFolder.InternetCache:
626 if (Platform == PlatformID.MacOSX)
627 return Path.Combine (home, "Library", "Caches");
632 case SpecialFolder.UserProfile:
635 case SpecialFolder.Programs:
636 case SpecialFolder.SendTo:
637 case SpecialFolder.StartMenu:
638 case SpecialFolder.Startup:
639 case SpecialFolder.Cookies:
640 case SpecialFolder.History:
641 case SpecialFolder.Recent:
642 case SpecialFolder.CommonProgramFiles:
643 case SpecialFolder.System:
644 case SpecialFolder.NetworkShortcuts:
645 case SpecialFolder.CommonStartMenu:
646 case SpecialFolder.CommonPrograms:
647 case SpecialFolder.CommonStartup:
648 case SpecialFolder.CommonDesktopDirectory:
649 case SpecialFolder.PrinterShortcuts:
650 case SpecialFolder.Windows:
651 case SpecialFolder.SystemX86:
652 case SpecialFolder.ProgramFilesX86:
653 case SpecialFolder.CommonProgramFilesX86:
654 case SpecialFolder.CommonDocuments:
655 case SpecialFolder.CommonAdminTools:
656 case SpecialFolder.AdminTools:
657 case SpecialFolder.CommonMusic:
658 case SpecialFolder.CommonPictures:
659 case SpecialFolder.CommonVideos:
660 case SpecialFolder.Resources:
661 case SpecialFolder.LocalizedResources:
662 case SpecialFolder.CommonOemLinks:
663 case SpecialFolder.CDBurning:
665 // This is where data common to all users goes
666 case SpecialFolder.CommonApplicationData:
669 throw new ArgumentException ("Invalid SpecialFolder");
675 [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
676 public static string[] GetLogicalDrives ()
678 return GetLogicalDrivesInternal ();
682 [MethodImplAttribute (MethodImplOptions.InternalCall)]
683 private static extern void internalBroadcastSettingChange ();
685 public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
688 case EnvironmentVariableTarget.Process:
689 return GetEnvironmentVariable (variable);
690 case EnvironmentVariableTarget.Machine:
691 new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
692 if (!IsRunningOnWindows)
694 using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
695 object regvalue = env.GetValue (variable);
696 return (regvalue == null) ? null : regvalue.ToString ();
698 case EnvironmentVariableTarget.User:
699 new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
700 if (!IsRunningOnWindows)
702 using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.CurrentUser.OpenSubKey ("Environment", false)) {
703 object regvalue = env.GetValue (variable);
704 return (regvalue == null) ? null : regvalue.ToString ();
707 throw new ArgumentException ("target");
711 public static IDictionary GetEnvironmentVariables (EnvironmentVariableTarget target)
713 IDictionary variables = (IDictionary)new Hashtable ();
715 case EnvironmentVariableTarget.Process:
716 variables = GetEnvironmentVariables ();
718 case EnvironmentVariableTarget.Machine:
719 new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
720 if (IsRunningOnWindows) {
721 using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
722 string[] value_names = env.GetValueNames ();
723 foreach (string value_name in value_names)
724 variables.Add (value_name, env.GetValue (value_name));
728 case EnvironmentVariableTarget.User:
729 new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
730 if (IsRunningOnWindows) {
731 using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.CurrentUser.OpenSubKey ("Environment")) {
732 string[] value_names = env.GetValueNames ();
733 foreach (string value_name in value_names)
734 variables.Add (value_name, env.GetValue (value_name));
739 throw new ArgumentException ("target");
744 [EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
745 public static void SetEnvironmentVariable (string variable, string value)
747 SetEnvironmentVariable (variable, value, EnvironmentVariableTarget.Process);
750 [EnvironmentPermission (SecurityAction.Demand, Unrestricted = true)]
751 public static void SetEnvironmentVariable (string variable, string value, EnvironmentVariableTarget target)
753 if (variable == null)
754 throw new ArgumentNullException ("variable");
755 if (variable == String.Empty)
756 throw new ArgumentException ("String cannot be of zero length.", "variable");
757 if (variable.IndexOf ('=') != -1)
758 throw new ArgumentException ("Environment variable name cannot contain an equal character.", "variable");
759 if (variable[0] == '\0')
760 throw new ArgumentException ("The first char in the string is the null character.", "variable");
763 case EnvironmentVariableTarget.Process:
764 InternalSetEnvironmentVariable (variable, value);
766 case EnvironmentVariableTarget.Machine:
767 if (!IsRunningOnWindows)
769 using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true)) {
770 if (String.IsNullOrEmpty (value))
771 env.DeleteValue (variable, false);
773 env.SetValue (variable, value);
774 internalBroadcastSettingChange ();
777 case EnvironmentVariableTarget.User:
778 if (!IsRunningOnWindows)
780 using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.CurrentUser.OpenSubKey ("Environment", true)) {
781 if (String.IsNullOrEmpty (value))
782 env.DeleteValue (variable, false);
784 env.SetValue (variable, value);
785 internalBroadcastSettingChange ();
789 throw new ArgumentException ("target");
793 public static void SetEnvironmentVariable (string variable, string value)
795 if (variable == null)
796 throw new ArgumentNullException ("variable");
797 if (variable == String.Empty)
798 throw new ArgumentException ("String cannot be of zero length.", "variable");
799 if (variable.IndexOf ('=') != -1)
800 throw new ArgumentException ("Environment variable name cannot contain an equal character.", "variable");
801 if (variable[0] == '\0')
802 throw new ArgumentException ("The first char in the string is the null character.", "variable");
804 InternalSetEnvironmentVariable (variable, value);
807 [MethodImplAttribute (MethodImplOptions.InternalCall)]
808 internal static extern void InternalSetEnvironmentVariable (string variable, string value);
810 [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode=true)]
811 public static void FailFast (string message)
813 throw new NotImplementedException ();
817 public static void FailFast (string message, Exception exception)
819 throw new NotImplementedException ();
822 public static bool Is64BitOperatingSystem {
823 get { return IntPtr.Size == 8; } // FIXME: is this good enough?
826 public static int SystemPageSize {
827 get { return GetPageSize (); }
831 static bool Is64BitProcess {
832 get { return IntPtr.Size == 8; }
835 public static extern int ProcessorCount {
836 [EnvironmentPermission (SecurityAction.Demand, Read="NUMBER_OF_PROCESSORS")]
837 [MethodImplAttribute (MethodImplOptions.InternalCall)]
842 #if (MONOTOUCH || MONODROID || XAMMAC)
843 internal const bool IsRunningOnWindows = false;
845 internal static bool IsRunningOnWindows {
846 get { return ((int) Platform < 4); }
852 // Used by gacutil.exe
854 #pragma warning disable 169
855 private static string GacPath {
857 if (Environment.IsRunningOnWindows) {
858 /* On windows, we don't know the path where mscorlib.dll will be installed */
859 string corlibDir = new DirectoryInfo (Path.GetDirectoryName (typeof (int).Assembly.Location)).Parent.Parent.FullName;
860 return Path.Combine (Path.Combine (corlibDir, "mono"), "gac");
863 return Path.Combine (Path.Combine (internalGetGacPath (), "mono"), "gac");
866 #pragma warning restore 169
867 [MethodImplAttribute (MethodImplOptions.InternalCall)]
868 internal extern static string internalGetGacPath ();
870 [MethodImplAttribute (MethodImplOptions.InternalCall)]
871 private extern static string [] GetLogicalDrivesInternal ();
873 [MethodImplAttribute (MethodImplOptions.InternalCall)]
874 private extern static string [] GetEnvironmentVariableNames ();
876 [MethodImplAttribute (MethodImplOptions.InternalCall)]
877 internal extern static string GetMachineConfigPath ();
879 [MethodImplAttribute (MethodImplOptions.InternalCall)]
880 internal extern static string internalGetHome ();
882 [MethodImplAttribute (MethodImplOptions.InternalCall)]
883 internal extern static int GetPageSize ();
885 static internal bool IsUnix {
887 int platform = (int) Environment.Platform;
889 return (platform == 4 || platform == 128 || platform == 6);
892 static internal bool IsMacOS {
894 return Environment.Platform == PlatformID.MacOSX;