英語版WindowsのPowerShellで日本語ショートカットを作成するには
Windows10/PowerShell5.1環境を考えています(より古い環境にも対応していると嬉しいですが)。
PowerShellでショートカットを作成する方法を検索すると、こちらに書かれているような、 WScript.Shell
を利用した例が多くヒットします。
この方法は、日本語版Windowsではうまく動作したのですが、英語版Windows(Windows Server 2016 on EC2)で同様のコマンドを実行するとエラーが発生しショートカットは作成されませんでした。
script(UTF-8 with BOM):
$file= $Env:Temp + "\ほげほげ.txt"
$shortcut = $Env:Temp + "\ほげほげショートカット.lnk"
$WsShell = New-Object -ComObject WScript.Shell
$Shortcut = $WsShell.CreateShortcut($shortcut)
$Shortcut.TargetPath = $file
$Shortcut.IconLocation = $file
$Shortcut.Save()
結果:
> .\create.ps1
Value does not fall within the expected range.
At C:\Users\Administrator\AppData\Local\Temp\2\create.ps1:6 char:1
+ $Shortcut.TargetPath = $file
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException
Unable to save shortcut "C:\Users\ADMINI~1\AppData\Local\Temp\2\???????????.lnk".
At C:\Users\Administrator\AppData\Local\Temp\2\create.ps1:8 char:1
+ $Shortcut.Save()
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], FileNotFoundException
+ FullyQualifiedErrorId : System.IO.FileNotFoundException
検索したところ、同様の質問をされている方がいらっしゃった
のですが、
- リンク先はC#であり、PowerShellで同様の方法を実現するにはどうすればいいか分からない
- Windows8(以降?)では動作しないというコメントもあり、結局どうするのが正しいのか不明瞭
のような理由で解決には至っておりません。
(以下、回答を頂いた後追記)
sayuriさんの回答を元に、次のようなスクリプトを書いて実行してみたところ、英語環境でも想定通り日本語名ショートカットを作成することができました。
create_shortcut_revised.ps1
(UTF-8 with BOM):
$srcDir = Join-Path $Env:TEMP "src"
$srcName = "ほげほげ.txt"
$srcPath = Join-Path $srcDir $srcName
$destDir = Join-Path $Env:TEMP "dest"
$destName = "ほげほげショートカット.lnk"
$destPath = Join-Path $destDir $destName
## 前準備
# New-Item $srcDir -ItemType Directory -Force
# New-Item $destDir -ItemType Directory -Force
# New-item $srcPath -ItemType File -Force
New-Item $destPath -ItemType File -Force
$shl = New-Object -ComObject Shell.Application
$dir = $shl.NameSpace($destDir)
$itm = $dir.Items().Item($destName)
$lnk = $itm.GetLink
$lnk.Path = $srcPath
$lnk.Save($destPath)
現状、まだこの処理が何を行っているのかちゃんと理解できていませんが、メンバ名から逆算するに、New-Object -ComObject Shell.Application
で得られているのが Shell
オブジェクトなのかなと思いますので、この辺りを見ていこうかと考えています。
また、情報後出しになってしまって申し訳ありませんが、今回解決したい問題は他の人が作成した不特定の人が使うプログラム内のものなので、採れる対応にはいくらかの縛りがありました。