Xamarin Public Jenkins (auto-signing) 64ac736ec5 Imported Upstream version 6.0.0.172
Former-commit-id: f3cc9b82f3e5bd8f0fd3ebc098f789556b44e9cd
2019-04-12 14:10:50 +00:00

1059 lines
31 KiB
C#

//------------------------------------------------------------------------------
//
// System.Environment.cs
//
// Copyright (C) 2001 Moonlight Enterprises, All Rights Reserved
//
// Author: Jim Richardson, develop@wtfo-guru.com
// Dan Lewis (dihlewis@yahoo.co.uk)
// Created: Saturday, August 11, 2001
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.IO;
using System.Collections;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Diagnostics.Contracts;
namespace System {
[ComVisible (true)]
public static partial class Environment {
/*
* This is the version of the corlib-runtime interface.
* It is defined in configure.ac.
*/
#pragma warning disable 169
private const string mono_corlib_version = Consts.MonoCorlibVersion;
#pragma warning restore 169
[ComVisible (true)]
public enum SpecialFolder
{
MyDocuments = 0x05,
Desktop = 0x00,
MyComputer = 0x11,
Programs = 0x02,
Personal = 0x05,
Favorites = 0x06,
Startup = 0x07,
Recent = 0x08,
SendTo = 0x09,
StartMenu = 0x0b,
MyMusic = 0x0d,
DesktopDirectory = 0x10,
Templates = 0x15,
ApplicationData = 0x1a,
LocalApplicationData = 0x1c,
InternetCache = 0x20,
Cookies = 0x21,
History = 0x22,
CommonApplicationData = 0x23,
System = 0x25,
ProgramFiles = 0x26,
MyPictures = 0x27,
CommonProgramFiles = 0x2b,
MyVideos = 0x0e,
NetworkShortcuts = 0x13,
Fonts = 0x14,
CommonStartMenu = 0x16,
CommonPrograms = 0x17,
CommonStartup = 0x18,
CommonDesktopDirectory = 0x19,
PrinterShortcuts = 0x1b,
Windows = 0x24,
UserProfile = 0x28,
SystemX86 = 0x29,
ProgramFilesX86 = 0x2a,
CommonProgramFilesX86 = 0x2c,
CommonTemplates = 0x2d,
CommonDocuments = 0x2e,
CommonAdminTools = 0x2f,
AdminTools = 0x30,
CommonMusic = 0x35,
CommonPictures = 0x36,
CommonVideos = 0x37,
Resources = 0x38,
LocalizedResources = 0x39,
CommonOemLinks = 0x3a,
CDBurning = 0x3b,
}
public
enum SpecialFolderOption {
None = 0,
DoNotVerify = 0x4000,
Create = 0x8000
}
/// <summary>
/// Gets the command line for this process
/// </summary>
public static string CommandLine {
// note: security demand inherited from calling GetCommandLineArgs
get {
StringBuilder sb = new StringBuilder ();
foreach (string str in GetCommandLineArgs ()) {
bool escape = false;
string quote = "";
string s = str;
for (int i = 0; i < s.Length; i++) {
if (quote.Length == 0 && Char.IsWhiteSpace (s [i])) {
quote = "\"";
} else if (s [i] == '"') {
escape = true;
}
}
if (escape && quote.Length != 0) {
s = s.Replace ("\"", "\\\"");
}
sb.AppendFormat ("{0}{1}{0} ", quote, s);
}
if (sb.Length > 0)
sb.Length--;
return sb.ToString ();
}
}
/// <summary>
/// Gets or sets the current directory. Actually this is supposed to get
/// and/or set the process start directory acording to the documentation
/// but actually test revealed at beta2 it is just Getting/Setting the CurrentDirectory
/// </summary>
public static string CurrentDirectory
{
get {
return Directory.InsecureGetCurrentDirectory ();
}
set {
Directory.InsecureSetCurrentDirectory (value);
}
}
public static int CurrentManagedThreadId {
get {
return Thread.CurrentThread.ManagedThreadId;
}
}
/// <summary>
/// Gets or sets the exit code of this process
/// </summary>
public extern static int ExitCode
{
[MethodImplAttribute (MethodImplOptions.InternalCall)]
get;
[MethodImplAttribute (MethodImplOptions.InternalCall)]
set;
}
static public extern bool HasShutdownStarted
{
[MethodImplAttribute (MethodImplOptions.InternalCall)]
get;
}
/// <summary>
/// Gets the name of the local computer
/// </summary>
public extern static string MachineName {
[MethodImplAttribute (MethodImplOptions.InternalCall)]
[EnvironmentPermission (SecurityAction.Demand, Read="COMPUTERNAME")]
[SecurityPermission (SecurityAction.Demand, UnmanagedCode=true)]
get;
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
extern static string GetNewLine ();
static string nl;
/// <summary>
/// Gets the standard new line value
/// </summary>
public static string NewLine {
get {
if (nl != null)
return nl;
nl = GetNewLine ();
return nl;
}
}
//
// Support methods and fields for OSVersion property
//
static OperatingSystem os;
static internal PlatformID Platform {
[MethodImplAttribute (MethodImplOptions.InternalCall)]
get;
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal static extern string GetOSVersionString ();
/// <summary>
/// Gets the current OS version information
/// </summary>
public static OperatingSystem OSVersion {
get {
if (os == null) {
Version v = CreateVersionFromString (GetOSVersionString ());
PlatformID p = Platform;
if (p == PlatformID.MacOSX)
p = PlatformID.Unix;
os = new OperatingSystem (p, v);
}
return os;
}
}
// a very gentle way to construct a Version object which takes
// the first four numbers in a string as the version
internal static Version CreateVersionFromString (string info)
{
int major = 0;
int minor = 0;
int build = 0;
int revision = 0;
int state = 1;
int number = -1; // string may not begin with a digit
if (info == null)
return new Version (0, 0, 0, 0);
for (int i=0; i < info.Length; i++) {
char c = info [i];
if (Char.IsDigit (c)) {
if (number < 0) {
number = (c - '0');
}
else {
number = (number * 10) + (c - '0');
}
}
else if (number >= 0) {
// assign
switch (state) {
case 1:
major = number;
break;
case 2:
minor = number;
break;
case 3:
build = number;
break;
case 4:
revision = number;
break;
}
number = -1;
state ++;
}
// ignore end of string
if (state == 5)
break;
}
// Last number
if (number >= 0) {
switch (state) {
case 1:
major = number;
break;
case 2:
minor = number;
break;
case 3:
build = number;
break;
case 4:
revision = number;
break;
}
}
return new Version (major, minor, build, revision);
}
/// <summary>
/// Get StackTrace
/// </summary>
public static string StackTrace {
[EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
get {
System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace (0, true);
return trace.ToString ();
}
}
/// <summary>
/// Get a fully qualified path to the system directory
/// </summary>
public static string SystemDirectory {
get {
return GetFolderPath (SpecialFolder.System);
}
}
/// <summary>
/// Get the number of milliseconds that have elapsed since the system was booted
/// </summary>
public extern static int TickCount {
[MethodImplAttribute (MethodImplOptions.InternalCall)]
get;
}
/// <summary>
/// Get UserDomainName
/// </summary>
public static string UserDomainName {
// FIXME: this variable doesn't exist (at least not on WinXP) - reported to MS as FDBK20562
[EnvironmentPermission (SecurityAction.Demand, Read="USERDOMAINNAME")]
get {
return MachineName;
}
}
/// <summary>
/// Gets a flag indicating whether the process is in interactive mode
/// </summary>
[MonoTODO ("Currently always returns false, regardless of interactive state")]
public static bool UserInteractive {
get {
return false;
}
}
/// <summary>
/// Get the user name of current process is running under
/// </summary>
public extern static string UserName {
[MethodImplAttribute (MethodImplOptions.InternalCall)]
[EnvironmentPermission (SecurityAction.Demand, Read="USERNAME;USER")]
get;
}
/// <summary>
/// Get the version of the common language runtime
/// </summary>
public static Version Version {
get {
return new Version (Consts.EnvironmentVersion);
}
}
/// <summary>
/// Get the amount of physical memory mapped to process
/// </summary>
[MonoTODO ("Currently always returns zero")]
public static long WorkingSet {
[EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
get { return 0; }
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
[SecurityPermission (SecurityAction.Demand, UnmanagedCode=true)]
public extern static void Exit (int exitCode);
internal static void _Exit (int exitCode)
{
Exit (exitCode);
}
/// <summary>
/// Substitute environment variables in the argument "name"
/// </summary>
public static string ExpandEnvironmentVariables (string name)
{
if (name == null)
throw new ArgumentNullException ("name");
int off1 = name.IndexOf ('%');
if (off1 == -1)
return name;
int len = name.Length;
int off2 = 0;
if (off1 == len - 1 || (off2 = name.IndexOf ('%', off1 + 1)) == -1)
return name;
StringBuilder result = new StringBuilder ();
result.Append (name, 0, off1);
Hashtable tbl = null;
do {
string var = name.Substring (off1 + 1, off2 - off1 - 1);
string value = GetEnvironmentVariable (var);
if (value == null && Environment.IsRunningOnWindows) {
// On windows, env. vars. are case insensitive
if (tbl == null)
tbl = GetEnvironmentVariablesNoCase ();
value = tbl [var] as string;
}
// If value not found, add %FOO to stream,
// and use the closing % for the next iteration.
// If value found, expand it in place of %FOO%
int realOldOff2 = off2;
if (value == null) {
result.Append ('%');
result.Append (var);
off2--;
} else {
result.Append (value);
}
int oldOff2 = off2;
off1 = name.IndexOf ('%', off2 + 1);
// If no % found for off1, don't look for one for off2
off2 = (off1 == -1 || off2 > len-1)? -1 :name.IndexOf ('%', off1 + 1);
// textLen is the length of text between the closing % of current iteration
// and the starting % of the next iteration if any. This text is added to output
int textLen;
// If no new % found, use all the remaining text
if (off1 == -1 || off2 == -1)
textLen = len - oldOff2 - 1;
// If value found in current iteration, use text after current closing % and next %
else if(value != null)
textLen = off1 - oldOff2 - 1;
// If value not found in current iteration, but a % was found for next iteration,
// use text from current closing % to the next %.
else
textLen = off1 - realOldOff2;
if(off1 >= oldOff2 || off1 == -1)
result.Append (name, oldOff2+1, textLen);
} while (off2 > -1 && off2 < len);
return result.ToString ();
}
/// <summary>
/// Return an array of the command line arguments of the current process
/// </summary>
[MethodImplAttribute (MethodImplOptions.InternalCall)]
[EnvironmentPermissionAttribute (SecurityAction.Demand, Read = "PATH")]
public extern static string[] GetCommandLineArgs ();
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static string internalGetEnvironmentVariable_native (IntPtr variable);
internal static string internalGetEnvironmentVariable (string variable) {
if (variable == null)
return null;
using (var h = Mono.RuntimeMarshal.MarshalString (variable)) {
return internalGetEnvironmentVariable_native (h.Value);
}
}
/// <summary>
/// Return a string containing the value of the environment
/// variable identifed by parameter "variable"
/// </summary>
public static string GetEnvironmentVariable (string variable)
{
#if MONO_FEATURE_CAS
if (SecurityManager.SecurityEnabled) {
new EnvironmentPermission (EnvironmentPermissionAccess.Read, variable).Demand ();
}
#endif
return internalGetEnvironmentVariable (variable);
}
static Hashtable GetEnvironmentVariablesNoCase ()
{
Hashtable vars = new Hashtable (CaseInsensitiveHashCodeProvider.Default,
CaseInsensitiveComparer.Default);
foreach (string name in GetEnvironmentVariableNames ()) {
vars [name] = internalGetEnvironmentVariable (name);
}
return vars;
}
/// <summary>
/// Return a set of all environment variables and their values
/// </summary>
#if !MOBILE
public static IDictionary GetEnvironmentVariables ()
{
StringBuilder sb = null;
if (SecurityManager.SecurityEnabled) {
// we must have access to each variable to get the lot
sb = new StringBuilder ();
// but (performance-wise) we do not want a stack-walk
// for each of them so we concatenate them
}
Hashtable vars = new Hashtable ();
foreach (string name in GetEnvironmentVariableNames ()) {
vars [name] = internalGetEnvironmentVariable (name);
if (sb != null) {
sb.Append (name);
sb.Append (";");
}
}
if (sb != null) {
new EnvironmentPermission (EnvironmentPermissionAccess.Read, sb.ToString ()).Demand ();
}
return vars;
}
#else
[EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
public static IDictionary GetEnvironmentVariables ()
{
Hashtable vars = new Hashtable ();
foreach (string name in GetEnvironmentVariableNames ()) {
vars [name] = internalGetEnvironmentVariable (name);
}
return vars;
}
#endif
/// <summary>
/// Returns the fully qualified path of the
/// folder specified by the "folder" parameter
/// </summary>
public static string GetFolderPath (SpecialFolder folder)
{
return GetFolderPath (folder, SpecialFolderOption.None);
}
#if !MONOTOUCH
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern static string GetWindowsFolderPath (int folder);
public
static string GetFolderPath(SpecialFolder folder, SpecialFolderOption option)
{
SecurityManager.EnsureElevatedPermissions (); // this is a no-op outside moonlight
string dir = null;
if (Environment.IsRunningOnWindows)
dir = GetWindowsFolderPath ((int) folder);
else
dir = UnixGetFolderPath (folder, option);
#if MONO_FEATURE_CAS
if ((dir != null) && (dir.Length > 0) && SecurityManager.SecurityEnabled) {
new FileIOPermission (FileIOPermissionAccess.PathDiscovery, dir).Demand ();
}
#endif
return dir;
}
private static string ReadXdgUserDir (string config_dir, string home_dir, string key, string fallback)
{
string env_path = internalGetEnvironmentVariable (key);
if (env_path != null && env_path != String.Empty) {
return env_path;
}
string user_dirs_path = Path.Combine (config_dir, "user-dirs.dirs");
if (!File.Exists (user_dirs_path)) {
return Path.Combine (home_dir, fallback);
}
try {
using(StreamReader reader = new StreamReader (user_dirs_path)) {
string line;
while ((line = reader.ReadLine ()) != null) {
line = line.Trim ();
int delim_index = line.IndexOf ('=');
if(delim_index > 8 && line.Substring (0, delim_index) == key) {
string path = line.Substring (delim_index + 1).Trim ('"');
bool relative = false;
if (path.StartsWithOrdinalUnchecked ("$HOME/")) {
relative = true;
path = path.Substring (6);
} else if (!path.StartsWithOrdinalUnchecked ("/")) {
relative = true;
}
return relative ? Path.Combine (home_dir, path) : path;
}
}
}
} catch (FileNotFoundException) {
}
return Path.Combine (home_dir, fallback);
}
// the security runtime (and maybe other parts of corlib) needs the
// information to initialize themselves before permissions can be checked
internal static string UnixGetFolderPath (SpecialFolder folder, SpecialFolderOption option)
{
string home = internalGetHome ();
// http://freedesktop.org/Standards/basedir-spec/basedir-spec-0.6.html
// note: skip security check for environment variables
string data = internalGetEnvironmentVariable ("XDG_DATA_HOME");
if ((data == null) || (data == String.Empty)) {
data = Path.Combine (home, ".local");
data = Path.Combine (data, "share");
}
// note: skip security check for environment variables
string config = internalGetEnvironmentVariable ("XDG_CONFIG_HOME");
if ((config == null) || (config == String.Empty)) {
config = Path.Combine (home, ".config");
}
switch (folder) {
// MyComputer is a virtual directory
case SpecialFolder.MyComputer:
return String.Empty;
// personal == ~
case SpecialFolder.Personal:
return home;
// use FDO's CONFIG_HOME. This data will be synced across a network like the windows counterpart.
case SpecialFolder.ApplicationData:
return config;
//use FDO's DATA_HOME. This is *NOT* synced
case SpecialFolder.LocalApplicationData:
return data;
case SpecialFolder.Desktop:
case SpecialFolder.DesktopDirectory:
return ReadXdgUserDir (config, home, "XDG_DESKTOP_DIR", "Desktop");
case SpecialFolder.MyMusic:
if (Platform == PlatformID.MacOSX)
return Path.Combine (home, "Music");
else
return ReadXdgUserDir (config, home, "XDG_MUSIC_DIR", "Music");
case SpecialFolder.MyPictures:
if (Platform == PlatformID.MacOSX)
return Path.Combine (home, "Pictures");
else
return ReadXdgUserDir (config, home, "XDG_PICTURES_DIR", "Pictures");
case SpecialFolder.Templates:
return ReadXdgUserDir (config, home, "XDG_TEMPLATES_DIR", "Templates");
case SpecialFolder.MyVideos:
return ReadXdgUserDir (config, home, "XDG_VIDEOS_DIR", "Videos");
case SpecialFolder.CommonTemplates:
return "/usr/share/templates";
case SpecialFolder.Fonts:
if (Platform == PlatformID.MacOSX)
return Path.Combine (home, "Library", "Fonts");
return Path.Combine (home, ".fonts");
// these simply dont exist on Linux
// The spec says if a folder doesnt exist, we
// should return ""
case SpecialFolder.Favorites:
if (Platform == PlatformID.MacOSX)
return Path.Combine (home, "Library", "Favorites");
else
return String.Empty;
case SpecialFolder.ProgramFiles:
if (Platform == PlatformID.MacOSX)
return "/Applications";
else
return String.Empty;
case SpecialFolder.InternetCache:
if (Platform == PlatformID.MacOSX)
return Path.Combine (home, "Library", "Caches");
else
return String.Empty;
// #2873
case SpecialFolder.UserProfile:
return home;
case SpecialFolder.Programs:
case SpecialFolder.SendTo:
case SpecialFolder.StartMenu:
case SpecialFolder.Startup:
case SpecialFolder.Cookies:
case SpecialFolder.History:
case SpecialFolder.Recent:
case SpecialFolder.CommonProgramFiles:
case SpecialFolder.System:
case SpecialFolder.NetworkShortcuts:
case SpecialFolder.CommonStartMenu:
case SpecialFolder.CommonPrograms:
case SpecialFolder.CommonStartup:
case SpecialFolder.CommonDesktopDirectory:
case SpecialFolder.PrinterShortcuts:
case SpecialFolder.Windows:
case SpecialFolder.SystemX86:
case SpecialFolder.ProgramFilesX86:
case SpecialFolder.CommonProgramFilesX86:
case SpecialFolder.CommonDocuments:
case SpecialFolder.CommonAdminTools:
case SpecialFolder.AdminTools:
case SpecialFolder.CommonMusic:
case SpecialFolder.CommonPictures:
case SpecialFolder.CommonVideos:
case SpecialFolder.Resources:
case SpecialFolder.LocalizedResources:
case SpecialFolder.CommonOemLinks:
case SpecialFolder.CDBurning:
return String.Empty;
// This is where data common to all users goes
case SpecialFolder.CommonApplicationData:
return "/usr/share";
default:
throw new ArgumentException ("Invalid SpecialFolder");
}
}
#endif
[EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
public static string[] GetLogicalDrives ()
{
return GetLogicalDrivesInternal ();
}
#if !MOBILE
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private static extern void internalBroadcastSettingChange ();
public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
{
switch (target) {
case EnvironmentVariableTarget.Process:
return GetEnvironmentVariable (variable);
case EnvironmentVariableTarget.Machine:
new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
if (!IsRunningOnWindows)
return null;
using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
object regvalue = env.GetValue (variable);
return (regvalue == null) ? null : regvalue.ToString ();
}
case EnvironmentVariableTarget.User:
new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
if (!IsRunningOnWindows)
return null;
using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.CurrentUser.OpenSubKey ("Environment", false)) {
object regvalue = env.GetValue (variable);
return (regvalue == null) ? null : regvalue.ToString ();
}
default:
throw new ArgumentException ("target");
}
}
public static IDictionary GetEnvironmentVariables (EnvironmentVariableTarget target)
{
IDictionary variables = (IDictionary)new Hashtable ();
switch (target) {
case EnvironmentVariableTarget.Process:
variables = GetEnvironmentVariables ();
break;
case EnvironmentVariableTarget.Machine:
new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
if (IsRunningOnWindows) {
using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment")) {
string[] value_names = env.GetValueNames ();
foreach (string value_name in value_names)
variables.Add (value_name, env.GetValue (value_name));
}
}
break;
case EnvironmentVariableTarget.User:
new EnvironmentPermission (PermissionState.Unrestricted).Demand ();
if (IsRunningOnWindows) {
using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.CurrentUser.OpenSubKey ("Environment")) {
string[] value_names = env.GetValueNames ();
foreach (string value_name in value_names)
variables.Add (value_name, env.GetValue (value_name));
}
}
break;
default:
throw new ArgumentException ("target");
}
return variables;
}
[EnvironmentPermission (SecurityAction.Demand, Unrestricted=true)]
public static void SetEnvironmentVariable (string variable, string value)
{
SetEnvironmentVariable (variable, value, EnvironmentVariableTarget.Process);
}
[EnvironmentPermission (SecurityAction.Demand, Unrestricted = true)]
public static void SetEnvironmentVariable (string variable, string value, EnvironmentVariableTarget target)
{
if (variable == null)
throw new ArgumentNullException ("variable");
if (variable == String.Empty)
throw new ArgumentException ("String cannot be of zero length.", "variable");
if (variable.IndexOf ('=') != -1)
throw new ArgumentException ("Environment variable name cannot contain an equal character.", "variable");
if (variable[0] == '\0')
throw new ArgumentException ("The first char in the string is the null character.", "variable");
switch (target) {
case EnvironmentVariableTarget.Process:
InternalSetEnvironmentVariable (variable, value);
break;
case EnvironmentVariableTarget.Machine:
if (!IsRunningOnWindows)
return;
using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.LocalMachine.OpenSubKey (@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment", true)) {
if (String.IsNullOrEmpty (value))
env.DeleteValue (variable, false);
else
env.SetValue (variable, value);
internalBroadcastSettingChange ();
}
break;
case EnvironmentVariableTarget.User:
if (!IsRunningOnWindows)
return;
using (Microsoft.Win32.RegistryKey env = Microsoft.Win32.Registry.CurrentUser.OpenSubKey ("Environment", true)) {
if (String.IsNullOrEmpty (value))
env.DeleteValue (variable, false);
else
env.SetValue (variable, value);
internalBroadcastSettingChange ();
}
break;
default:
throw new ArgumentException ("target");
}
}
#else
public static string GetEnvironmentVariable (string variable, EnvironmentVariableTarget target)
{
if (target == EnvironmentVariableTarget.Process)
return GetEnvironmentVariable (variable);
return null;
}
public static IDictionary GetEnvironmentVariables (EnvironmentVariableTarget target)
{
if (target == EnvironmentVariableTarget.Process)
return GetEnvironmentVariables ();
return (IDictionary)new Hashtable ();
}
public static void SetEnvironmentVariable (string variable, string value)
{
if (variable == null)
throw new ArgumentNullException ("variable");
if (variable == String.Empty)
throw new ArgumentException ("String cannot be of zero length.", "variable");
if (variable.IndexOf ('=') != -1)
throw new ArgumentException ("Environment variable name cannot contain an equal character.", "variable");
if (variable[0] == '\0')
throw new ArgumentException ("The first char in the string is the null character.", "variable");
InternalSetEnvironmentVariable (variable, value);
}
public static void SetEnvironmentVariable (string variable, string value, EnvironmentVariableTarget target)
{
if (target == EnvironmentVariableTarget.Process)
SetEnvironmentVariable (variable, value);
// other targets ignored
}
#endif
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal unsafe static extern void InternalSetEnvironmentVariable (char *variable, int variable_length,
char *value, int value_length);
internal unsafe static void InternalSetEnvironmentVariable (string variable, string value)
{
fixed (char *fixed_variable = variable)
fixed (char *fixed_value = value)
InternalSetEnvironmentVariable (fixed_variable, variable?.Length ?? 0,
fixed_value, value?.Length ?? 0);
}
[SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode=true)]
public static void FailFast (string message)
{
throw new NotImplementedException ();
}
internal static void FailFast (String message, uint exitCode)
{
throw new NotImplementedException ();
}
[SecurityCritical]
public static void FailFast (string message, Exception exception)
{
#pragma warning disable 618
throw new ExecutionEngineException (message, exception);
#pragma warning restore
}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
extern static bool GetIs64BitOperatingSystem ();
public static bool Is64BitOperatingSystem {
get { return GetIs64BitOperatingSystem (); }
}
public static int SystemPageSize {
get { return GetPageSize (); }
}
public
static bool Is64BitProcess {
get { return IntPtr.Size == 8; }
}
public static extern int ProcessorCount {
[EnvironmentPermission (SecurityAction.Demand, Read="NUMBER_OF_PROCESSORS")]
[MethodImplAttribute (MethodImplOptions.InternalCall)]
get;
}
// private methods
#if (MONOTOUCH || MONODROID || XAMMAC)
internal const bool IsRunningOnWindows = false;
#else
internal static bool IsRunningOnWindows {
get { return ((int) Platform < 4); }
}
#endif
#if !MOBILE
//
// Used by gacutil.exe
//
#pragma warning disable 169
private static string GacPath {
get {
if (Environment.IsRunningOnWindows) {
/* On windows, we don't know the path where mscorlib.dll will be installed */
string corlibDir = new DirectoryInfo (Path.GetDirectoryName (typeof (int).Assembly.Location)).Parent.Parent.FullName;
return Path.Combine (Path.Combine (corlibDir, "mono"), "gac");
}
return Path.Combine (Path.Combine (internalGetGacPath (), "mono"), "gac");
}
}
#pragma warning restore 169
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static string internalGetGacPath ();
#endif
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static string [] GetLogicalDrivesInternal ();
[MethodImplAttribute (MethodImplOptions.InternalCall)]
private extern static string [] GetEnvironmentVariableNames ();
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static string GetMachineConfigPath ();
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static string internalGetHome ();
[MethodImplAttribute (MethodImplOptions.InternalCall)]
internal extern static int GetPageSize ();
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern private static string get_bundled_machine_config ();
internal static string GetBundledMachineConfig ()
{
return get_bundled_machine_config ();
}
static internal bool IsUnix {
get {
int platform = (int) Environment.Platform;
return (platform == 4 || platform == 128 || platform == 6);
}
}
static internal bool IsMacOS {
get {
return Environment.Platform == PlatformID.MacOSX;
}
}
internal static bool IsCLRHosted {
get {
return false;
}
}
internal static void TriggerCodeContractFailure(ContractFailureKind failureKind, String message, String condition, String exceptionAsString)
{
}
// Copied from referencesource Environment
internal static String GetStackTrace(Exception e, bool needFileInfo)
{
System.Diagnostics.StackTrace st;
if (e == null)
st = new System.Diagnostics.StackTrace(needFileInfo);
else
st = new System.Diagnostics.StackTrace(e, needFileInfo);
// Do not include a trailing newline for backwards compatibility
return st.ToString( System.Diagnostics.StackTrace.TraceFormat.Normal );
}
// Copied from referencesource Environment
internal static bool IsWinRTSupported
{
get
{
return true;
}
}
}
}