Not only is the Internet dead, it's starting to smell really bad.:2020年12月分

2020/12/06(Sun)

[音楽][ハードウェア] E-MU 1820/0404/1616m がWindows10 19H1(1903)以降で動作しない

表題の件のせいでDTM環境にしてるマシンは1809のままにしとったんだけど、先月EOLを迎えてしまったので対策を考えんとならんのだ。 まぁWindows 8.1に戻して2023年まで延命できればワイの寿命の方が先だろうからいいんだけど、手元には1台分しかライセンス無くてな…

ちなみにE-MU製品でドライバの非互換性にぶち当たるのは前世紀以来( 過去記事参照)で一度ならずと二度もかよクソがE-MU滅びろという気分なのだが、とっくの昔にE-MUなぞ滅んでヘッドホンのブランドとして名前が残ってるだけなのである。

そもそもWindows 7正式対応の前にEOLになってしまった製品でいまさら対策済ドライバがご用意されるはずもないのだけど、新しい機材を買う予算もオペレーション覚える若さも無いのでしゃーない。

いちおうこれにはKVR Audioのフォーラムに 対策が投稿されている。要するに同じEMU10K1チップを採用したSound Blaster X-Fi Titaniumの対策済ドライバから一部のファイルを貰ってきて置き換える方法。 ちなみに単純にドライバの互換性を無視してX-Fi Titaniumのドライバを強制インストールする方法だと不足する機能があるようでダメ。

これ法的な問題つまりソフトウェア使用許諾(EULA)に違反しないか気になるところだけれど、改めてEULAを読んでみたところ

とあるのでE-MUもクリエイティブの製品ファミリだから問題ないなヨシ!

ただ中身を読んでみると置換対象のファイルが数十個にも及んでて元々存在しないファイルまでインストールするので、正直ここまでする必要あるのかちょっとよくわからんのだ。 うちの環境で試した限りだとctoss2k.sysというカーネルドライバだけ置換すりゃ音出るし、PatchMixという専用ミキサーアプリケーションも動作するっぽいのよな。 まぁすべての機能を試したわけではないので追試せなアカンのだが、そもそも久しく音楽制作なんかやっとらんのでサウンドカード代わりに音さえ出れば困らないのでな…

そんでこの対症療法のなによりの問題は、PowerShellスクリプトでSystem32以下にあるドライバを置き換えてるだけなので、DriverStoreはそのままだから何らかの事情(大型アップデートやシステムの修復あるいは再コンフィギュレーション)によってドライバの再インストールが発生するとせっかく置き換えたファイルが元に戻ってしまうのよね。 ということであまりお勧めできる方法ではないんだな。

まぁこれは頑張ってinfファイルを書き直せばいいんだが禁止事項にあるソフトウェアの改変に抵触しそうなのが微妙である、そもそもinfはソフトウェアに該当しない説もあるしinfを完全にスクラッチから書けばEULAもクソも無い気がしないでもないけどね。

そんなわけで、うちではこの対症療法をそのまま使わず

という方針で様子見すっかね。

セキュリティカタログについてはこれどう考えてもソフトウェアではないのでオレオレ署名で再作成してもEULAに抵触しようはずもない。 そもそも 以前も書いたけどセキュリティカタログ無くてもDism /Add-DriverあるいはPowerShellのAdd-WindowsDriverコマンドレット使えばSmartScreenにドライバインストールがブロックされることはないしな。

2020/12/24(Thu)

[Windows] PowerShellで生活するために - Import-Csvコマンドレット編(その3)

いまさら1年半前の記事の続きを書くのもアレだけどリハビリがてらに。

前回はImport-Csvの欠点として

ってとこまで書いた、これまで長年UNIXタッパーウェア哲学に染まってたワイとしては「標準入出力もまたファイルである」が当然なので、面食らってしまうわけだ。 まぁPowerShellの流儀において邪教であるUNIX哲学なぞ捨ててしまえいわれりゃそれまでではある。

じゃあどうするのが正しいのかというと、答えは簡単Import-Csvとは別にConvertFrom-CsvというStringを処理する専用のコマンドレットが存在するのだ。

PS C:\Users\tnozaki> "a,b,c,d`naa,bb,cc,dd`naaa,bbb,ccc,ddd" | ConvertFrom-Csv -Header col1,col2,col3,col4


col1 col2 col3 col4
---- ---- ---- ----
a    b    c    d   
aa   bb   cc   dd  
aaa  bbb  ccc  ddd

なるほどね。

でもそれだったら

Import-Csv $env:TEMP\syukujitsu.csv

というコードは

Get-Content $env:TEMP\syukujitsu.csv | ConvertFrom-Csv

