https://github.com/osakanataro/showroom-live のPowerShellスクリプトを作っている際に問題となった点のメモ書きです。
その1:改行コード
改行コードはWindows10ならCR+LF、LinuxならLFにする必要がある。それぞれ逆だとエラーになった。
コードを共有するのであれば、git for Windowsを使って管理し、Windowsに持ってくる時に改行コードを変換するようにした方が良い。
github上でreleaseとしてzipを提供する場合は、github側の機能でzipを作ると改行コードがLFになるので、Windowsユーザ向けに改行コードをCR+LFにしたバージョンを追加でアップロードした方が良い。
その2:文字エンコーディング
Windows10上のVisual Studio Codeで日本語文字列を含んで保存したところ、UTF-8 BOMなしで保存され、それをLinuxに持って行ったところ問題無く動作した。
しかし、UTF-8 BOMなしのファイルをWindows10上のPowerShell ISEで開くと文字化けする。
PowerShell ISEではUTF-8 BOMありを想定しているということで、BOMありに変えてみたところ、Linux上では「#!/usr/bin/pwsh」の#!より前にBOMのコードが挿入されてしまうため問題が発生した。
Windows10標準notepadなどでの編集には全く問題なく、PowerShell ISEのみの問題であるため、PowerShell ISEでの編集を諦め、UTF-8 BOMなしとした。
その3:ファイル名の取り扱い
まず、WindowsとUNIXでパス名の「\」と「/」の違い問題がある。
また、日本語文字列を使いファイル名を作成しようとした場合、許可される文字列がどの範囲かという判定が必要になったりする。
クロスプラットフォームで確実に動作させることを考えた場合は、いわゆるASCII文字だけでファイル名を構成した方が無難である。
その4:ParsedHtmlは使えない
Invoke-WebRequestで取得したWebページをParsedHtmlで解析して使用する、ということが出来るのは、Windows上でInternetExplorerコンポーネントを使える場合のみで、PowerShell Core環境では使えない。
このため、地道にパース処理を実装する必要がある。
その5:他のコマンド実行処理
PowerShellスクリプト内から、他のコマンドを実行するための処理として「Start-Process」というのがある。
ただ、実験してみた限りでは、Windows環境でDOSコマンドを実行する場合、Start-ProcessではPowerShellを実行した画面と同じ場所にDOSコマンドの出力内容をそのまま出力させることができなかった。(-Wait -PassThru -NoNewWindowをつけてもダメだった)
Windows環境の場合、PowerShell内から「cmd /c」を利用してDOSコマンドを実行した場合はPowerShellを実行した画面と同じ場所にDOSコマンドの出力内容を表示させることができた。
それに対して、Linux環境ではStart-Processを「-Wait -PassThru -NoNewWindow」オプション付きで実行することで通常のコマンドの出力内容をそのまま表示させることはできた。
その6:機種依存処理の条件分け
その3、その5のような機種依存処理をどのように実行するかについては「[Environment]::OSVersion.Platform」を利用した。
どのような文字列が取得できるかという点については「PlatformID Enum」にあるように「MacOSX」「Unix」「Win32NT」の3種類(他にもあるけど過去のモノなので無視)
MacOSXとUnixの処理はだいたい似たようにできるので、「Win32NT」の場合を検出した方がよさそうだったので、下記の様な処理を書いた。
if([Environment]::OSVersion.Platform -eq "Win32NT"){
cmd /c $streamlinkcmd $streamtypes $liveurl $quolity $streamlinkoption $streamlinkfilename
}else{
Start-Process -FilePath $streamlinkcmd -ArgumentList $streamtypes,$liveurl,$quolity,$streamlinkoption,$streamlinkfilename -Wait -PassThru -NoNewWindow
}