我最終找到了一種方法來加載用戶的EnvironmentBlock,提取每個變量並將它們加載到我現有的環境中。基於代碼和理念幾頁:
請原諒我的C#代碼,任何調整加讚賞:
[DllImport("userenv.dll", SetLastError = true)]
private static extern bool CreateEnvironmentBlock(ref IntPtr lpEnvironment, IntPtr hToken, bool bInherit);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, ref IntPtr TokenHandle);
private const uint TOKEN_QUERY = 0x0008;
[DllImport("kernel32.dll")]
static extern IntPtr GetCurrentProcess();
[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool CloseHandle(IntPtr hObject);
private static void ReloadEnviroVars()
{
IntPtr hToken = IntPtr.Zero;
IntPtr envBlock = IntPtr.Zero;
//Load this user's environment variables
OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, ref hToken);
bool retVal = CreateEnvironmentBlock(ref envBlock, hToken, false);
//Extract each environment variable from the envroblock and add it to
// our running program's environment vars
int offset = 0;
while (true) {
//EnviroBlock is an array of null-terminated unicode strings
IntPtr ptr = new IntPtr(envBlock.ToInt64() + offset);
string Enviro = Marshal.PtrToStringUni(ptr);
offset += Encoding.Unicode.GetByteCount(Enviro) + 2;
if (string.IsNullOrEmpty(Enviro))
break;
string EnviroKey = Enviro.Substring(0, Enviro.IndexOf("="));
string EnviroValue = Enviro.Substring(Enviro.IndexOf("=") + 1, Enviro.Length - 1 - Enviro.IndexOf("="));
Environment.SetEnvironmentVariable(EnviroKey, EnviroValue);
}
CloseHandle(hToken);
}
更新的代碼使用ToInt64而不是64位系統的ToInt32(超過4gig ram?)。 http://stackoverflow.com/a/1866268報告說,它只會在32位系統上使用更多的開銷,但會起作用。 – Halfdone 2013-02-01 16:50:01