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 //------------------------------------------------------------------------------
15 //using System.Diagnostics;
16 using System.Collections;
17 using System.Security;
18 using System.Security.Permissions;
19 using System.Runtime.CompilerServices;
24 public sealed class Environment
27 * This is the version number of the corlib-runtime interface. When
28 * making changes to this interface (by changing the layout
29 * of classes the runtime knows about, changing icall semantics etc),
30 * increment this variable. Also increment the
31 * pair of this variable in the runtime in metadata/appdomain.c.
33 private const int mono_corlib_version = 16;
35 private Environment ()
40 public enum SpecialFolder
41 { // TODO: Determine if these windoze style folder identifiers
42 // have unix/linux counterparts
56 DesktopDirectory = 0x10,
58 ApplicationData = 0x1a,
59 LocalApplicationData = 0x1c,
63 CommonApplicationData = 0x23,
67 CommonProgramFiles = 0x2b,
70 // TODO: Make sure the security attributes do what I expect
73 /// Gets the command line for this process
75 public static string CommandLine
76 { // TODO: Coordinate with implementor of EnvironmentPermissionAttribute
77 // [EnvironmentPermissionAttribute(SecurityAction.Demand, Read = "COMMANDLINE")]
80 // FIXME: we may need to quote, but any sane person
81 // should use GetCommandLineArgs () instead.
82 return String.Join (" ", GetCommandLineArgs ());
87 /// Gets or sets the current directory. Actually this is supposed to get
88 /// and/or set the process start directory acording to the documentation
89 /// but actually test revealed at beta2 it is just Getting/Setting the CurrentDirectory
91 public static string CurrentDirectory
93 // originally it was my thought that the external call would be made in
94 // the directory class however that class has additional security requirements
95 // so the Directory class will call this class for its get/set current directory
97 [EnvironmentPermissionAttribute(SecurityAction.Demand, Unrestricted = true)]
99 return Directory.GetCurrentDirectory ();
101 [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
103 Directory.SetCurrentDirectory (value);
108 /// Gets or sets the exit code of this process
110 public extern static int ExitCode
112 [MethodImplAttribute (MethodImplOptions.InternalCall)]
114 [MethodImplAttribute (MethodImplOptions.InternalCall)]
121 public extern bool HasShutdownStarted
123 [MethodImplAttribute (MethodImplOptions.InternalCall)]
129 /// Gets the name of the local computer
131 public extern static string MachineName {
132 [MethodImplAttribute (MethodImplOptions.InternalCall)]
137 /// Gets the standard new line value
139 public extern static string NewLine {
140 [MethodImplAttribute (MethodImplOptions.InternalCall)]
145 // Support methods and fields for OSVersion property
147 static OperatingSystem os;
149 internal static extern PlatformID Platform {
150 [MethodImplAttribute (MethodImplOptions.InternalCall)]
155 /// Gets the current OS version information
157 [MonoTODO("Correct version")]
158 public static OperatingSystem OSVersion {
161 os = new OperatingSystem (Platform, new Version (5,1,2600,0));
170 public static string StackTrace {
172 System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace (1);
173 return trace.ToString ();
178 /// Get a fully qualified path to the system directory
180 public static string SystemDirectory {
182 return GetFolderPath (SpecialFolder.System);
187 /// Get the number of milliseconds that have elapsed since the system was booted
189 public extern static int TickCount {
190 [MethodImplAttribute (MethodImplOptions.InternalCall)]
195 /// Get UserDomainName
197 public static string UserDomainName {
204 /// Gets a flag indicating whether the process is in interactive mode
207 public static bool UserInteractive {
214 /// Get the user name of current process is running under
216 public extern static string UserName
218 [MethodImplAttribute (MethodImplOptions.InternalCall)]
223 /// Get the version of the common language runtime
225 public static Version Version {
228 return new Version (1, 1, 4322, 573);
230 return new Version (1, 0, 3705, 288);
236 /// Get the amount of physical memory mapped to process
239 public static long WorkingSet
246 [MethodImplAttribute (MethodImplOptions.InternalCall)]
247 public extern static void Exit (int exitCode);
250 /// Substitute environment variables in the argument "name"
252 public static string ExpandEnvironmentVariables (string name)
255 throw new ArgumentNullException ("name");
257 int off1 = name.IndexOf ('%');
261 int len = name.Length;
263 if (off1 == len - 1 || (off2 = name.IndexOf ('%', off1 + 1)) == -1)
266 PlatformID platform = Platform;
267 StringBuilder result = new StringBuilder ();
268 result.Append (name, 0, off1);
270 Hashtable tbl = null;
271 string var = name.Substring (off1 + 1, off2 - off1 - 1);
272 string value = GetEnvironmentVariable (var);
273 if (value == null && (int) platform != 128) {
274 // On windows, env. vars. are case insensitive
276 tbl = GetEnvironmentVariablesNoCase ();
278 value = tbl [var] as string;
286 result.Append (value);
289 if (off2 + 1 == len) {
294 off2 = (off1 + 1 == len) ? -1 : name.IndexOf ('%', off1 + 1);
297 } while (off2 != -1);
300 result.Append (name.Substring (off1));
302 return result.ToString ();
306 /// Return an array of the command line arguments of the current process
308 [MethodImplAttribute (MethodImplOptions.InternalCall)]
309 public extern static string[] GetCommandLineArgs();
312 /// Return a string containing the value of the environment
313 /// variable identifed by parameter "variable"
315 [MethodImplAttribute (MethodImplOptions.InternalCall)]
316 public extern static string GetEnvironmentVariable (string name);
318 static Hashtable GetEnvironmentVariablesNoCase ()
320 Hashtable vars = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
321 CaseInsensitiveComparer.Default);
323 foreach (string name in GetEnvironmentVariableNames ()) {
324 vars [name] = GetEnvironmentVariable (name);
331 /// Return a set of all environment variables and their values
334 public static IDictionary GetEnvironmentVariables()
336 Hashtable vars = new Hashtable ();
337 foreach (string name in GetEnvironmentVariableNames ()) {
338 vars [name] = GetEnvironmentVariable (name);
345 [MethodImplAttribute (MethodImplOptions.InternalCall)]
346 private extern static string GetWindowsFolderPath (int folder);
349 /// Returns the fully qualified path of the
350 /// folder specified by the "folder" parameter
352 public static string GetFolderPath (SpecialFolder folder)
354 if ((int) Platform != 128)
355 return GetWindowsFolderPath ((int) folder);
357 // we can do this in managed code for non-Windows environments
358 string path = String.Empty;
360 // http://freedesktop.org/Standards/basedir-spec/basedir-spec-0.6.html
361 string data = GetEnvironmentVariable ("XDG_DATA_HOME");
362 if ((data == null) || (data == String.Empty)) {
363 data = Path.Combine (GetEnvironmentVariable ("HOME"), ".local");
364 data = Path.Combine (data, "share");
367 string config = GetEnvironmentVariable ("XDG_CONFIG_HOME");
368 if ((config == null) || (config == String.Empty)) {
369 config = Path.Combine (GetEnvironmentVariable ("HOME"), ".config");
372 string cache = GetEnvironmentVariable ("XDG_CACHE_HOME");
373 if ((cache == null) || (cache == String.Empty)) {
374 cache = Path.Combine (GetEnvironmentVariable ("HOME"), ".cache");
379 case SpecialFolder.MyComputer: // MyComputer is a virtual directory
385 case SpecialFolder.ApplicationData:
386 case SpecialFolder.LocalApplicationData:
387 case SpecialFolder.MyMusic:
388 case SpecialFolder.MyPictures:
389 case SpecialFolder.Personal:
390 case SpecialFolder.Templates:
394 // configuration related
396 case SpecialFolder.Desktop:
398 case SpecialFolder.DesktopDirectory:
399 case SpecialFolder.Favorites:
400 case SpecialFolder.Programs:
401 case SpecialFolder.SendTo:
402 case SpecialFolder.StartMenu:
403 case SpecialFolder.Startup:
407 // cache related (could disappear)
408 case SpecialFolder.Cookies:
409 case SpecialFolder.History:
410 case SpecialFolder.InternetCache:
411 case SpecialFolder.Recent:
416 case SpecialFolder.CommonProgramFiles:
417 case SpecialFolder.ProgramFiles:
418 case SpecialFolder.System:
421 // Directories shared by all users
422 case SpecialFolder.CommonApplicationData:
423 path = Path.GetDirectoryName (GetMachineConfigPath ());
427 throw new ArgumentException ("Invalid SpecialFolder");
434 /// Returns an array of the logical drives
437 public static string[] GetLogicalDrives ()
439 return(new string[] { "/" });
442 static internal string GetResourceString (string s) { return ""; }
446 private static string GacPath
448 get { return Path.Combine (Path.Combine (internalGetGacPath (), "mono"), "gac"); }
451 [MethodImplAttribute (MethodImplOptions.InternalCall)]
452 private extern static string [] GetEnvironmentVariableNames ();
454 [MethodImplAttribute (MethodImplOptions.InternalCall)]
455 internal extern static string GetMachineConfigPath ();
457 [MethodImplAttribute (MethodImplOptions.InternalCall)]
458 internal extern static string internalGetGacPath ();