plugging/unplugging 笔记本电脑通过任务计划程序更改特定设置
Change a specific setting when plugging/unplugging laptop via task scheduler
免责声明:我用他们所代表的全部大写字符串更改了所有个人信息。
我将开门见山:我希望我的浏览器在我的笔记本电脑插入电源时使用我的 dGPU,而在未插入电源时使用我的 iGPU。
到目前为止,我已经在 Windows 设置中为我的浏览器设置了始终使用我的 dGPU(设置说:“高性能”):
然后每次我 plug/unplug 我的笔记本电脑我手动更改该设置并重新启动我的浏览器。
因为每次都这样做很烦人,我想使用 Windows 10 Task Scheduler 到 运行 一个脚本,当我的笔记本电脑启动时将设置更改为“高性能”当我的笔记本电脑被拔掉时,插入电源或将该设置更改为“节电”。
在这两种情况下,如果浏览器已打开,它还应通知用户重新启动浏览器以使更改生效。
我设法找到了这两个事件的日志:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Kernel-Power" Guid="{331c3b3a-2005-44c2-ac5e-77220c37d6b4}" />
<EventID>105</EventID>
<Version>1</Version>
<Level>4</Level>
<Task>100</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000404</Keywords>
<TimeCreated SystemTime="2022-05-28T09:44:34.5100785Z" />
<EventRecordID>13688</EventRecordID>
<Correlation />
<Execution ProcessID="4" ThreadID="3004" />
<Channel>System</Channel>
<Computer>COMPUTER</Computer>
<Security UserID="USERID" />
</System>
<EventData>
<Data Name="AcOnline">false</Data>
<Data Name="RemainingCapacity">30111</Data>
<Data Name="FullChargeCapacity">91245</Data>
</EventData>
</Event>
(堵塞事件的日志相同,但 AcOnline 设置为 true)。
我写的脚本如下:
Param([Parameter()][switch]$AcOnline)
enum GPU {
Integrated = 1
Dedicated = 2
}
function Update-Opera-GPU-Preference {
Param([Parameter()][GPU]$GPU)
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\DirectX\UserGpuPreferences\' -Name 'PATHTOPROGRAMS\Opera GX\opera.exe' -Value "GpuPreference=$($GPU.value__);"
}
function Restart-Opera {
Param([Parameter()]$opera)
$opera.CloseMainWindow()
Start-Sleep 3
if (!$opera.HasExited) {
$opera | Stop-Process -Force
}
$opera.Start() # Gives error. How to restart?
}
function Send-Preference-Changed-Toast {
Param([Parameter()]$opera)
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
$Template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
$RawXml = [xml] $Template.GetXml()
($RawXml.toast.visual.binding.text|Where-Object {$_.id -eq "1"}).AppendChild($RawXml.CreateTextNode("Opera GX GPU setting changed")) > $null
($RawXml.toast.visual.binding.text|Where-Object {$_.id -eq "2"}).AppendChild($RawXml.CreateTextNode("Restart Opera GX for the change to take effect")) > $null
# Add on click behavior to restart opera if opera is open
# Restart-Opera $opera
$SerializedXml = New-Object Windows.Data.Xml.Dom.XmlDocument
$SerializedXml.LoadXml($RawXml.OuterXml)
$Toast = [Windows.UI.Notifications.ToastNotification]::new($SerializedXml)
$Toast.Tag = "Task Scheduler"
$Toast.Group = "Task Scheduler"
$Toast.ExpirationTime = [DateTimeOffset]::Now.AddMinutes(1)
$Notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("Task Scheduler")
$Notifier.Show($Toast);
}
Update-Opera-GPU-Preference $(if ($AcOnline.IsPresent) {[GPU]::Dedicated} else {[GPU]::Integrated})
$opera = Get-Process opera -ErrorAction SilentlyContinue
if ($opera) {
Send-Preference-Changed-Toast $opera
}
Remove-Variable opera
然后我创建了这样的任务:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2022-05-28T10:52:12.1836624</Date>
<Author>AUTHOR</Author>
<URI>\Change Opera GX GPU Setting</URI>
</RegistrationInfo>
<Triggers>
<EventTrigger>
<Enabled>true</Enabled>
<Subscription><QueryList><Query Id="0" Path="Microsoft-Windows-Kernel-Power/Thermal-Operational"><Select Path="Microsoft-Windows-Kernel-Power/Thermal-Operational">*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and EventID=105]]</Select></Query></QueryList></Subscription>
</EventTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>USERID</UserId>
<LogonType>Password</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<RestartOnFailure>
<Interval>PT1M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell</Command>
<Arguments>-ExecutionPolicy Bypass -File PATHTOSCRIPTFOLDER\opera-gpu-setting-update.ps1</Arguments>
</Exec>
</Actions>
</Task>
如果我手动 运行 任务,它工作正常。但是,如果我插入笔记本电脑,它只会用 Windows 记事本打开脚本文件,而不是 运行ning 脚本。此外,如果我拔下笔记本电脑,任务似乎根本不会 运行(没有脚本正在执行,记事本也不会打开)。
为什么会这样?我该如何解决这个问题?
如何在我的脚本中实现注释中描述的部分?
最后打开记事本是因为我错误地创建了另一个任务
真正的问题是订阅标签值错误。为了修复它,我转到 Windows 事件记录器并从 Kernel-Power 事件创建了一个新任务,然后复制了它的 XML 订阅标签并将其粘贴到我的任务 XML 中。
更新后的标签如下所示:
<Subscription><QueryList><Query Id="0" Path="System"><Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and EventID=105]]</Select></Query></QueryList></Subscription>
免责声明:我用他们所代表的全部大写字符串更改了所有个人信息。
我将开门见山:我希望我的浏览器在我的笔记本电脑插入电源时使用我的 dGPU,而在未插入电源时使用我的 iGPU。
到目前为止,我已经在 Windows 设置中为我的浏览器设置了始终使用我的 dGPU(设置说:“高性能”):
然后每次我 plug/unplug 我的笔记本电脑我手动更改该设置并重新启动我的浏览器。
因为每次都这样做很烦人,我想使用 Windows 10 Task Scheduler 到 运行 一个脚本,当我的笔记本电脑启动时将设置更改为“高性能”当我的笔记本电脑被拔掉时,插入电源或将该设置更改为“节电”。
在这两种情况下,如果浏览器已打开,它还应通知用户重新启动浏览器以使更改生效。
我设法找到了这两个事件的日志:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-Kernel-Power" Guid="{331c3b3a-2005-44c2-ac5e-77220c37d6b4}" />
<EventID>105</EventID>
<Version>1</Version>
<Level>4</Level>
<Task>100</Task>
<Opcode>0</Opcode>
<Keywords>0x8000000000000404</Keywords>
<TimeCreated SystemTime="2022-05-28T09:44:34.5100785Z" />
<EventRecordID>13688</EventRecordID>
<Correlation />
<Execution ProcessID="4" ThreadID="3004" />
<Channel>System</Channel>
<Computer>COMPUTER</Computer>
<Security UserID="USERID" />
</System>
<EventData>
<Data Name="AcOnline">false</Data>
<Data Name="RemainingCapacity">30111</Data>
<Data Name="FullChargeCapacity">91245</Data>
</EventData>
</Event>
(堵塞事件的日志相同,但 AcOnline 设置为 true)。
我写的脚本如下:
Param([Parameter()][switch]$AcOnline)
enum GPU {
Integrated = 1
Dedicated = 2
}
function Update-Opera-GPU-Preference {
Param([Parameter()][GPU]$GPU)
Set-ItemProperty -Path 'HKCU:\Software\Microsoft\DirectX\UserGpuPreferences\' -Name 'PATHTOPROGRAMS\Opera GX\opera.exe' -Value "GpuPreference=$($GPU.value__);"
}
function Restart-Opera {
Param([Parameter()]$opera)
$opera.CloseMainWindow()
Start-Sleep 3
if (!$opera.HasExited) {
$opera | Stop-Process -Force
}
$opera.Start() # Gives error. How to restart?
}
function Send-Preference-Changed-Toast {
Param([Parameter()]$opera)
[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] > $null
$Template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)
$RawXml = [xml] $Template.GetXml()
($RawXml.toast.visual.binding.text|Where-Object {$_.id -eq "1"}).AppendChild($RawXml.CreateTextNode("Opera GX GPU setting changed")) > $null
($RawXml.toast.visual.binding.text|Where-Object {$_.id -eq "2"}).AppendChild($RawXml.CreateTextNode("Restart Opera GX for the change to take effect")) > $null
# Add on click behavior to restart opera if opera is open
# Restart-Opera $opera
$SerializedXml = New-Object Windows.Data.Xml.Dom.XmlDocument
$SerializedXml.LoadXml($RawXml.OuterXml)
$Toast = [Windows.UI.Notifications.ToastNotification]::new($SerializedXml)
$Toast.Tag = "Task Scheduler"
$Toast.Group = "Task Scheduler"
$Toast.ExpirationTime = [DateTimeOffset]::Now.AddMinutes(1)
$Notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("Task Scheduler")
$Notifier.Show($Toast);
}
Update-Opera-GPU-Preference $(if ($AcOnline.IsPresent) {[GPU]::Dedicated} else {[GPU]::Integrated})
$opera = Get-Process opera -ErrorAction SilentlyContinue
if ($opera) {
Send-Preference-Changed-Toast $opera
}
Remove-Variable opera
然后我创建了这样的任务:
<?xml version="1.0" encoding="UTF-16"?>
<Task version="1.4" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<RegistrationInfo>
<Date>2022-05-28T10:52:12.1836624</Date>
<Author>AUTHOR</Author>
<URI>\Change Opera GX GPU Setting</URI>
</RegistrationInfo>
<Triggers>
<EventTrigger>
<Enabled>true</Enabled>
<Subscription><QueryList><Query Id="0" Path="Microsoft-Windows-Kernel-Power/Thermal-Operational"><Select Path="Microsoft-Windows-Kernel-Power/Thermal-Operational">*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and EventID=105]]</Select></Query></QueryList></Subscription>
</EventTrigger>
</Triggers>
<Principals>
<Principal id="Author">
<UserId>USERID</UserId>
<LogonType>Password</LogonType>
<RunLevel>HighestAvailable</RunLevel>
</Principal>
</Principals>
<Settings>
<MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
<DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
<StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
<AllowHardTerminate>true</AllowHardTerminate>
<StartWhenAvailable>true</StartWhenAvailable>
<RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
<IdleSettings>
<StopOnIdleEnd>true</StopOnIdleEnd>
<RestartOnIdle>false</RestartOnIdle>
</IdleSettings>
<AllowStartOnDemand>true</AllowStartOnDemand>
<Enabled>true</Enabled>
<Hidden>false</Hidden>
<RunOnlyIfIdle>false</RunOnlyIfIdle>
<DisallowStartOnRemoteAppSession>false</DisallowStartOnRemoteAppSession>
<UseUnifiedSchedulingEngine>true</UseUnifiedSchedulingEngine>
<WakeToRun>false</WakeToRun>
<ExecutionTimeLimit>PT0S</ExecutionTimeLimit>
<Priority>7</Priority>
<RestartOnFailure>
<Interval>PT1M</Interval>
<Count>3</Count>
</RestartOnFailure>
</Settings>
<Actions Context="Author">
<Exec>
<Command>powershell</Command>
<Arguments>-ExecutionPolicy Bypass -File PATHTOSCRIPTFOLDER\opera-gpu-setting-update.ps1</Arguments>
</Exec>
</Actions>
</Task>
如果我手动 运行 任务,它工作正常。但是,如果我插入笔记本电脑,它只会用 Windows 记事本打开脚本文件,而不是 运行ning 脚本。此外,如果我拔下笔记本电脑,任务似乎根本不会 运行(没有脚本正在执行,记事本也不会打开)。
为什么会这样?我该如何解决这个问题?
如何在我的脚本中实现注释中描述的部分?
最后打开记事本是因为我错误地创建了另一个任务
真正的问题是订阅标签值错误。为了修复它,我转到 Windows 事件记录器并从 Kernel-Power 事件创建了一个新任务,然后复制了它的 XML 订阅标签并将其粘贴到我的任务 XML 中。
更新后的标签如下所示:
<Subscription><QueryList><Query Id="0" Path="System"><Select Path="System">*[System[Provider[@Name='Microsoft-Windows-Kernel-Power'] and EventID=105]]</Select></Query></QueryList></Subscription>