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 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.
37 //using System.Diagnostics;
38 using System.Collections;
39 using System.Security;
40 using System.Security.Permissions;
41 using System.Runtime.CompilerServices;
46 public sealed class Environment
49 * This is the version number of the corlib-runtime interface. When
50 * making changes to this interface (by changing the layout
51 * of classes the runtime knows about, changing icall semantics etc),
52 * increment this variable. Also increment the
53 * pair of this variable in the runtime in metadata/appdomain.c.
54 * Changes which are already detected at runtime, like the addition
55 * of icalls, do not require an increment.
57 private const int mono_corlib_version = 22;
59 private Environment ()
64 public enum SpecialFolder
65 { // TODO: Determine if these windoze style folder identifiers
66 // have unix/linux counterparts
80 DesktopDirectory = 0x10,
82 ApplicationData = 0x1a,
83 LocalApplicationData = 0x1c,
87 CommonApplicationData = 0x23,
91 CommonProgramFiles = 0x2b,
94 // TODO: Make sure the security attributes do what I expect
97 /// Gets the command line for this process
99 public static string CommandLine
100 { // TODO: Coordinate with implementor of EnvironmentPermissionAttribute
101 // [EnvironmentPermissionAttribute(SecurityAction.Demand, Read = "COMMANDLINE")]
104 // FIXME: we may need to quote, but any sane person
105 // should use GetCommandLineArgs () instead.
106 return String.Join (" ", GetCommandLineArgs ());
111 /// Gets or sets the current directory. Actually this is supposed to get
112 /// and/or set the process start directory acording to the documentation
113 /// but actually test revealed at beta2 it is just Getting/Setting the CurrentDirectory
115 public static string CurrentDirectory
117 // originally it was my thought that the external call would be made in
118 // the directory class however that class has additional security requirements
119 // so the Directory class will call this class for its get/set current directory
121 return Directory.GetCurrentDirectory ();
124 Directory.SetCurrentDirectory (value);
129 /// Gets or sets the exit code of this process
131 public extern static int ExitCode
133 [MethodImplAttribute (MethodImplOptions.InternalCall)]
135 [MethodImplAttribute (MethodImplOptions.InternalCall)]
142 public extern bool HasShutdownStarted
144 [MethodImplAttribute (MethodImplOptions.InternalCall)]
150 /// Gets the name of the local computer
152 public extern static string MachineName {
153 [MethodImplAttribute (MethodImplOptions.InternalCall)]
158 /// Gets the standard new line value
160 public extern static string NewLine {
161 [MethodImplAttribute (MethodImplOptions.InternalCall)]
166 // Support methods and fields for OSVersion property
168 static OperatingSystem os;
170 internal static extern PlatformID Platform {
171 [MethodImplAttribute (MethodImplOptions.InternalCall)]
175 [MethodImplAttribute (MethodImplOptions.InternalCall)]
176 internal static extern string GetOSVersionString ();
179 /// Gets the current OS version information
181 public static OperatingSystem OSVersion {
184 Version v = Version.CreateFromString (GetOSVersionString ());
185 os = new OperatingSystem (Platform, v);
194 public static string StackTrace {
196 System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace (1);
197 return trace.ToString ();
202 /// Get a fully qualified path to the system directory
204 public static string SystemDirectory {
206 return GetFolderPath (SpecialFolder.System);
211 /// Get the number of milliseconds that have elapsed since the system was booted
213 public extern static int TickCount {
214 [MethodImplAttribute (MethodImplOptions.InternalCall)]
219 /// Get UserDomainName
221 public static string UserDomainName {
228 /// Gets a flag indicating whether the process is in interactive mode
231 public static bool UserInteractive {
238 /// Get the user name of current process is running under
240 public extern static string UserName
242 [MethodImplAttribute (MethodImplOptions.InternalCall)]
247 /// Get the version of the common language runtime
249 public static Version Version {
252 return new Version (1, 1, 4322, 573);
254 return new Version (1, 0, 3705, 288);
260 /// Get the amount of physical memory mapped to process
263 public static long WorkingSet
270 [MethodImplAttribute (MethodImplOptions.InternalCall)]
271 public extern static void Exit (int exitCode);
274 /// Substitute environment variables in the argument "name"
276 public static string ExpandEnvironmentVariables (string name)
279 throw new ArgumentNullException ("name");
281 int off1 = name.IndexOf ('%');
285 int len = name.Length;
287 if (off1 == len - 1 || (off2 = name.IndexOf ('%', off1 + 1)) == -1)
290 PlatformID platform = Platform;
291 StringBuilder result = new StringBuilder ();
292 result.Append (name, 0, off1);
293 Hashtable tbl = null;
295 string var = name.Substring (off1 + 1, off2 - off1 - 1);
296 string value = GetEnvironmentVariable (var);
297 if (value == null && (int) platform != 128) {
298 // On windows, env. vars. are case insensitive
300 tbl = GetEnvironmentVariablesNoCase ();
302 value = tbl [var] as string;
310 result.Append (value);
313 if (off2 + 1 == len) {
318 off2 = (off1 + 1 == len) ? -1 : name.IndexOf ('%', off1 + 1);
321 } while (off2 != -1);
324 result.Append (name.Substring (off1));
326 return result.ToString ();
330 /// Return an array of the command line arguments of the current process
332 [MethodImplAttribute (MethodImplOptions.InternalCall)]
333 public extern static string[] GetCommandLineArgs();
336 /// Return a string containing the value of the environment
337 /// variable identifed by parameter "variable"
339 [MethodImplAttribute (MethodImplOptions.InternalCall)]
340 public extern static string GetEnvironmentVariable (string name);
342 static Hashtable GetEnvironmentVariablesNoCase ()
344 Hashtable vars = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
345 CaseInsensitiveComparer.Default);
347 foreach (string name in GetEnvironmentVariableNames ()) {
348 vars [name] = GetEnvironmentVariable (name);
355 /// Return a set of all environment variables and their values
358 public static IDictionary GetEnvironmentVariables()
360 Hashtable vars = new Hashtable ();
361 foreach (string name in GetEnvironmentVariableNames ()) {
362 vars [name] = GetEnvironmentVariable (name);
369 [MethodImplAttribute (MethodImplOptions.InternalCall)]
370 private extern static string GetWindowsFolderPath (int folder);
373 /// Returns the fully qualified path of the
374 /// folder specified by the "folder" parameter
376 public static string GetFolderPath (SpecialFolder folder)
378 if ((int) Platform != 128)
379 return GetWindowsFolderPath ((int) folder);
381 string home = internalGetHome ();
383 // http://freedesktop.org/Standards/basedir-spec/basedir-spec-0.6.html
384 string data = GetEnvironmentVariable ("XDG_DATA_HOME");
385 if ((data == null) || (data == String.Empty)) {
386 data = Path.Combine (home, ".local");
387 data = Path.Combine (data, "share");
390 string config = GetEnvironmentVariable ("XDG_CONFIG_HOME");
391 if ((config == null) || (config == String.Empty)) {
392 config = Path.Combine (home, ".config");
397 // MyComputer is a virtual directory
398 case SpecialFolder.MyComputer:
402 case SpecialFolder.Personal:
404 // use FDO's CONFIG_HOME. This data will be synced across a network like the windows counterpart.
405 case SpecialFolder.ApplicationData:
407 //use FDO's DATA_HOME. This is *NOT* synced
408 case SpecialFolder.LocalApplicationData:
411 case SpecialFolder.Desktop:
413 case SpecialFolder.DesktopDirectory:
414 return Path.Combine (home, "Desktop");
416 // these simply dont exist on Linux
417 // The spec says if a folder doesnt exist, we
419 case SpecialFolder.Favorites:
420 case SpecialFolder.Programs:
421 case SpecialFolder.SendTo:
422 case SpecialFolder.StartMenu:
423 case SpecialFolder.Startup:
424 case SpecialFolder.MyMusic:
425 case SpecialFolder.MyPictures:
426 case SpecialFolder.Templates:
427 case SpecialFolder.Cookies:
428 case SpecialFolder.History:
429 case SpecialFolder.InternetCache:
430 case SpecialFolder.Recent:
431 case SpecialFolder.CommonProgramFiles:
432 case SpecialFolder.ProgramFiles:
433 case SpecialFolder.System:
435 // This is where data common to all users goes
436 case SpecialFolder.CommonApplicationData:
439 throw new ArgumentException ("Invalid SpecialFolder");
443 public static string[] GetLogicalDrives ()
445 return GetLogicalDrivesInternal ();
448 static internal string GetResourceString (string s) { return ""; }
452 private static string GacPath {
454 if ((int) Platform != 128) {
455 /* On windows, we don't know the path where mscorlib.dll will be installed */
456 string corlibDir = Path.GetDirectoryName (typeof (int).Assembly.Location);
457 return Path.Combine (Path.Combine (corlibDir, "mono"), "gac");
460 return Path.Combine (Path.Combine (internalGetGacPath (), "mono"), "gac");
464 [MethodImplAttribute (MethodImplOptions.InternalCall)]
465 private extern static string [] GetLogicalDrivesInternal ();
467 [MethodImplAttribute (MethodImplOptions.InternalCall)]
468 private extern static string [] GetEnvironmentVariableNames ();
470 [MethodImplAttribute (MethodImplOptions.InternalCall)]
471 internal extern static string GetMachineConfigPath ();
473 [MethodImplAttribute (MethodImplOptions.InternalCall)]
474 internal extern static string internalGetGacPath ();
476 [MethodImplAttribute (MethodImplOptions.InternalCall)]
477 internal extern static string internalGetHome ();