と書けるわけで、なんならConvertFrom-Csvに-Pathオプションを用意すればGet-Contentも必要も無いよね。 やっぱりPowerShellっていろいろと設計が変だよなぁと感じてしまうわけだ、クソ言語ソムリエとしてはビンビン感じますね…

ちなみにコマンドレットの命名規則には「動詞 + 名詞」というルールがあり 承認されている動詞としてまとめられてる。

ここからConvertFromの持つ意味を調べると

1 種類のプライマリ入力 (コマンドレットの名詞が入力を示します) を、1 つ以上のサポートされている出力の種類に変換します。

とあり、イメージ的に「オブジェクト形式をパイプの前後で変換するフィルタ」だという事がわかる。

そんでImportの方はというと

永続的なデータ ストア (ファイルなど) に、またはインターチェンジ形式で格納されているデータから、リソースを作成します。

とあり、イメージ的には「データベースへの接続をオープンする処理」ってところだろうか。

しかしだな、面白いことにCSVと似たようなテキストフォーマットに関連して

は存在するんだけど

は存在しないのだうーんこの、やっぱりお前らImport-Csvは失敗だったと気づいてるだろ!おい!

ちょいと話脱線するけど同じテキストフォーマットのXMLのためのConvertFrom-Xmlは存在しない。 なぜならXMLには専用のSystem.XML.XMLDocument型があるので、文字列からの変換にわざわざフィルタを経由する必要が無いのだ。

PS C:\Users\tnozaki> function walk($node) {
	Write-Host $node.GetType()
	$node.ChildNodes | ForEach-Object {
		walk($_)
	}
}
walk([System.Xml.XmlDocument]"<root/>")


System.Xml.XmlDocument
System.Xml.XmlElement

文字列からキャストだけで変換できる。

つまりConvertFrom-*は専用型を持たないテキストフォーマットを汎用のPSCustomObjectにパックせなあかんから必要ってことだ。

PS C:\Users\install> "{`"foo`":`"bar`"}" | ConvertFrom-Json | ForEach-Object {
	Write-Host $_.GetType()
}


System.Management.Automation.PSCustomObject

なるほどね。

では前回サンプルで書いたImvoke-WebRequestで取得したCSVを一時ファイルに保存してからImport-Csvで読み込むというコード

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
$tmpfile = New-TemporaryFile
Invoke-WebRequest -Method Get -Uri 'https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv' -OutFile $tmpfile
Import-Csv -Encoding OEM $tmpfile | Where-Object { ([DateTime]$_.{国民の祝日・休日月日}).Year -eq 2020 } | ForEach-Object {
	Write-Host $_.{国民の祝日・休日月日}
}
Remove-Item -Force $tmpfile

を修正して、Invoke-RestMethodとConvertFrom-Csvを使って一時ファイルを使わないように書き直してみよう。

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
Invoke-RestMethod -Method Get -Uri 'https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv' | `
ConvertFrom-Csv | Where-Object { ([DateTime]$_.{国民の祝日・休日月日}).Year -eq 2020 } | ForEach-Object {
	Write-Host $_.{国民の祝日・休日月日}
}

こんなかんじ。

ところがこれやってみるとわかるけど正常に動きません。 なぜなら別記事で書いた Invoke-WebRequestの文字化け問題と同じ話で、サーバーのレスポンスヘッダのcontent-type charsetを元に文字コード変換が行われるせい。 指定がないためShift_JISのCSVがISO-8859-1と解釈されて文字化けしてしまう。

基本PowerShellで扱える文字コードはユニコードなので、Shift_JISなCSVファイルを扱うにはImport-CsvやGet-Contentに-Encoding OEMオプション与えて変換するんだけど、Invoke-RestMethodにはそんな便利機能無いのよね。

ということでkludgeだけど文字コード変換かます必要がある。

[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
$res = Invoke-RestMethod -Method Get -Uri 'https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv'
$bytes = [System.Text.Encoding]::GetEncoding('ISO-8859-1').GetBytes($res)
[System.Text.Encoding]::GetEncoding('Shift_JIS').GetString($bytes) | `
ConvertFrom-Csv | Where-Object { ([DateTime]$_.{国民の祝日・休日月日}).Year -eq 2020 } | ForEach-Object {
	Write-Host $_.{国民の祝日・休日月日}
}

うーんこれじゃCSVのサイズが巨大だったりすると性能問題が発生しちゃうよ、場合によってはメモリ足りなくなるわな。 やはり一時ファイルに保存してImport-Csvが安全ですかね…

結論、やっぱりPowerShellは捨てろ(ぉ

2020/12/25(Fri)

[Unix] Ancient Unix

The Unix Heritage SocietyThe Unix Tree、しれっと今年の4月に8~10th Unixなんて増えてるんですけお…(遅い)

うんPlan 9まで繋がるミッシングリンクが補完されてしまったので人類は滅亡する。