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
;
43 using System
.Diagnostics
.Contracts
;
48 public static partial class Environment
{
51 * This is the version number of the corlib-runtime interface. When
52 * making changes to this interface (by changing the layout
53 * of classes the runtime knows about, changing icall signature or
54 * semantics etc), increment this variable. Also increment the
55 * pair of this variable in the runtime in metadata/appdomain.c.
56 * Changes which are already detected at runtime, like the addition
57 * of icalls, do not require an increment.
59 #pragma warning disable 169
60 private const int mono_corlib_version
= 139;
61 #pragma warning restore 169
64 public enum SpecialFolder
77 DesktopDirectory
= 0x10,
79 ApplicationData
= 0x1a,
80 LocalApplicationData
= 0x1c,
84 CommonApplicationData
= 0x23,
88 CommonProgramFiles
= 0x2b,
90 NetworkShortcuts
= 0x13,
92 CommonStartMenu
= 0x16,
93 CommonPrograms
= 0x17,
95 CommonDesktopDirectory
= 0x19,
96 PrinterShortcuts
= 0x1b,
100 ProgramFilesX86
= 0x2a,
101 CommonProgramFilesX86
= 0x2c,
102 CommonTemplates
= 0x2d,
103 CommonDocuments
= 0x2e,
104 CommonAdminTools
= 0x2f,
107 CommonPictures
= 0x36,
110 LocalizedResources
= 0x39,
111 CommonOemLinks
= 0x3a,
116 enum SpecialFolderOption
{
118 DoNotVerify
= 0x4000,
123 /// Gets the command line for this process
125 public static string CommandLine
{
126 // note: security demand inherited from calling GetCommandLineArgs
128 StringBuilder sb
= new StringBuilder ();
129 foreach (string str
in GetCommandLineArgs ()) {
133 for (int i
= 0; i
< s
.Length
; i
++) {
134 if (quote
.Length
== 0 && Char
.IsWhiteSpace (s
[i
])) {
136 } else if (s
[i
] == '"') {
140 if (escape
&& quote
.Length
!= 0) {
141 s
= s
.Replace ("\"", "\\\"");
143 sb
.AppendFormat ("{0}{1}{0} ", quote
, s
);
147 return sb
.ToString ();
152 /// Gets or sets the current directory. Actually this is supposed to get
153 /// and/or set the process start directory acording to the documentation
154 /// but actually test revealed at beta2 it is just Getting/Setting the CurrentDirectory
156 public static string CurrentDirectory
159 return Directory
.GetCurrentDirectory ();
162 Directory
.SetCurrentDirectory (value);
166 public static int CurrentManagedThreadId
{
168 return Thread
.CurrentThread
.ManagedThreadId
;
173 /// Gets or sets the exit code of this process
175 public extern static int ExitCode
177 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
179 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
183 static public extern bool HasShutdownStarted
185 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
191 /// Gets the name of the local computer
193 public extern static string MachineName
{
194 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
195 [EnvironmentPermission (SecurityAction
.Demand
, Read
="COMPUTERNAME")]
196 [SecurityPermission (SecurityAction
.Demand
, UnmanagedCode
=true)]
200 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
201 extern static string GetNewLine ();
205 /// Gets the standard new line value
207 public static string NewLine
{
218 // Support methods and fields for OSVersion property
220 static OperatingSystem os
;
222 static extern PlatformID Platform
{
223 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
227 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
228 internal static extern string GetOSVersionString ();
231 /// Gets the current OS version information
233 public static OperatingSystem OSVersion
{
236 Version v
= CreateVersionFromString (GetOSVersionString ());
237 PlatformID p
= Platform
;
238 if (p
== PlatformID
.MacOSX
)
240 os
= new OperatingSystem (p
, v
);
247 // a very gentle way to construct a Version object which takes
248 // the first four numbers in a string as the version
249 internal static Version
CreateVersionFromString (string info
)
256 int number
= -1; // string may not begin with a digit
259 return new Version (0, 0, 0, 0);
261 for (int i
=0; i
< info
.Length
; i
++) {
263 if (Char
.IsDigit (c
)) {
268 number
= (number
* 10) + (c
- '0');
271 else if (number
>= 0) {
290 // ignore end of string
312 return new Version (major
, minor
, build
, revision
);
318 public static string StackTrace
{
319 [EnvironmentPermission (SecurityAction
.Demand
, Unrestricted
=true)]
321 System
.Diagnostics
.StackTrace trace
= new System
.Diagnostics
.StackTrace (0, true);
322 return trace
.ToString ();
327 /// Get a fully qualified path to the system directory
329 public static string SystemDirectory
{
331 return GetFolderPath (SpecialFolder
.System
);
336 /// Get the number of milliseconds that have elapsed since the system was booted
338 public extern static int TickCount
{
339 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
344 /// Get UserDomainName
346 public static string UserDomainName
{
347 // FIXME: this variable doesn't exist (at least not on WinXP) - reported to MS as FDBK20562
348 [EnvironmentPermission (SecurityAction
.Demand
, Read
="USERDOMAINNAME")]
355 /// Gets a flag indicating whether the process is in interactive mode
357 [MonoTODO ("Currently always returns false, regardless of interactive state")]
358 public static bool UserInteractive
{
365 /// Get the user name of current process is running under
367 public extern static string UserName
{
368 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
369 [EnvironmentPermission (SecurityAction
.Demand
, Read
="USERNAME;USER")]
374 /// Get the version of the common language runtime
376 public static Version Version
{
378 return new Version (Consts
.FxFileVersion
);
383 /// Get the amount of physical memory mapped to process
385 [MonoTODO ("Currently always returns zero")]
386 public static long WorkingSet
{
387 [EnvironmentPermission (SecurityAction
.Demand
, Unrestricted
=true)]
391 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
392 [SecurityPermission (SecurityAction
.Demand
, UnmanagedCode
=true)]
393 public extern static void Exit (int exitCode
);
395 internal static void _Exit (int exitCode
)
401 /// Substitute environment variables in the argument "name"
403 public static string ExpandEnvironmentVariables (string name
)
406 throw new ArgumentNullException ("name");
408 int off1
= name
.IndexOf ('%');
412 int len
= name
.Length
;
414 if (off1
== len
- 1 || (off2
= name
.IndexOf ('%', off1
+ 1)) == -1)
417 StringBuilder result
= new StringBuilder ();
418 result
.Append (name
, 0, off1
);
419 Hashtable tbl
= null;
421 string var = name
.Substring (off1
+ 1, off2
- off1
- 1);
422 string value = GetEnvironmentVariable (var);
423 if (value == null && Environment
.IsRunningOnWindows
) {
424 // On windows, env. vars. are case insensitive
426 tbl
= GetEnvironmentVariablesNoCase ();
428 value = tbl
[var] as string;
431 // If value not found, add %FOO to stream,
432 // and use the closing % for the next iteration.
433 // If value found, expand it in place of %FOO%
434 int realOldOff2
= off2
;
440 result
.Append (value);
443 off1
= name
.IndexOf ('%', off2
+ 1);
444 // If no % found for off1, don't look for one for off2
445 off2
= (off1
== -1 || off2
> len
-1)? -1 :name
.IndexOf ('%', off1
+ 1);
446 // textLen is the length of text between the closing % of current iteration
447 // and the starting % of the next iteration if any. This text is added to output
449 // If no new % found, use all the remaining text
450 if (off1
== -1 || off2
== -1)
451 textLen
= len
- oldOff2
- 1;
452 // If value found in current iteration, use text after current closing % and next %
453 else if(value != null)
454 textLen
= off1
- oldOff2
- 1;
455 // If value not found in current iteration, but a % was found for next iteration,
456 // use text from current closing % to the next %.
458 textLen
= off1
- realOldOff2
;
459 if(off1
>= oldOff2
|| off1
== -1)
460 result
.Append (name
, oldOff2
+1, textLen
);
461 } while (off2
> -1 && off2
< len
);
463 return result
.ToString ();
468 /// Return an array of the command line arguments of the current process
470 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
471 [EnvironmentPermissionAttribute (SecurityAction
.Demand
, Read
= "PATH")]
472 public extern static string[] GetCommandLineArgs ();
474 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
475 internal extern static string internalGetEnvironmentVariable (string variable
);
478 /// Return a string containing the value of the environment
479 /// variable identifed by parameter "variable"
481 public static string GetEnvironmentVariable (string variable
)
484 if (SecurityManager
.SecurityEnabled
) {
485 new EnvironmentPermission (EnvironmentPermissionAccess
.Read
, variable
).Demand ();
488 return internalGetEnvironmentVariable (variable
);
491 static Hashtable
GetEnvironmentVariablesNoCase ()
493 Hashtable vars
= new Hashtable (CaseInsensitiveHashCodeProvider
.Default
,
494 CaseInsensitiveComparer
.Default
);
496 foreach (string name
in GetEnvironmentVariableNames ()) {
497 vars
[name
] = internalGetEnvironmentVariable (name
);
504 /// Return a set of all environment variables and their values
507 public static IDictionary
GetEnvironmentVariables ()
509 StringBuilder sb
= null;
510 if (SecurityManager
.SecurityEnabled
) {
511 // we must have access to each variable to get the lot
512 sb
= new StringBuilder ();
513 // but (performance-wise) we do not want a stack-walk
514 // for each of them so we concatenate them
517 Hashtable vars
= new Hashtable ();
518 foreach (string name
in GetEnvironmentVariableNames ()) {
519 vars
[name
] = internalGetEnvironmentVariable (name
);
527 new EnvironmentPermission (EnvironmentPermissionAccess
.Read
, sb
.ToString ()).Demand ();
532 [EnvironmentPermission (SecurityAction
.Demand
, Unrestricted
=true)]
533 public static IDictionary
GetEnvironmentVariables ()
535 Hashtable vars
= new Hashtable ();
536 foreach (string name
in GetEnvironmentVariableNames ()) {
537 vars
[name
] = internalGetEnvironmentVariable (name
);
544 /// Returns the fully qualified path of the
545 /// folder specified by the "folder" parameter
547 public static string GetFolderPath (SpecialFolder folder
)
549 return GetFolderPath (folder
, SpecialFolderOption
.None
);
553 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
554 private extern static string GetWindowsFolderPath (int folder
);
557 static string GetFolderPath(SpecialFolder folder
, SpecialFolderOption option
)
559 SecurityManager
.EnsureElevatedPermissions (); // this is a no-op outside moonlight
563 if (Environment
.IsRunningOnWindows
)
564 dir
= GetWindowsFolderPath ((int) folder
);
566 dir
= UnixGetFolderPath (folder
, option
);
569 if ((dir
!= null) && (dir
.Length
> 0) && SecurityManager
.SecurityEnabled
) {
570 new FileIOPermission (FileIOPermissionAccess
.PathDiscovery
, dir
).Demand ();
576 private static string ReadXdgUserDir (string config_dir
, string home_dir
, string key
, string fallback
)
578 string env_path
= internalGetEnvironmentVariable (key
);
579 if (env_path
!= null && env_path
!= String
.Empty
) {
583 string user_dirs_path
= Path
.Combine (config_dir
, "user-dirs.dirs");
585 if (!File
.Exists (user_dirs_path
)) {
586 return Path
.Combine (home_dir
, fallback
);
590 using(StreamReader reader
= new StreamReader (user_dirs_path
)) {
592 while ((line
= reader
.ReadLine ()) != null) {
594 int delim_index
= line
.IndexOf ('=');
595 if(delim_index
> 8 && line
.Substring (0, delim_index
) == key
) {
596 string path
= line
.Substring (delim_index
+ 1).Trim ('"');
597 bool relative
= false;
599 if (path
.StartsWithOrdinalUnchecked ("$HOME/")) {
601 path
= path
.Substring (6);
602 } else if (!path
.StartsWithOrdinalUnchecked ("/")) {
606 return relative
? Path
.Combine (home_dir
, path
) : path
;
610 } catch (FileNotFoundException
) {
613 return Path
.Combine (home_dir
, fallback
);
617 // the security runtime (and maybe other parts of corlib) needs the
618 // information to initialize themselves before permissions can be checked
619 internal static string UnixGetFolderPath (SpecialFolder folder
, SpecialFolderOption option
)
621 string home
= internalGetHome ();
623 // http://freedesktop.org/Standards/basedir-spec/basedir-spec-0.6.html
625 // note: skip security check for environment variables
626 string data
= internalGetEnvironmentVariable ("XDG_DATA_HOME");
627 if ((data
== null) || (data
== String
.Empty
)) {
628 data
= Path
.Combine (home
, ".local");
629 data
= Path
.Combine (data
, "share");
632 // note: skip security check for environment variables
633 string config
= internalGetEnvironmentVariable ("XDG_CONFIG_HOME");
634 if ((config
== null) || (config
== String
.Empty
)) {
635 config
= Path
.Combine (home
, ".config");
639 // MyComputer is a virtual directory
640 case SpecialFolder
.MyComputer
:
644 case SpecialFolder
.Personal
:
647 // use FDO's CONFIG_HOME. This data will be synced across a network like the windows counterpart.
648 case SpecialFolder
.ApplicationData
:
651 //use FDO's DATA_HOME. This is *NOT* synced
652 case SpecialFolder
.LocalApplicationData
:
655 case SpecialFolder
.Desktop
:
656 case SpecialFolder
.DesktopDirectory
:
657 return ReadXdgUserDir (config
, home
, "XDG_DESKTOP_DIR", "Desktop");
659 case SpecialFolder
.MyMusic
:
660 if (Platform
== PlatformID
.MacOSX
)
661 return Path
.Combine (home
, "Music");
663 return ReadXdgUserDir (config
, home
, "XDG_MUSIC_DIR", "Music");
665 case SpecialFolder
.MyPictures
:
666 if (Platform
== PlatformID
.MacOSX
)
667 return Path
.Combine (home
, "Pictures");
669 return ReadXdgUserDir (config
, home
, "XDG_PICTURES_DIR", "Pictures");
671 case SpecialFolder
.Templates
:
672 return ReadXdgUserDir (config
, home
, "XDG_TEMPLATES_DIR", "Templates");
673 case SpecialFolder
.MyVideos
:
674 return ReadXdgUserDir (config
, home
, "XDG_VIDEOS_DIR", "Videos");
675 case SpecialFolder
.CommonTemplates
:
676 return "/usr/share/templates";
677 case SpecialFolder
.Fonts
:
678 if (Platform
== PlatformID
.MacOSX
)
679 return Path
.Combine (home
, "Library", "Fonts");
681 return Path
.Combine (home
, ".fonts");
682 // these simply dont exist on Linux
683 // The spec says if a folder doesnt exist, we
685 case SpecialFolder
.Favorites
:
686 if (Platform
== PlatformID
.MacOSX
)
687 return Path
.Combine (home
, "Library", "Favorites");
691 case SpecialFolder
.ProgramFiles
:
692 if (Platform
== PlatformID
.MacOSX
)
693 return "/Applications";
697 case SpecialFolder
.InternetCache
:
698 if (Platform
== PlatformID
.MacOSX
)
699 return Path
.Combine (home
, "Library", "Caches");
704 case SpecialFolder
.UserProfile
:
707 case SpecialFolder
.Programs
:
708 case SpecialFolder
.SendTo
:
709 case SpecialFolder
.StartMenu
:
710 case SpecialFolder
.Startup
:
711 case SpecialFolder
.Cookies
:
712 case SpecialFolder
.History
:
713 case SpecialFolder
.Recent
:
714 case SpecialFolder
.CommonProgramFiles
:
715 case SpecialFolder
.System
:
716 case SpecialFolder
.NetworkShortcuts
:
717 case SpecialFolder
.CommonStartMenu
:
718 case SpecialFolder
.CommonPrograms
:
719 case SpecialFolder
.CommonStartup
:
720 case SpecialFolder
.CommonDesktopDirectory
:
721 case SpecialFolder
.PrinterShortcuts
:
722 case SpecialFolder
.Windows
:
723 case SpecialFolder
.SystemX86
:
724 case SpecialFolder
.ProgramFilesX86
:
725 case SpecialFolder
.CommonProgramFilesX86
:
726 case SpecialFolder
.CommonDocuments
:
727 case SpecialFolder
.CommonAdminTools
:
728 case SpecialFolder
.AdminTools
:
729 case SpecialFolder
.CommonMusic
:
730 case SpecialFolder
.CommonPictures
:
731 case SpecialFolder
.CommonVideos
:
732 case SpecialFolder
.Resources
:
733 case SpecialFolder
.LocalizedResources
:
734 case SpecialFolder
.CommonOemLinks
:
735 case SpecialFolder
.CDBurning
:
737 // This is where data common to all users goes
738 case SpecialFolder
.CommonApplicationData
:
741 throw new ArgumentException ("Invalid SpecialFolder");
747 [EnvironmentPermission (SecurityAction
.Demand
, Unrestricted
=true)]
748 public static string[] GetLogicalDrives ()
750 return GetLogicalDrivesInternal ();
754 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
755 private static extern void internalBroadcastSettingChange ();
757 public static string GetEnvironmentVariable (string variable
, EnvironmentVariableTarget target
)
760 case EnvironmentVariableTarget
.Process
:
761 return GetEnvironmentVariable (variable
);
762 case EnvironmentVariableTarget
.Machine
:
763 new EnvironmentPermission (PermissionState
.Unrestricted
).Demand ();
764 if (!IsRunningOnWindows
)
766 using (Microsoft
.Win32
.RegistryKey env
= Microsoft
.Win32
.Registry
.LocalMachine
.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
767 object regvalue
= env
.GetValue (variable
);
768 return (regvalue
== null) ? null : regvalue
.ToString ();
770 case EnvironmentVariableTarget
.User
:
771 new EnvironmentPermission (PermissionState
.Unrestricted
).Demand ();
772 if (!IsRunningOnWindows
)
774 using (Microsoft
.Win32
.RegistryKey env
= Microsoft
.Win32
.Registry
.CurrentUser
.OpenSubKey ("Environment", false)) {
775 object regvalue
= env
.GetValue (variable
);
776 return (regvalue
== null) ? null : regvalue
.ToString ();
779 throw new ArgumentException ("target");
783 public static IDictionary
GetEnvironmentVariables (EnvironmentVariableTarget target
)
785 IDictionary variables
= (IDictionary
)new Hashtable ();
787 case EnvironmentVariableTarget
.Process
:
788 variables
= GetEnvironmentVariables ();
790 case EnvironmentVariableTarget
.Machine
:
791 new EnvironmentPermission (PermissionState
.Unrestricted
).Demand ();
792 if (IsRunningOnWindows
) {
793 using (Microsoft
.Win32
.RegistryKey env
= Microsoft
.Win32
.Registry
.LocalMachine
.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
794 string[] value_names
= env
.GetValueNames ();
795 foreach (string value_name
in value_names
)
796 variables
.Add (value_name
, env
.GetValue (value_name
));
800 case EnvironmentVariableTarget
.User
:
801 new EnvironmentPermission (PermissionState
.Unrestricted
).Demand ();
802 if (IsRunningOnWindows
) {
803 using (Microsoft
.Win32
.RegistryKey env
= Microsoft
.Win32
.Registry
.CurrentUser
.OpenSubKey ("Environment")) {
804 string[] value_names
= env
.GetValueNames ();
805 foreach (string value_name
in value_names
)
806 variables
.Add (value_name
, env
.GetValue (value_name
));
811 throw new ArgumentException ("target");
816 [EnvironmentPermission (SecurityAction
.Demand
, Unrestricted
=true)]
817 public static void SetEnvironmentVariable (string variable
, string value)
819 SetEnvironmentVariable (variable
, value, EnvironmentVariableTarget
.Process
);
822 [EnvironmentPermission (SecurityAction
.Demand
, Unrestricted
= true)]
823 public static void SetEnvironmentVariable (string variable
, string value, EnvironmentVariableTarget target
)
825 if (variable
== null)
826 throw new ArgumentNullException ("variable");
827 if (variable
== String
.Empty
)
828 throw new ArgumentException ("String cannot be of zero length.", "variable");
829 if (variable
.IndexOf ('=') != -1)
830 throw new ArgumentException ("Environment variable name cannot contain an equal character.", "variable");
831 if (variable
[0] == '\0')
832 throw new ArgumentException ("The first char in the string is the null character.", "variable");
835 case EnvironmentVariableTarget
.Process
:
836 InternalSetEnvironmentVariable (variable
, value);
838 case EnvironmentVariableTarget
.Machine
:
839 if (!IsRunningOnWindows
)
841 using (Microsoft
.Win32
.RegistryKey env
= Microsoft
.Win32
.Registry
.LocalMachine
.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true)) {
842 if (String
.IsNullOrEmpty (value))
843 env
.DeleteValue (variable
, false);
845 env
.SetValue (variable
, value);
846 internalBroadcastSettingChange ();
849 case EnvironmentVariableTarget
.User
:
850 if (!IsRunningOnWindows
)
852 using (Microsoft
.Win32
.RegistryKey env
= Microsoft
.Win32
.Registry
.CurrentUser
.OpenSubKey ("Environment", true)) {
853 if (String
.IsNullOrEmpty (value))
854 env
.DeleteValue (variable
, false);
856 env
.SetValue (variable
, value);
857 internalBroadcastSettingChange ();
861 throw new ArgumentException ("target");
865 public static void SetEnvironmentVariable (string variable
, string value)
867 if (variable
== null)
868 throw new ArgumentNullException ("variable");
869 if (variable
== String
.Empty
)
870 throw new ArgumentException ("String cannot be of zero length.", "variable");
871 if (variable
.IndexOf ('=') != -1)
872 throw new ArgumentException ("Environment variable name cannot contain an equal character.", "variable");
873 if (variable
[0] == '\0')
874 throw new ArgumentException ("The first char in the string is the null character.", "variable");
876 InternalSetEnvironmentVariable (variable
, value);
879 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
880 internal static extern void InternalSetEnvironmentVariable (string variable
, string value);
882 [SecurityPermission (SecurityAction
.LinkDemand
, UnmanagedCode
=true)]
883 public static void FailFast (string message
)
885 throw new NotImplementedException ();
888 internal static void FailFast (String message
, uint exitCode
)
890 throw new NotImplementedException ();
894 public static void FailFast (string message
, Exception exception
)
896 throw new NotImplementedException ();
899 public static bool Is64BitOperatingSystem
{
900 get { return IntPtr.Size == 8; }
// FIXME: is this good enough?
903 public static int SystemPageSize
{
904 get { return GetPageSize (); }
908 static bool Is64BitProcess
{
909 get { return IntPtr.Size == 8; }
912 public static extern int ProcessorCount
{
913 [EnvironmentPermission (SecurityAction
.Demand
, Read
="NUMBER_OF_PROCESSORS")]
914 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
919 #if (MONOTOUCH || MONODROID || XAMMAC)
920 internal const bool IsRunningOnWindows
= false;
922 internal static bool IsRunningOnWindows
{
923 get { return ((int) Platform < 4); }
929 // Used by gacutil.exe
931 #pragma warning disable 169
932 private static string GacPath
{
934 if (Environment
.IsRunningOnWindows
) {
935 /* On windows, we don't know the path where mscorlib.dll will be installed */
936 string corlibDir
= new DirectoryInfo (Path
.GetDirectoryName (typeof (int).Assembly
.Location
)).Parent
.Parent
.FullName
;
937 return Path
.Combine (Path
.Combine (corlibDir
, "mono"), "gac");
940 return Path
.Combine (Path
.Combine (internalGetGacPath (), "mono"), "gac");
943 #pragma warning restore 169
944 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
945 internal extern static string internalGetGacPath ();
947 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
948 private extern static string [] GetLogicalDrivesInternal ();
950 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
951 private extern static string [] GetEnvironmentVariableNames ();
953 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
954 internal extern static string GetMachineConfigPath ();
956 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
957 internal extern static string internalGetHome ();
959 [MethodImplAttribute (MethodImplOptions
.InternalCall
)]
960 internal extern static int GetPageSize ();
962 static internal bool IsUnix
{
964 int platform
= (int) Environment
.Platform
;
966 return (platform
== 4 || platform
== 128 || platform
== 6);
969 static internal bool IsMacOS
{
971 return Environment
.Platform
== PlatformID
.MacOSX
;
975 internal static bool IsCLRHosted
{
981 internal static void TriggerCodeContractFailure(ContractFailureKind failureKind
, String message
, String condition
, String exceptionAsString
)