作成の背景
壁紙をスライドショー形式で設定しているのだが、時間帯によって参照フォルダーを変えたいというのが目的。
レジストリーにフォルダー・パスが直接記入されているだろうから、cmd.exe をタスク・スケジューラーから叩くだけで簡単に実現できるかと思いきや、どうも複雑な指定がされているみたいで、結局以下のスクリプトでテーマをまるごと切り替える方法を採ることとした。
コード
ThemeChanger.ps1
<# Theme Changer for Windows 10 by Jutha DDA #>
# .theme ファイルのパスを指定
[String]$pathTheme1 = "C:\Users\johndoe\AppData\Local\Microsoft\Windows\Themes\foo.theme"
[String]$pathTheme2 = "C:\Users\johndoe\AppData\Local\Microsoft\Windows\Themes\bar.theme"
[String]$pathTheme3 = "C:\Users\johndoe\AppData\Local\Microsoft\Windows\Themes\Roamed.theme"
# "HH:mm" 形式でテーマを変更する時刻を指定( 1<2<3 となるように指定すること)
[String]$timeStartTheme1 = "00:00"
[String]$timeStartTheme2 = "15:00"
[String]$timeStartTheme3 = "21:30"
# $timeStartThemesX を Get-Date に渡すために時と分に分解
$hour1 = [Int]($timeStartTheme1 -replace ":.*", "")
$minute1 = [Int]($timeStartTheme1 -replace ".*:", "")
$hour2 = [Int]($timeStartTheme2 -replace ":.*", "")
$minute2 = [Int]($timeStartTheme2 -replace ".*:", "")
$hour3 = [Int]($timeStartTheme3 -replace ":.*", "")
$minute3 = [Int]($timeStartTheme3 -replace ".*:", "")
# すでに SystemSetting ウィンドウが開いている場合、ページが遷移するため確認を行う。
$killSystemSettings = $true # SystemSettings が開いていない場合は、実行後ウィンドウを閉じる。
if ( (Get-Process | Where-Object { $_.ProcessName -eq "SystemSettings" }) ) {
Read-Host "テーマ変更スクリプトを続けるには、Enter を押してください(「設定」ウィンドウのページが「テーマ」に切り替わります)。"
$killSystemSettings = $false # SystemSettings が開いている場合は、実行後ウィンドウを閉じない
}
# 時刻に応じてテーマを切り替える。
if (
( ( Get-Date ) -ge ( Get-Date -Hour $hour1 -Minute $minute1 ) ) -and
( ( Get-Date ) -lt ( Get-Date -Hour $hour2 -Minute $minute2 ) )
) {
Start-Process $pathTheme1 -Wait
} elseif (
( ( Get-Date ) -ge ( Get-Date -Hour $hour2 -Minute $minute2 ) ) -and
( ( Get-Date ) -lt ( Get-Date -Hour $hour3 -Minute $minute3 ) )
) {
Start-Process $pathTheme2 -Wait
} else {
Start-Process $pathTheme3 -Wait
}
# SystemSettings が開くので閉じる(最初から開いていた場合は閉じない)。
if ( $killSystemSettings ) {
Get-Process | Where-Object { $_.ProcessName -eq "SystemSettings" } | ForEach-Object { $_.Kill() }
# SystemSetting プロセスが終了する前に、数秒ウィンドウが表示される場合がある。
}
※ Start-Process
は Invoke-Command
に変えても動く。
タスクスケジューラの設定
トリガー
- 「スケジュールに従う」>「毎日」を選択。
- スクリプトの
$timeStartTheme1
と同じ開始時刻を指定。 -
$timeStartTheme2
と$timeStartTheme3
についても、同様にトリガーを追加。
操作
- 「プログラムの開始」を選択。
- 「プログラム/スクリプト」に PowerShell のパス(
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
)を入力。 - 「引数の追加に」
-Command ".\WallpaperChanger.ps1"
と入力。 - 「開始」にスクリプト・ファイルのパス(例:
C:\User\johndoe\hoge fuga\piyo
)を入力(引用符""
も半角スペース等のエスケープ`
も不要)。
設定
- 「スケジュールされた時刻にタスクを開始できなかった場合、すぐにタスクを実行する」にチェックを入れる。
改善したい点
- 「設定」アプリ(SystemSettings.exe)の起動画面がどうしても表示されてしまうのを解消したい( 実行ファイルを指定してプロセスを起動していないためか、
-WindowStyle Hidden
は効果がなかった。) -
SystemSettings.exe の起動待ちを使えないと勘違いしていたfor
構文で実装しているのが、あまりスマートに思えないので、他の方法で起動を検知したい。Start-Process -Wait
が使えることが判明したため、修正。 - 「設定」アプリで他のページを開いていた場合、ページ遷移が発生してしまう問題もあるので、そもそも SystemSettings.exe を起動させないで、テーマを切り替えたい(さらにそもそもをいえば、「コントロールパネル」みたいに複数起動できないのをなんとかしてほしいと思うのだが)。
以上です。