我正试图将我的应用程序路径添加到系统环境路径中,而下面的代码确实适当地附加了它:
using (RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SYSTEMCurrentControlSetControlSession ManagerEnvironment", true)) {
String pathString = regKey.GetValue("PATH", "", RegistryValueOptions.DoNotExpandEnvironmentNames).ToString();
if (pathString[pathString.Length - 1] != ';') {
pathString = pathString + ";";
}
regKey.SetValue("PATH", pathString + Directory.GetCurrentDirectory() + ";");
}
在我通过控制面板查看环境变量之前,它不会生效,然后当我查看时,它会断开该路径中的所有其他环境变量引用,如%SystemRoot%\System32,直到。。。我将整个路径字符串从path变量中复制出来并返回到path变量中,然后重新保存
因此,我显然遗漏了一些内容,因为路径是100%正确的,只是它似乎没有针对系统进行更新。
编辑:我发现改变:
regKey.SetValue("PATH", pathString + Directory.GetCurrentDirectory() + ";");
收件人:
regKey.SetValue("PATH", pathString + Directory.GetCurrentDirectory() + ";", RegistryValueKind.ExpandString);
将修复中断引用变量的问题(不确定我为什么需要这样做,它们的键已经是REG_EXPAND_SZ类型,我不会更改它(,但我仍然存在路径在通过控制面板编辑之前不会刷新的问题。
到目前为止,我还没有找到一种程序化的方法来做到这一点。
好吧,用一点R&D、 似乎我需要向窗口广播WM_SETTINGCHANGE消息。我能够通过导入user32.dll函数SendMessageTimeout来实现这一点:
class NativeMsg {
public static readonly IntPtr HWND_BROADCAST = new IntPtr(0xffff);
public static readonly IntPtr HWND_TOP = new IntPtr(0);
public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
public static readonly IntPtr HWND_MESSAGE = new IntPtr(-3);
public enum WindowsMessages : UInt32 {
//For full list of WM_ constants reference: http://www.pinvoke.net/default.aspx/Constants.WM
WM_SETTINGCHANGE = 0x001A
}
[Flags]
public enum SendMessageTimeoutFlags : UInt32 {
SMTO_NORMAL = 0x0,
SMTO_BLOCK = 0x1,
SMTO_ABORTIFHUNG = 0x2,
SMTO_NOTIMEOUTIFNOTHUNG = 0x8,
SMTO_ERRORONEXIT = 0x20
}
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
IntPtr hWnd,
WindowsMessages Msg,
UIntPtr wParam,
String lParam,
SendMessageTimeoutFlags fuFlags,
UInt32 uTimeout,
out UIntPtr lpdwResult
);
}
然后在环境改变后用调用它
UIntPtr lRes;
NativeMsg.SendMessageTimeout(NativeMsg.HWND_BROADCAST, NativeMsg.WindowsMessages.WM_SETTINGCHANGE, UIntPtr.Zero, "Environment", NativeMsg.SendMessageTimeoutFlags.SMTO_ABORTIFHUNG, 1000, out lRes);
这似乎是有效的,这里可能有一些代码缺陷,因为我从pinvoke.net中列举了大部分代码缺陷,它的C#示例并没有逐字逐句地工作,但它确实完成了任务。