(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / corlib / System / Environment.cs
blob9515c2f3af8fcdee4910747aca9622bf4b2d5eb3
1 //------------------------------------------------------------------------------
2 //
3 // System.Environment.cs
4 //
5 // Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
6 //
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:
22 //
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 //
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.
35 using System;
36 using System.IO;
37 //using System.Diagnostics;
38 using System.Collections;
39 using System.Security;
40 using System.Security.Permissions;
41 using System.Runtime.CompilerServices;
42 using System.Text;
44 namespace System
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 = 28;
59 private Environment ()
63 [MonoTODO]
64 public enum SpecialFolder
65 { // TODO: Determine if these windoze style folder identifiers
66 // have unix/linux counterparts
68 #if NET_1_1
69 Desktop = 0x00,
70 MyComputer = 0x11,
71 #endif
72 Programs = 0x02,
73 Personal = 0x05,
74 Favorites = 0x06,
75 Startup = 0x07,
76 Recent = 0x08,
77 SendTo = 0x09,
78 StartMenu = 0x0b,
79 MyMusic = 0x0d,
80 DesktopDirectory = 0x10,
81 Templates = 0x15,
82 ApplicationData = 0x1a,
83 LocalApplicationData = 0x1c,
84 InternetCache = 0x20,
85 Cookies = 0x21,
86 History = 0x22,
87 CommonApplicationData = 0x23,
88 System = 0x25,
89 ProgramFiles = 0x26,
90 MyPictures = 0x27,
91 CommonProgramFiles = 0x2b,
94 // TODO: Make sure the security attributes do what I expect
96 /// <summary>
97 /// Gets the command line for this process
98 /// </summary>
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 ());
110 /// <summary>
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
114 /// </summary>
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
120 get {
121 return Directory.GetCurrentDirectory ();
123 set {
124 Directory.SetCurrentDirectory (value);
128 /// <summary>
129 /// Gets or sets the exit code of this process
130 /// </summary>
131 public extern static int ExitCode
133 [MethodImplAttribute (MethodImplOptions.InternalCall)]
134 get;
135 [MethodImplAttribute (MethodImplOptions.InternalCall)]
136 set;
139 #if NET_1_1
140 static
141 #endif
142 public extern bool HasShutdownStarted
144 [MethodImplAttribute (MethodImplOptions.InternalCall)]
145 get;
149 /// <summary>
150 /// Gets the name of the local computer
151 /// </summary>
152 public extern static string MachineName {
153 [MethodImplAttribute (MethodImplOptions.InternalCall)]
154 get;
157 /// <summary>
158 /// Gets the standard new line value
159 /// </summary>
160 public extern static string NewLine {
161 [MethodImplAttribute (MethodImplOptions.InternalCall)]
162 get;
166 // Support methods and fields for OSVersion property
168 static OperatingSystem os;
170 internal static extern PlatformID Platform {
171 [MethodImplAttribute (MethodImplOptions.InternalCall)]
172 get;
175 [MethodImplAttribute (MethodImplOptions.InternalCall)]
176 internal static extern string GetOSVersionString ();
178 /// <summary>
179 /// Gets the current OS version information
180 /// </summary>
181 public static OperatingSystem OSVersion {
182 get {
183 if (os == null) {
184 Version v = Version.CreateFromString (GetOSVersionString ());
185 os = new OperatingSystem (Platform, v);
187 return os;
191 /// <summary>
192 /// Get StackTrace
193 /// </summary>
194 public static string StackTrace {
195 get {
196 System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace (1);
197 return trace.ToString ();
201 /// <summary>
202 /// Get a fully qualified path to the system directory
203 /// </summary>
204 public static string SystemDirectory {
205 get {
206 return GetFolderPath (SpecialFolder.System);
210 /// <summary>
211 /// Get the number of milliseconds that have elapsed since the system was booted
212 /// </summary>
213 public extern static int TickCount {
214 [MethodImplAttribute (MethodImplOptions.InternalCall)]
215 get;
218 /// <summary>
219 /// Get UserDomainName
220 /// </summary>
221 public static string UserDomainName {
222 get {
223 return MachineName;
227 /// <summary>
228 /// Gets a flag indicating whether the process is in interactive mode
229 /// </summary>
230 [MonoTODO]
231 public static bool UserInteractive {
232 get {
233 return false;
237 /// <summary>
238 /// Get the user name of current process is running under
239 /// </summary>
240 public extern static string UserName
242 [MethodImplAttribute (MethodImplOptions.InternalCall)]
243 get;
246 /// <summary>
247 /// Get the version of the common language runtime
248 /// </summary>
249 public static Version Version {
250 get {
251 #if NET_2_0
252 // FIXME: this is the version number for MS.NET 2.0 beta1.
253 // It must be changed when the final version is released.
254 return new Version (2, 0, 40607, 16);
255 #elif NET_1_1
256 return new Version (1, 1, 4322, 573);
257 #else
258 return new Version (1, 0, 3705, 288);
259 #endif
263 /// <summary>
264 /// Get the amount of physical memory mapped to process
265 /// </summary>
266 [MonoTODO]
267 public static long WorkingSet
269 get {
270 return 0;
274 [MethodImplAttribute (MethodImplOptions.InternalCall)]
275 public extern static void Exit (int exitCode);
277 /// <summary>
278 /// Substitute environment variables in the argument "name"
279 /// </summary>
280 public static string ExpandEnvironmentVariables (string name)
282 if (name == null)
283 throw new ArgumentNullException ("name");
285 int off1 = name.IndexOf ('%');
286 if (off1 == -1)
287 return name;
289 int len = name.Length;
290 int off2 = 0;
291 if (off1 == len - 1 || (off2 = name.IndexOf ('%', off1 + 1)) == -1)
292 return name;
294 PlatformID platform = Platform;
295 StringBuilder result = new StringBuilder ();
296 result.Append (name, 0, off1);
297 Hashtable tbl = null;
298 do {
299 string var = name.Substring (off1 + 1, off2 - off1 - 1);
300 string value = GetEnvironmentVariable (var);
301 if (value == null && (int) platform != 128) {
302 // On windows, env. vars. are case insensitive
303 if (tbl == null)
304 tbl = GetEnvironmentVariablesNoCase ();
306 value = tbl [var] as string;
309 // If value not found, add %FOO to stream,
310 // and use the closing % for the next iteration.
311 // If value found, expand it in place of %FOO%
312 if (value == null) {
313 result.Append ('%');
314 result.Append (var);
315 off2--;
316 } else {
317 result.Append (value);
319 int oldOff2 = off2;
320 off1 = name.IndexOf ('%', off2 + 1);
321 // If no % found for off1, don't look for one for off2
322 off2 = (off1 == -1 || off2 > len-1)? -1 :name.IndexOf ('%', off1 + 1);
323 // textLen is the length of text between the closing % of current iteration
324 // and the starting % of the next iteration if any. This text is added to output
325 int textLen;
326 // If no new % found, use all the remaining text
327 if (off1 == -1 || off2 == -1)
328 textLen = len - oldOff2 - 1;
329 // If value found in current iteration, use text after current closing % and next %
330 else if(value != null)
331 textLen = off1 - oldOff2 - 1;
332 // If value not found in current iteration, but a % was found for next iteration,
333 // use text from current closing % to the next %.
334 else
335 textLen = off1 - oldOff2;
336 if(off1 >= oldOff2 || off1 == -1)
337 result.Append (name.Substring (oldOff2+1, textLen));
338 } while (off2 > -1 && off2 < len);
340 return result.ToString ();
344 /// <summary>
345 /// Return an array of the command line arguments of the current process
346 /// </summary>
347 [MethodImplAttribute (MethodImplOptions.InternalCall)]
348 public extern static string[] GetCommandLineArgs();
350 /// <summary>
351 /// Return a string containing the value of the environment
352 /// variable identifed by parameter "variable"
353 /// </summary>
354 [MethodImplAttribute (MethodImplOptions.InternalCall)]
355 public extern static string GetEnvironmentVariable (string name);
357 static Hashtable GetEnvironmentVariablesNoCase ()
359 Hashtable vars = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
360 CaseInsensitiveComparer.Default);
362 foreach (string name in GetEnvironmentVariableNames ()) {
363 vars [name] = GetEnvironmentVariable (name);
366 return vars;
369 /// <summary>
370 /// Return a set of all environment variables and their values
371 /// </summary>
373 public static IDictionary GetEnvironmentVariables()
375 Hashtable vars = new Hashtable ();
376 foreach (string name in GetEnvironmentVariableNames ()) {
377 vars [name] = GetEnvironmentVariable (name);
380 return vars;
384 [MethodImplAttribute (MethodImplOptions.InternalCall)]
385 private extern static string GetWindowsFolderPath (int folder);
387 /// <summary>
388 /// Returns the fully qualified path of the
389 /// folder specified by the "folder" parameter
390 /// </summary>
391 public static string GetFolderPath (SpecialFolder folder)
393 if ((int) Platform != 128)
394 return GetWindowsFolderPath ((int) folder);
396 string home = internalGetHome ();
398 // http://freedesktop.org/Standards/basedir-spec/basedir-spec-0.6.html
399 string data = GetEnvironmentVariable ("XDG_DATA_HOME");
400 if ((data == null) || (data == String.Empty)) {
401 data = Path.Combine (home, ".local");
402 data = Path.Combine (data, "share");
405 string config = GetEnvironmentVariable ("XDG_CONFIG_HOME");
406 if ((config == null) || (config == String.Empty)) {
407 config = Path.Combine (home, ".config");
410 switch (folder) {
411 #if NET_1_1
412 // MyComputer is a virtual directory
413 case SpecialFolder.MyComputer:
414 return "";
415 #endif
416 // personal == ~
417 case SpecialFolder.Personal:
418 return home;
419 // use FDO's CONFIG_HOME. This data will be synced across a network like the windows counterpart.
420 case SpecialFolder.ApplicationData:
421 return config;
422 //use FDO's DATA_HOME. This is *NOT* synced
423 case SpecialFolder.LocalApplicationData:
424 return data;
425 #if NET_1_1
426 case SpecialFolder.Desktop:
427 #endif
428 case SpecialFolder.DesktopDirectory:
429 return Path.Combine (home, "Desktop");
431 // these simply dont exist on Linux
432 // The spec says if a folder doesnt exist, we
433 // should return ""
434 case SpecialFolder.Favorites:
435 case SpecialFolder.Programs:
436 case SpecialFolder.SendTo:
437 case SpecialFolder.StartMenu:
438 case SpecialFolder.Startup:
439 case SpecialFolder.MyMusic:
440 case SpecialFolder.MyPictures:
441 case SpecialFolder.Templates:
442 case SpecialFolder.Cookies:
443 case SpecialFolder.History:
444 case SpecialFolder.InternetCache:
445 case SpecialFolder.Recent:
446 case SpecialFolder.CommonProgramFiles:
447 case SpecialFolder.ProgramFiles:
448 case SpecialFolder.System:
449 return "";
450 // This is where data common to all users goes
451 case SpecialFolder.CommonApplicationData:
452 return "/usr/share";
453 default:
454 throw new ArgumentException ("Invalid SpecialFolder");
458 public static string[] GetLogicalDrives ()
460 return GetLogicalDrivesInternal ();
463 static internal string GetResourceString (string s) { return ""; }
466 #if NET_2_0
467 public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
469 return (string)(GetEnvironmentVariables (target) [variable]);
472 [MonoTODO]
473 public static IDictionary GetEnvironmentVariables (EnvironmentVariableTarget target)
475 throw new NotImplementedException ();
478 public static void SetEnvironmentVariable (string variable, string value)
480 SetEnvironmentVariable (variable, value, EnvironmentVariableTarget.Process);
483 [MonoTODO]
484 public static void SetEnvironmentVariable (string variable, string value, EnvironmentVariableTarget target)
486 throw new NotImplementedException ();
489 [MonoTODO]
490 static bool IsServerGC {
491 get {
492 throw new NotImplementedException ();
496 [MonoTODO]
497 static int ProcessorCount {
498 get {
499 throw new NotImplementedException ();
502 #endif
504 // private methods
506 private static string GacPath {
507 get {
508 if ((int) Platform != 128) {
509 /* On windows, we don't know the path where mscorlib.dll will be installed */
510 string corlibDir = new DirectoryInfo (Path.GetDirectoryName (typeof (int).Assembly.Location)).Parent.Parent.FullName;
511 return Path.Combine (Path.Combine (corlibDir, "mono"), "gac");
514 return Path.Combine (Path.Combine (internalGetGacPath (), "mono"), "gac");
518 [MethodImplAttribute (MethodImplOptions.InternalCall)]
519 private extern static string [] GetLogicalDrivesInternal ();
521 [MethodImplAttribute (MethodImplOptions.InternalCall)]
522 private extern static string [] GetEnvironmentVariableNames ();
524 [MethodImplAttribute (MethodImplOptions.InternalCall)]
525 internal extern static string GetMachineConfigPath ();
527 [MethodImplAttribute (MethodImplOptions.InternalCall)]
528 internal extern static string internalGetGacPath ();
530 [MethodImplAttribute (MethodImplOptions.InternalCall)]
531 internal extern static string internalGetHome ();