PowerShell运行后消息Windows API功能失败



我需要编写一个脚本以安装特定版本的Java运行时,添加到系统路径变量,然后继续运行Java程序。我想一口气做这一切,而不必重新启动目标计算机。

我发现了这个问题,并认为我可以尝试改变我的需求。

sendmessage导致脚本挂起

所以我根据答案尝试了后期。显然我需要更改消息。

所以我尝试了这样的代码:

echo Start of experiment
$NewPath = (Get-ItemProperty -Path "HKLM:SystemCurrentControlSetControlSession ManagerEnvironment" -Name Path).Path
$NewPath = "%JAVA_BIN%;" + $NewPath
$RegKey ="HKLM:SYSTEMCurrentControlSetControlSession ManagerEnvironment"
Set-ItemProperty -Path $RegKey -Name Path -Value $NewPath
echo Updated Path environment variable

# Next bit which isn't working
$HWND_BROADCAST = 0xffff
$WM_SETTINGCHANGE = 0x001A
$ENVIRON = "Environment"
#Store the C# signature of the PostMessage function. 
$signature = @"
[DllImport("user32.dll")]
public static extern int PostMessage(int hWnd, int hMsg, int wParam, int lParam);
"@
#Add the SendMessage function as a static method of a class
$PostMessage = Add-Type -MemberDefinition $signature -Name "Win32PostMessage" -Namespace Win32Functions -PassThru
#Invoke the PostMessage Function
$PostMessage::PostMessage($HWND_BROADCAST, $WM_SETTINGCHANGE, 0, $ENVIRON)
echo end of experiment

这是我的输出:

Start
of
experiment
Cannot convert argument "3", with value: "Environment", for "PostMessage" to type "System.Int32": "Cannot convert value "Environment" to type "System.Int32".
Error: "Input string was not in a correct format.""
At C:sharetvm_driversPEDsetenv.ps1:43 char:26
+ $PostMessage::PostMessage <<<< ($HWND_BROADCAST, $WM_SETTINGCHANGE, 0, $ENVIRON)
+ CategoryInfo          : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
end
of
experiment

我在Windows 7上运行此。

任何人可以帮忙吗?

对于一些背景,如果设置路径env变量后,请重新启动目标PC,则设置工作。但是,如果您不重新启动,则有必要在上面发送广播消息,以告诉任何其他窗口,包括命令提示符,以了解更改。这就是为什么我需要消息。

这是成功更新有关env Change的所有打开窗口的PowerShell。

# Notifies other processes that the global environment block has changed.
# This lets other processes see changes to ENV: without having to reboot
# or logoff/logon. A non-zero result from SendMessageTimeout indicates success.
if (-not ("win32.nativemethods" -as [type])) {
    # import sendmessagetimeout from win32
    add-type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern IntPtr SendMessageTimeout(
    IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
    uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
"@
}
$HWND_BROADCAST = [intptr]0xffff;
$WM_SETTINGCHANGE = 0x1a;
$result = [uintptr]::zero
# notify all windows of environment block change
[win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE,
    [uintptr]::Zero, "Environment", 2, 5000, [ref]$result);

最新更新