@ledsun blog

Hのキーがhellで、Sのキーがslaveだ、と彼は思った。そしてYのキーがyouだ。

WiXの値の共通化方法がわからない

ComponentGroupを使う時につぎのようにSource属性に同じ値を何度か書きました。

<ComponentGroup Id='Processors' Directory="Processors"  Source="..\Project\bin\Release">
  <Component Id="CMP__main.exe" Guid="{xxxx}">
    <File Id="File__main.exe" Name="main.exe" />
  </Component>
</ComponentGroup>

<ComponentGroup Id='Processors' Directory="Processors"  Source="..\Project\bin\Release\etc\">
  <Component Id="CMP__hoge.txt" Guid="{xxxx}">
    <File Id="File__hoge.txt" Name="hoge.txt" />
  </Component>
</ComponentGroup>

これをSource="[SourceDir]\etc\"みたいに書きたいです。 Property要素を使うのかな?と思ったのですが・・・。

の、Chapetr 3. Putting Properties and AppSearch to Work によると、読み取れる要素が決まっているようです。 ComponentGroupでは使えませんでした。

Orca.exeをつかってmsiファイルの中身の見る

Orcaとは?

orcamsiファイルの中身のみたり編集したりするためのツールです。

例えば次のようにPowerShellインストーラーに含まれるファイルの一覧が参照できます。

f:id:ledsun:20211129185514p:plain
PowerShellインストーラーに含まれるファイル

これが何の役に立つのかわかりませんが、既存のインストーラーを真似て模造品を作るときには便利です。

インストール方法

