先月末くらいにインフラが更新されたせいなのか、Windows Update 側に何らかの変更が加わったのか、原因は不明だが、承前の話が解決して自動アップデートが無事通って 1909 → 20H2 になったのが昨日の話。
で、こいつ 2022-05-10 がサポート終了予定日なので、余命1ヶ月を切ってるんで、とっとと 21H2 振ってきてほしいのだが、何故か振ってこない。
それはさておき、タイトルの件。
winget は App Installer に同梱されたので、Microsoft Store で勝手に最新版にアップデートされて winget.exe は含まれてるはずなのに PATH が通ってないと言われる。
winget は
確認してみるとちゃんとある。アプリ実行エイリアスも ON になっていた。
おかしいなーと思って、環境変数 Path を確認してみる以下の通り。
レジストリ確認してみると、なぜか REG_EXPAND_SZ じゃなくて REG_SZ になっている。
どこで、REG_EXPAND_SZ から REG_SZ にすり替わった?
とりあえず、PowerShell から
これで直った。
直ったんだけど、PowerShell の sp (Set-ItemProperty) で Path の型を REG_EXPAND_SZ ↔ REG_SZ で変更してもこの設定は即座には反映されない。
「システムのプロパティ」ダイアログの「詳細設定」タブ(SystemPropertiesAdvanced.exe)から、「環境変数」 ダイアログ開いて「OK」で閉じたタイミングで反映される。
これ、「環境変数」ダイアログが何か特殊なことしてるの間違いないけど、要 GUI 操作なので Path の変更自動化できんじゃん orz
「reg_expand_sz update not expand」でググってみたところ以下のページを見つけた。
RegenerateUserEnvironment in shell32.dll って何よ!?
どうも「環境変数」 ダイアログで Path 変更すると新しく立ち上げたプロセスには環境変数が即座に反映されるのは、 こいつが関係してそうな雰囲気だが、ExpandEnvironmentStrings() がその場で expand せずプロセス起動時の状態使うの衝撃だわ。
ってことで、「regenerateuserenvironment」でググってみるが、断片的な情報しか見つからない。
第2引数がTRUEなら自身の環境も同時に更新され、FALSEなら自身の環境はそのままということだが、これは子プロセスに渡す用の環境変数を作るやつ???
なんか、
という事で「WM_SETTINGCHANGE powershell」でググったら以下の gist を見つけた。
素晴らしい。これです。求めてたのこれです。
Set-ItemProperty した結果が即座に explorer.exe に反映されました。
で、この WM_SETTINGCHANGE の件、セパレートして にまとめたんだけど、REG_SZ 縛りがあるものの [Environment]::SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) が WM_SETTINGCHANGE 発行してくれるの分かったので、WM_SETTINGCHANGE を発行するために SetTimeoutMessage() インポートするよりは、無いと分かってる変数をこいつで消す方が一番手間が少ないので以下のコードで WM_SETTINGCHANGE 発行しとけって結論に至った。
で、こいつ 2022-05-10 がサポート終了予定日なので、余命1ヶ月を切ってるんで、とっとと 21H2 振ってきてほしいのだが、何故か振ってこない。
それはさておき、タイトルの件。
winget は App Installer に同梱されたので、Microsoft Store で勝手に最新版にアップデートされて winget.exe は含まれてるはずなのに PATH が通ってないと言われる。
> gcm winget.exe gcm : 用語 'winget.exe' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されま せん。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してく ださい。 発生場所 行:1 文字:1 + gcm winget.exe + ~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (winget.exe:String) [Get-Command], CommandNotFoundException + FullyQualifiedErrorId : CommandNotFoundException,Microsoft.PowerShell.Commands.GetCommandCommand
winget は
- Microsoft / Developer Blog / Command Line / 2021-05-26: Windows Package Manager 1.0
- Microsoft / Docs / Windows の開発環境 / 開発者用ツール / Windows パッケージマネージャー / 2022-04-03: winget ツールを使用したアプリケーションのインストールと管理
確認してみるとちゃんとある。アプリ実行エイリアスも ON になっていた。
PS C:\Users\kou> Get-AppxPackage |? name -match installer Name : Microsoft.DesktopAppInstaller Publisher : CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US Architecture : X64 ResourceId : Version : 1.17.10271.0 PackageFullName : Microsoft.DesktopAppInstaller_1.17.10271.0_x64__8wekyb3d8bbwe InstallLocation : C:\Program Files\WindowsApps\Microsoft.DesktopAppInstaller_1.17.10271.0_x64__8wekyb3d8bbwe IsFramework : False PackageFamilyName : Microsoft.DesktopAppInstaller_8wekyb3d8bbwe PublisherId : 8wekyb3d8bbwe IsResourcePackage : False IsBundle : False IsDevelopmentMode : False NonRemovable : False Dependencies : {Microsoft.UI.Xaml.2.7_7.2203.17001.0_x64__8wekyb3d8bbwe, Microsoft.VCLibs.140.00.UWPDesktop_14.0.3 0704.0_x64__8wekyb3d8bbwe, Microsoft.DesktopAppInstaller_1.17.10271.0_neutral_split.language-ja_8we kyb3d8bbwe, Microsoft.DesktopAppInstaller_1.17.10271.0_neutral_split.scale-100_8wekyb3d8bbwe} IsPartiallyStaged : False SignatureKind : Store Status : Ok
PS C:\Users\kou> Get-AppxPackage |? name -match installer | Get-AppxPackageManifest |% Package |% Applications |% Application Id : App Executable : AppInstaller.exe EntryPoint : AppInstaller.App VisualElements : VisualElements Extensions : Extensions Id : PythonRedirector Executable : AppInstallerPythonRedirector.exe EntryPoint : Windows.FullTrustApplication VisualElements : VisualElements Extensions : Extensions Id : winget Executable : winget.exe EntryPoint : Windows.FullTrustApplication VisualElements : VisualElements Extensions : Extensions
おかしいなーと思って、環境変数 Path を確認してみる以下の通り。
PS C:\Users\kou> $Env:Path -split ";" |sls WindowsApps %USERPROFILE%\AppData\Local\Microsoft\WindowsApps一瞬、ちゃんと設定されてるのに、と思ったのだが、あれ? %USERPROFILE% が展開されてないのでは!?
レジストリ確認してみると、なぜか REG_EXPAND_SZ じゃなくて REG_SZ になっている。
PS C:\Users\kou> REG Query HKCU\Environment /V Path HKEY_CURRENT_USER\Environment Path REG_SZ C:\Users\kou\local\bin;C:\Users\kou\local\w32tex\bin;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\borland\bcc55\Bin;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;嘘やん。
どこで、REG_EXPAND_SZ から REG_SZ にすり替わった?
とりあえず、PowerShell から
PS C:\Users\kou> $path = (gi Registry::HKEY_CURRENT_USER\Environment).GetValue("Path",$null,"DoNotExpandEnvironmentNames")のようにして $path に現状の REG_EXPAND_SZ の値を展開しない状態で取り出して
PS C:\Users\kou> $path C:\Users\kou\local\bin;C:\Users\kou\local\w32tex\bin;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\borland\bcc55\Bin;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;
PS C:\Users\kou> $path -split ";" C:\Users\kou\local\bin C:\Users\kou\local\w32tex\bin C:\Program Files\Intel\WiFi\bin\ C:\Program Files\Common Files\Intel\WirelessCommon\ C:\borland\bcc55\Bin %USERPROFILE%\AppData\Local\Microsoft\WindowsAppsのような値を
PS C:\Users\kou> sp Registry::HKEY_CURRENT_USER\Environment Path $path -Type ExpandStringとして書き込むことで
PS C:\Users\kou> REG QUERY HKCU\Environment /V Path HKEY_CURRENT_USER\Environment Path REG_EXPAND_SZ C:\Users\kou\local\bin;C:\Users\kou\local\w32tex\bin;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\borland\bcc55\Bin;%USERPROFILE%\AppData\Local\Microsoft\WindowsApps;のように、REG_EXPAND_SZ 型に入れ直した。
これで直った。
直ったんだけど、PowerShell の sp (Set-ItemProperty) で Path の型を REG_EXPAND_SZ ↔ REG_SZ で変更してもこの設定は即座には反映されない。
「システムのプロパティ」ダイアログの「詳細設定」タブ(SystemPropertiesAdvanced.exe)から、「環境変数」 ダイアログ開いて「OK」で閉じたタイミングで反映される。
これ、「環境変数」ダイアログが何か特殊なことしてるの間違いないけど、要 GUI 操作なので Path の変更自動化できんじゃん orz
「reg_expand_sz update not expand」でググってみたところ以下のページを見つけた。
- GitHub / microsoft / terminal / issues / 2021-04-07: REG_EXPAND_SZ environment variables not properly expanded for shells #9741
RegenerateUserEnvironment in shell32.dll って何よ!?
どうも「環境変数」 ダイアログで Path 変更すると新しく立ち上げたプロセスには環境変数が即座に反映されるのは、 こいつが関係してそうな雰囲気だが、ExpandEnvironmentStrings() がその場で expand せずプロセス起動時の状態使うの衝撃だわ。
ってことで、「regenerateuserenvironment」でググってみるが、断片的な情報しか見つからない。
- ハングアップの日々 / 2010-05-30: URL memo
- 丁稚な日々 / 2008−03−03: [Win32] 小ネタ
- BOOL RegenerateUserEnvironment(WCHAR**, BOOL);
第2引数がTRUEなら自身の環境も同時に更新され、FALSEなら自身の環境はそのままということだが、これは子プロセスに渡す用の環境変数を作るやつ???
なんか、
シェル(Explorer)はこのWM_SETTINGCHANGEを受け取って、自分が持ってる環境変数領域を再生成して、以降子プロセスを起動する際に新しい環境変数領域を渡している。って言ってるけど、私が欲しいのはこいつなのでは???
という事で「WM_SETTINGCHANGE powershell」でググったら以下の gist を見つけた。
- Gist / alphp / NativeMethods.psm1
素晴らしい。これです。求めてたのこれです。
Set-ItemProperty した結果が即座に explorer.exe に反映されました。
で、この WM_SETTINGCHANGE の件、セパレートして にまとめたんだけど、REG_SZ 縛りがあるものの [Environment]::SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) が WM_SETTINGCHANGE 発行してくれるの分かったので、WM_SETTINGCHANGE を発行するために SetTimeoutMessage() インポートするよりは、無いと分かってる変数をこいつで消す方が一番手間が少ないので以下のコードで WM_SETTINGCHANGE 発行しとけって結論に至った。
[Environment]::SetEnvironmentVariable("WM_SETTINGCHANGE","","User")
HKCU\Environment の Path が REG_SZ になっていた場合の自動修正は以下のコマンドで OK
反映されてるかどうかの確認はショートカット キー [田]+[R] で「ファイル名を指定して実行」開いて、以下のコマンドを実行すると良い。
if ((gi HKCU:\Environment).GetValueKind("Path") -eq "String") {sp Registry::HKEY_CURRENT_USER\Environment Path (gi HKCU:\Environment).GetValue("Path",$null,"DoNotExpandEnvironmentNames") -Type ExpandString; [Environment]::SetEnvironmentVariable("WM_SETTINGCHANGE","","User")}
反映されてるかどうかの確認はショートカット キー [田]+[R] で「ファイル名を指定して実行」開いて、以下のコマンドを実行すると良い。
powershell -C "reg QUERY HKCU\Environment /v Path;$Env:Path -split """;""" |sls WindowsApp; pause"
タグ
コメントをかく