LoginSignup
0
0

Visual Studio Installer ProjectsでASP.NET Coreプロジェクトのインストーラーをなんとかして作る

Last updated at Posted at 2024-04-19

はじめに

Visual Studio Installer Projectsというのがある。要するにインストーラーを作れる機能である。

しかし↑にはこう書かれている。

注意
このワークフローは、ASP.NET Core アプリケーションには対応していません。Windows デスクトップ アプリケーションにのみ対応しています。

実際ASP.NET Coreプロジェクトのインストーラーをこの方法で作ってみるといろいろとおかしな事になる。インストールするとなぜか動かなかったり、さらには何もインストールしないインストーラーが作られたりする。
StackOverflowやGitHubやマイクロソフト コミュニティなどを追ったところ、同じ問題に悩む人々は見つかったが、対処法は見つからなかった。

その割にはMicrosoft公式のサンプルがあったりする。

信じがたいことに、こいつは正常に動く。

対処法

結論から言うとこの2点である。

  • 「項目の公開」のPublishProfilePathを指定する
  • .csproj.pubxmlを編集してなんとかする

対処法までの道のり

すでに動いている物があるのだから、これを見ながら問題を解決していけるはずである。

PublishProfilePathを指定した場合の現象

公式サンプルでは指定されているので、とりあえず普通にやると作られるFolderProfile.pubxmlでも指定してみる。
すると何もインストールしないインストーラーが作られてしまう。これではだめである。

というわけで、PublishProfilePathを外してみよう。

PublishProfilePathを指定しない場合の現象

一見正常なインストーラーが作成されるように見えるが、次のような現象が発生し、実際には動作しない。

  • ネイティブのライブラリが読み込まれずDllNotFoundExceptionが発生する
  • wwwrootフォルダ等が含まれていない

結局だめである。

もう一度PublishProfilePathを指定する

改めて考えると、公式サンプルではPublishProfilePathを指定していても正常なインストーラーが作られているという重要な事実がある。
すなわち、ここで指定している.pubxmlに何かあるはずである。

公式サンプルの.pubxml(↑のファイル)を自分のプロジェクトに丸ごとコピーし、これを「項目の公開」のPublishProfilePathに指定したところ、とりあえず「何もしていないインストーラーが作られる」状態からは脱却した。

ここにもサンプルの.pubxmlを貼り付けておく。

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
  <PropertyGroup>
    <Configuration>Release</Configuration>
    <Platform>Any CPU</Platform>
    <PublishDir>bin\Release\net8.0\publish\Fd_Win64</PublishDir>
    <PublishProtocol>FileSystem</PublishProtocol>
    <_TargetId>Folder</_TargetId>
    <TargetFramework>net8.0</TargetFramework>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <SelfContained>false</SelfContained>
    <PublishSingleFile>false</PublishSingleFile>
    <PublishReadyToRun>false</PublishReadyToRun>
  </PropertyGroup>
</Project>

公式サンプル内の.pubxmlに対し、普通に生成される.pubxmlはいくつか項目が多い。おそらく特定の項目があると何もインストールしないインストーラーが作られてしまうのだろう。

そして動作確認した結果はこうだ。

  • ネイティブのライブラリは正常に読み込まれる
  • wwwrootフォルダ等が含まれていない
  • Razor Pagesがいずれも表示されない

少なくとも重大な問題が一つ解決した。なお新たな問題も発生したが、これも最終的には解決した。

ちなみに、ネイティブのライブラリが読み込まれなかったのは.deps.jsonが含まれていなかったのが原因である。

wwwrootフォルダ等が含まれない問題

正確にはwwwrootフォルダの他、appsettings.jsonweb.configが含まれない。

↑を読むと、どうやらASP.NET Coreプロジェクトでは、デフォルトでビルド時に含めるファイルがいろいろと設定されているようだ。

しかし今までの様々な現象を見るに、インストーラーを作る時はこれが正常に反映されず、様々なファイルが不足してしまうようである。
つまり、これらのファイルを含める設定を自前で行えばよい。
なお、先のページにも.csprojの断片があるが、これを丸ごと.csprojに書き足すだけではだめである。
↓のようなエラーが発生する。

対策は、デフォルトでビルド時にファイルを含める機能を無効にすることである。このようになる。

<PropertyGroup>
    <EnableDefaultContentItems>false</EnableDefaultContentItems>
</PropertyGroup>

ならばいっそ、これをtrueにするだけで解決では?と思ってしまうが、残念ながらそうはいかなかった。というわけでまだ続きがある。

wwwrootが含まれない問題は↓を参考にして解消した。

最終的に↓のようになった。これを.csproj内に書き足す。

<PropertyGroup>
    <EnableDefaultContentItems>false</EnableDefaultContentItems>
</PropertyGroup>
<ItemGroup>
	<EmbeddedResource Include="wwwroot\**" CopyToOutputDirectory="PreserveNewest" />
	<Content Include="web.config" CopyToOutputDirectory="PreserveNewest" />
 
     <!--ルートディレクトリの.jsonだけ含めるようにする-->
	<Content Include="*.json" CopyToOutputDirectory="PreserveNewest" />
 
	<_ContentIncludedByDefault Include="@(Content)" />
 </ItemGroup>

Razor Pagesが含まれない問題

こちらは↓を参考にした。

↓を.csproj内に書き足す。

</ItemGroup>
	<Content Include="**\*.cshtml" ExcludeFromSingleFile="true" CopyToPublishDirectory="PreserveNewest" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes)" />
	<Content Include="**\*.razor" ExcludeFromSingleFile="true" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes)" />
	<None Remove="**\*.cshtml" />
	<None Remove="**\*.razor" />
</ItemGroup>

これでようやく正常に動作するようになった。

Microsoftの公式サンプルはなぜ動くのか

.pubxmlが予め細工されており、さらに申し訳程度のWeb APIを提供するだけのプログラムなのでwwwrootappsettings.jsonは必要ないしRazor Pagesも使っていないからである。

ASP.NET Coreプロジェクトの.exeを直接起動するとproduction環境になる

インストーラーの問題とは直接関係ないがこれも記載しておく。
これは↓の通り、意図的な仕様である。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0