如何在不通过 Regedit 重启的情况下更改“控制面板”设置?

Ign*_*eti 3 control-panel reboot regedit windows-10

我想通过 regedit 更改 toast 通知显示时间。

这可以通过更改MessageDuration此注册表项下的值来完成:

HKEY_CURRENT_USER\Control Panel\Accessibility
Run Code Online (Sandbox Code Playgroud)

如果我通过控制面板更改此设置,将立即应用新设置。

但是,如果通过 regedit 更改此设置,除非我重新启动 Windows,否则不会应用新设置。

如何在不重新启动的情况下执行此操作?

Ben*_*n N 5

许多控制面板自定义设置旨在通过SystemParametersInfoWin32 功能进行更新。要更改通知消息持续时间,可以使用SPI_SETMESSAGEDURATION操作 (0x2017)调用该函数。这是一个 PowerShell 脚本,它采用一个参数来指定所需的消息持续时间(以秒为单位)并应用设置更改:

Param(
    [int]$MessageDuration
)

Add-Type @"
using System.Runtime.InteropServices;
public class PInvoke {
    [DllImport("user32.dll")] public static extern int SystemParametersInfo(int uiAction, int uiParam, System.IntPtr pvParam, int fWinIni);
}
"@

[PInvoke]::SystemParametersInfo(0x2017, 0, [IntPtr]$MessageDuration, 3)
Run Code Online (Sandbox Code Playgroud)

最后一个参数中的 3 设置了SPIF_UPDATEINIFILESPIF_SENDCHANGE标志,以便将新值写入注册表,并且所有应用程序都会收到设置更改通知。如果函数成功,则返回 1。

要使用该脚本,请将其另存为 PS1 文件,例如toasttime.ps1. 然后您可以从命令提示符调用它,如下所示:

powershell -executionpolicy bypass -c .\toasttime.ps1 60
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想通过其他方式应用已在注册表中设置的任何持续时间,您可以使用脚本的此变体从注册表中读取所需的持续时间,而不是采用参数:

Add-Type @"
using System.Runtime.InteropServices;
public class PInvoke {
    [DllImport("user32.dll")] public static extern int SystemParametersInfo(int uiAction, int uiParam, System.IntPtr pvParam, int fWinIni);
}
"@

$accessibility = Get-ItemProperty 'HKCU:\Control Panel\Accessibility'
[PInvoke]::SystemParametersInfo(0x2017, 0, [IntPtr]$accessibility.MessageDuration, 3)
Run Code Online (Sandbox Code Playgroud)