Orcaの入手法 - .NET Tips (VB.NET,C#...) を参考にしてインストールしました。 記載されている手順のなかでWindwods 10 SDKを選択しました。

f:id:ledsun:20211129190015p:plain
Windows 10 SDKの中のMSI Toolsだけをインストール

これ、驚くべき事にインストーラーがインストールされるんです。髙階インストーラーです。

C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x86にインストールされました。

f:id:ledsun:20211129190329p:plain
Orcaインストーラーがインストールされました。

Orca-x86_en-us.msiを実行してOrcaをインストールします。

WiXのComponentGroupを使う

ComponentGroupの効果

WiXでは次のようにDirectory要素の下に、インストールするコンポーネントを列挙します。 GUIDは、適当に省略してあります。

<Directory Id='TARGETDIR' Name='SourceDir'>
  <Directory Id='ProgramFilesFolder' Name='_'>
    <Directory Id='Hoge' Name='Hoge' FileSource="src\">
      <Component Id="CMP__main.exe" Guid="{xxx}">
        <File Id="File__main.exe" Name="main.exe" />
      </Component>
      <Component Id="CMP__lib.dll" Guid="{xxx}">
        <File Id="File__lib.dll" Name="lib.exe" />
      </Component>
    </Directory>
  </Directory>
</Directory>

定義したコンポーネントは次のように、一つ一つFeatureに登録します。

<Feature Id='Complete' Level='1' >
  <ComponentRef Id='CMP__main.exe' />
  <ComponentRef Id='CMP__lib.dll' />
</Feature>

これがめんどうです。 2つなら良いのですが、10ファイルあるととてもダルいです。

ComponentGroupを使うとコンポーネントをグループ化出来ます。 次のようにFeatureに1つのコンポーネントグループを登録すれば良くなります。 インストールするファイルが増えてもFeatureを変更しなくてよくなります。

<Feature Id='Complete' Level='1' >
  <ComponentGroupRef Id='Hoge' />
</Feature>

ComponentGroupの定義

ComponentGroupはPackage直下に定義します。 Componentの定義もDirectory配下からComponentGroup配下に移動します。

<Directory Id='TARGETDIR' Name='SourceDir'>
  <Directory Id='ProgramFilesFolder' Name='_'>
    <Directory Id='Hoge' Name='Hoge'>
    </Directory>
  </Directory>
</Directory>

<ComponentGroup Id="Hoge" Directory="Hoge" Source="src\">
  <Component Id="CMP__main.exe" Guid="{xxx}">
    <File Id="File__main.exe" Name="main.exe" />
  </Component>
  <Component Id="CMP__lib.dll" Guid="{xxx}">
    <File Id="File__lib.dll" Name="lib.exe" />
  </Component>
</CopmonentGroup>

ComponetGroupにはインストール先のDirectoryと、ファイルを参照するSourceを指定します。 このためDirectoryが異なる場合は、異なるComponentGroupを作る必要があります。

なぜかはわかりませんがDirectoryのIdとComponentGroupのIdが重複しても問題ありません。 たぶん、MSIデータベースのDirectoryテーブルとComponentGroupテーブルのIDカラムがそれぞれユニークであれば問題無いのだと思います。 HTMLの感覚でいると面食らいます。

とんでもスキルで異世界放浪メシ 8

アースドラゴンを捌いてもらうためにドランの街までギルドマスターを訪ねた主人公、ギルド秘蔵のミスリルナイフでもドラゴンの皮には刃が立ちませんでした。 ここからドラゴンの皮を切れるナイフまたはその素材を探すかと思いきや・・・?

ダンジョンの近くの街で今までに無い貴重な物が欲しい、「金の羊毛」パターンにしてくださいといわんばかりの舞台設定です。 それでも、かたくなに「難題に直面した平凡な奴」パターンを貫きます。 これが8巻まで来てもスローライフを続けて居られる秘訣なのでしょうか?

f:id:ledsun:20211128102124p:plain
涙のギルドマスター

Node.jsのスーパープログラマ達の今

僕がNode.jsを熱心に勉強していた頃に、スーパープログラマとして憧れていた人たちが、今何をやっているのか調べてみました。

github.com

Express.jsなんかを作っていたtjは、Go言語がメインに書いているようです。 OSS活動自体あまりやっていなさそうです。

github.com

Browserifyをつくっていたsubstackは、主にrustを書いているようです。 サーバーを書いていた人はGo言語に、CLIを書いていた人がrustに行くのかもしれません。

github.com

Babelを書いていたsebmckもrustです。

github.com

Rad VaggはGo言語とPythonのようです。

github.com

tjfontaineはOSS活動がほとんど無くなっています。

ここからはNode.jsを去っていない人たちです。

github.com

Guillermo は Vercelをやっています。

github.com

Matteo は fastifyという、今一番イケている感じのNode.jsのWebアプリケーションフレームワークを作っているようです。

WiXにはMediaTemplate要素がある

wix-tutorial-ja.github.io

<Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt='CD-ROM 1枚目' />

では、Media要素を使う例が紹介されています。

では、MediaTemplate要素が紹介されていました。 次のように、Id属性とCabinet属性が省略可能なため、ちょっとだけ短く書けます。

<MediaTemplate EmbedCab='yes' />

ちなみにWiXチュートリアルの英語版でもMedia要素を使っています。

WSLにPostgresSQLをインストールした

結局、PostgreSQLにログインユーザと同名のロールを追加しました。

経緯としては、PostgreSQLを使っているRailsアプリケーションが動かしたかったです。

ledsun@MSI:~/pubannotation►bin/rails db:create
could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
Couldn't create 'pubannotation' database. Please check your configuration.
rails aborted!
PG::ConnectionBad: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
bin/rails:4:in `<main>'
Tasks: TOP => db:create
(See full trace by running task with --trace)

こんな感じで、そもそもPostgreSQLをインストールしていないことに気がつきました。 How To Install PostgreSQL on Ubuntu 20.04 [Quickstart] | DigitalOcean を参考にし

sudo apt update && sudo apt upgrade
sudo apt install postgresql postgresql-contrib

それからPostgreSQLを起動します。

ledsun@MSI:~/pubannotation►sudo -i -u postgres
postgres@MSI:~$  /etc/init.d/postgresql start
 * Starting PostgreSQL 12 database server

それでもう一度DBを作ろうとすると

ledsun@MSI:~/pubannotation[1]►bin/rails db:create
FATAL:  Peer authentication failed for user "postgres"
Couldn't create 'pubannotation' database. Please check your configuration.
rails aborted!
PG::ConnectionBad: FATAL:  Peer authentication failed for user "postgres"
bin/rails:4:in `<main>'
Tasks: TOP => db:create
(See full trace by running task with --trace)

RailsでPostgresを使おうとしてはまった|TechRacho by BPS株式会社

結論としてはPeer認証が有効になっていたのが原因でした。 Peer認証が有効になっている場合は、ユーザ名とUnixユーザ名が一致している必要があります。

database.ymlにユーザー指定がなかったので、ログインユーザと同じロールを作ることにしました。

ledsun@MSI:~/pubannotation[1]►sudo -i -u postgres
postgres@MSI:~$ createuser -s ledsun

/etc/postgresql/12/main/pg_hba.conf を編集します。

postgres@MSI:~$ vi /etc/postgresql/12/main/pg_hba.conf

次のようにすべてのローカルユーザーをPeer認証にします。

# Database administrative login by Unix domain socket
local   all             postgres                                peer

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
local   all             all                                     peer

再起動します。

postgres@MSI:~$  /etc/init.d/postgresql restart
 * Restarting PostgreSQL 12 database server

DBの作成に成功しました。

ledsun@MSI:~/pubannotation[1]►bin/rails db:create
Database 'pubannotation' already exists
Created database 'pubannotation_test'

参考

WSLでsystemctlが動かない

Elasticsearchを動かそうとしました。 Ubuntu 20.04にElasticsearchをインストールする方法 - Tutorial Crawler に従って、インストールは上手く行って、起動しようとしたところで次のエラーが起きました。

ledsun@MSI:~/pubannotation►sudo /bin/systemctl start elasticsearch
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

qiita.com

なにやら結構大変そうなので、今回は適用をパスしました。 結局、WSL上に環境を作ること自体諦めて、古いMacに残っている環境を使ってしのぎました。

望まぬ不死の冒険者 8

主人公の故郷への旅立ちの準備を進めつつ、主人公を最初に助けてくれた冒険者に再会したり、謎の少女の影を見たり。 全体のストーリーのパターンが「魔法のランプ」なのか「金の羊毛」なのか判断に迷っていたのですが、 「白銀級冒険者」を目指す「金の羊毛」パターンに思えてきました。

f:id:ledsun:20211126214131p:plain
主人公の奇行にめまいを覚える鍛冶屋

HTMLのbutton要素のdisabledスタイル

button要素のdisabeledスタイルがある気がするのに、時々消えるなーと思ったので、確認してみました。

See the Pen button style also overwrite disabled style by shigeru.nakajima (@ledsun) on CodePen.

デフォルトではdisabeledスタイルがあります。 スタイルを当てると無くなります。 スタイルを当てたときは:disabledにもスタイルを追加するのが良さそうです。

怪獣8号 4

これまでに無く積極的に、主人公の所属する防衛隊の基地に攻撃を仕掛ける怪獣の一団。隊員達は凌げるのか?

ストーリーは「家の中のモンスター」パターン。 基地の中で、主人公の力を使えば怪獣である正体が、周りの隊員達にばれてしまう。 持っている力を振るえない主人公のジレンマが、スパイスとして加わっています。

漫画は、映画より断然尺が長いので、ストーリー全体のパターンと、エピソードのパターンを二重に持っていると考えています。 エピソードのパターンは「家の中のモンスター」です。 ストーリー全体のパターンは「魔法のランプ」だと予想しています。 「魔法のランプ」パターンだと、お話の最後には魔法の力を返さないといけません。 でも、ここまでの話の流れから、この怪獣の力返せます?うーん、謎です。

この先どうなるんでしょうね?楽しみです。

f:id:ledsun:20211124224609p:plain
猫ちゃんスタビライザー

2巻でこんなん使ってなかったやん!?と思いつつ、そんなことどうでも良いくらい良いですよね。猫ちゃんスタビライザー。 ただ、立っているだけでなくで、体を寄せて支えにいっているところがいいですよね。 ここにもバディぶっ込んでくるらしいですよ。主人公の入る隙間、残っているんですか?

高2病のことはわすれて

ツイッターで次の画像を見つけました。

twitter.com

元ネタはFacebookで流行った次の画像のようです。

f:id:ledsun:20211124094955j:plain
If you knew me in high school, what's something that I was known for?

高校時代の私を知っている人は、私が有名だったことは何ですか?

https://www.facebook.com/MMBUTTERFLYJEWELRY/photos/if-you-knew-me-in-high-school-whats-something-that-i-was-known-forqotd-march-que/641597733054541/:url

WiXでWSLポートフォワード設定するインストーラーを作る

WSL向けのWindowsポートフォワード設定をスクリプト化する - @ledsun blog にて、WSLポートフォワード設定をするバッチファイルが出来ました。 WiXの練習用にこのバッチファイルのインストーラーを作ってみました。

ソースコードです。

gist.github.com

書いていていくつか面白い、あるいは腑に落ちない現象に出会ったので、メモを残します。

アドバタイズされたショートカット

Windowsインストーラーでは「アドバタイズされたショートカット」という仕様が存在します。

[msi]アドバタイズ機能

Windows Installer にはアプリケーションを実際にインストールせずに利用可能な状態にするアドバタイズ機能がある。アドバタイズ機能は、あらかじめユーザーによる実行やアプリによるロードなどを行えるようにするインターフェース部分だけを用意しておき、オンデマンドインストールで説明されているように必要になった時に必要なコンポーネントをインストールする仕組みである。」

説明を読んだかんじ、遅延インストールする機能のようです。 この機能と「管理者として実行」に何の関連があるのかわかりませんが、「アドバタイズされたショートカット」これでバッチファイルへのショートカットを作ると、コンテキストメニューに「管理者として実行」が出てきません。

f:id:ledsun:20211124101539p:plain
コンテキストメニューに「管理社として実行」が表示されない

今回のポートフォワード設定は「管理者として実行」したいので、アドバタイズされていないショートカットを作ります。

アドバタイズショートカットではなく、普通のショートカットを作成する - .NET Tips (VB.NET,C#...)

一番簡単な方法は、DISABLEADVTSHORTCUTS Propertyを設定することでしょう。これにより、アドバタイズショートカットが作成されなくなります。

次のように、オプションをつけてインストールすると「アドバタイズされたショートカット」でなくすることができます。

msiexec.exe /i port-forward.msi /lv hoge.log DISABLEADVTSHORTCUTS=1

オプションなしで「アドバタイズされたショートカット」でなくすることもできます。 しかし、なぜかレジストリキーの登録が必要になります。

<Component Id='PortForwardOff' Guid='{7E167F5E-36E4-4130-9464-FB55D895D07F}'>
  <File Id='OFF'
           Name='port-forward-off.bat' DiskId='1'
           Source='port-forward-off.bat' >
    <Shortcut Id="startmenuoff" Directory="DesktopFolder"
                     Name=""WSLポートフォワード設定 OFF" WorkingDirectory='INSTALLDIR'
                     Advertise="yes" />
  </File>
</Component>

を、次のようにする必要があります。

<Component Id='PortForwardOff' Guid='{7E167F5E-36E4-4130-9464-FB55D895D07F}'>
  <File Id='OFF'
           Name='port-forward-off.bat' DiskId='1'
           Source='port-forward-off.bat' >
    <Shortcut Id="startmenuoff" Directory="DesktopFolder"
                     Name=""WSLポートフォワード設定 OFF" WorkingDirectory='INSTALLDIR'
                     Advertise="no" />
  </File>
  <RegistryValue Root='HKCU'
                           Key='Software\[Manufacturer]\[ProductName]'
                           Type='string' Value='' KeyPath='yes' />
</Component>

オプションつけたときは要らなかったクセに・・・・と不思議な気持ちになります。

ちなみにこの設定でビルドすると次のような警告が出ます。

PS C:\Users\led_l\wix-play-ground\port-forward> light.exe .\port-forward.wixobj
Windows Installer XML Toolset Linker version 3.11.2.4516
Copyright (c) .NET Foundation and contributors. All rights reserved.

C:\Users\led_l\wix-play-ground\port-forward\port-forward.wxs(34) : warning LGHT1076 : ICE57: Component 'PortForwardOff' has both per-user and per-machine data with an HKCU Registry KeyPath.

wix - error LGHT0204 : ICE57: Component 'XXX' has both per-user data and a keypath that can be either per-user or per-machine - Stack Overflow

This looks like a bug in ICE57. Sadly we don't have access to the ICE57 source, so it is difficult to fix directly. There are a couple of options to work around the problem:

と、あるので、気にしなくて良いのかもしれません。

プログラムメニューからはバッチファイルへのリンクを「管理者として実行」できない

上記の設定をして「アドバタイズされていないショートカット」を作っても、プログラムメニューのショートカットからは「管理者として実行」できません。

f:id:ledsun:20211124102616p:plain
プログラムメニューでは「管理者として実行」できない

リンク先がEXEファイルの場合は「アドバタイズされたショートカット」でも「管理者として実行」できます。 今回はバッチファイルへのリンクを作っているので、苦戦しています。

理由はわかりませんが、今回のインストーラーはデスクトップにショートカットを作ることにしました。

参考

29歳独身は異世界で自由に生きた……かった。 5

主人公の勇者は、在籍している国の王女様に呼び出されて性暴力被害に?相棒の隣国の王女様の機転で危機一髪。 「バディとの友情」パターンかな?と思ったんですが、ハーレム化によってバディの存在感が薄れてきました。 きっと「人生の節目」パターンで、いろいろなイベントにもまれつつ、主人公の成長が描かれていくのだと思います。 性描写有り。