ClickOnceインストーラー作るのに結構苦戦したのでメモ。使った環境はVisual Studio 2010 Pro + XNA Game Studio 4.0だけど新しめのVSだったら大体同じはず。
XNA使ってゲームを作ったのだけど、ランタイムのインストール難易度が高かったのでClickOnce使ってインストールできるようにしたかったのがそもそものきっかけ。
まず特に何も設定をいじらずにプロジェクトのプロパティの発行タブから発行をやったら、自作スクリプトのコードがインストーラーのパッケージに含まれなかった。そこでコンテンツとしてスクリプトフォルダを入れて、各スクリプトファイルのプロパティを「ビルドアクション なし」「出力ディレクトリに 新しい場合はコピーする」に設定してビルドしたらちゃんとContentsディレクトリ内にスクリプトが入って、発行をやっても問題なくできた。

そこで次の問題が浮上。XNA標準だとXBoxのコントローラー(それも使いにくい公式ドライバ)だけしか対応していなかったので、SlimDXというライブラリを通じてDirectInputを使用する自作ライブラリを作ってそれを参照設定に入れてゲームで使っていたのだが、インストールするとSlimDX関係でよく分からないエラーが出る。使っていたSlimDXはMarch 2011版で、既にClickOnceに公式で対応していたはずなのだがその説明通りにやってもうまくいかない。なのでその説明に逆らって以下のようにした。
まずゲーム本体の参照設定にSlimDXを登録する。そのプロパティで「ローカルコピー」がFalseになっているのをTrueに変更。プロジェクトのプロパティの発行タブにある「アプリケーションファイル」にSlimDX.dllが「含む(自動)」になっているのを確認して発行。

これでめでたくインストーラーが動くようになった。が、またまた別の問題。マニュアルやコンフィグツールなど、ゲーム本体と直接は関係がないファイルをインストーラーに忍び込ませる方法が分からなかった。これはソリューションエクスプローラでプロジェクトのファイルとして、忍び込ませるファイルを追加して、そのファイルのプロパティを「ビルドアクション コンテンツ」「出力ディレクトリに 新しい場合はコピーする」と設定すればOK。後から考えればスクリプトもこの方法で構わなかった。

だがまだこれでは終わらない。ClickOnceでインストールされたアプリケーションは普通に探しただけではインストールされたディレクトリが分からないようになっている(実際インストールされているディレクトリ名はカオスなので人が開くことを想定していなさそう)ため、せっかく忍び込ませたファイルが見つからない。そこでランチャを作って必要なものを開けるようにした。
だがClickOnceインストーラでは本体のアプリケーションへのショートカット(普通のショートカットファイルとは別物みたいだが)を作ることしかできなかった。そのためランチャを本体のアプリケーションとして発行しようとしたが、ゲーム本体をファイルに追加するときにカオスったので断念。なので仕方なく、ゲーム本体のアプリケーションを起動すると最初にランチャが開いてそのままゲーム本体を開始するか、マニュアルを開くか、などと選べるようにした。
最初はランチャをゲーム本体に組み込もうと思ったので、本体のプロジェクトにFormを追加してプログラム起動時にそれが開くようにしてみたのだがメッセージ処理関係で何か駄目なようでうまくいかない。そういうわけで、ゲーム本体のアプリケーションを起動→ゲームウィンドウが開く前に別個のランチャアプリケーション起動→ランチャアプリケーションの戻り値を使ってゲーム起動ボタンが押されたか判断してゲームのウィンドウを生成、ゲーム開始、という流れに。

以上でやりたかったことは全部解決したのだけど、インストールされたディレクトリが分かりにくい&カオス、という仕様があるからプレイヤーがセーブデータをバックアップするときとか困るだろうなぁ。

あとこの成果としての制作物は以下(本末転倒)。
【作ってみた】ほむほむシューティング ‐ ニコニコ動画(原宿)