.NET Coreに対応したInputManで次世代のアプリ配布方法を試す(自己完結型編)

.NET Coreで作成したWindowsアプリケーションでは、自己完結型での発行や、MSIX形式での展開など、アプリケーションの配布方法にも新しい要素が登場してきています。

弊社が提供する入力支援コンポーネント「InputManPlus for WPF(インプットマンプラス)」も先日ついに.NET Coreへの対応が完了しましたので、本ブログでも複数回に渡って.NET Core時代の新しいアプリの配布方法を試してみたいと思います。

今回紹介するのは「自己完結型」での配布方法です。

InputManとJPAddressで郵便番号検索アプリを作る

InputManとJPAddressを使用して、実際に配布する簡単な郵便番号検索アプリを作成します。あらかじめInputManとJPAddressの製品版かトライアル版のインストールを行ってください。

<検証環境>
OS:Windows 10, バージョン1909(OSビルド 18363.657)
IDE:Visual Studio 2019 Version 16.4.5
フレームワーク:.NET Core 3.1.102
InputMan for WPF:2.0J SP3
JPAddress for WPF:2.0J SP3

なお、これから作成するアプリケーションは以下で公開しております。お急ぎの方はこちらをお使いください。
App.configは含まれていませんので、適宜作成してください。

WPF(.NET Core)アプリの作成

まずはVisual Studioを起動し、WPF(.NET Core)アプリを新規作成します。プロジェクト名はAddress-search-Appとしました。

新規プロジェクトの作成

NuGetパッケージのインストール

.NET Core版のInputManPlusはNugetパッケージとして提供されます。ここが.NET Framework版との大きな違いです。製品同梱のNuGetパッケージファイルを使用する方法もありますが、インターネットに接続されている環境であれば「NuGet Gallery」から取得するのが簡単です。

プロジェクトを右クリックし、「NuGetパッケージの管理」のメニューをクリックし、「NuGet パッケージマネージャー」を開きます。

「参照」タブから以下のパッケージを検索し、インストールします。

  • GrapeCity.WPF.InputMan
  • GrapeCity.Windows.JPAddress

NuGetパッケージの取得

MainWindows.xamlをデザイナで開くと、ツールボックスにInputManとJPAddressのコントロールが自動で登録されていることがわかります。

ツールボックスへの登録

アプリのデザイン

今回作成するのは郵便番号から住所を検索するアプリです。標準コントロールのほか、InputManのマスクコントロールとテキストボックスコントロール、JPAddressの3つを使用します。

WPFのXAMLデザイナーは.NET Coreへの対応が完了しているので、.NET Framework版と同様に、ツールボックスからコントロールをドロップしてデザインができます。

XAMLデザイナーで設計

MainWindow.xamlのコードは以下のようになります。マスクコントロールでは郵便番号用の書式の設定を、またマスクコントロール、テキストボックスコントロールともに入力を促すための透かし表示テキストを設定しています。InputManならこのような痒い所に手が届く設定が簡単にできます。

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Address_Search_App"
        xmlns:im="http://schemas.grapecity.com/windows/2010/inputman" xmlns:jpaddress="http://schemas.grapecity.com/windows/2010/jpaddress" x:Class="Address_Search_App.MainWindow"
        mc:Ignorable="d"
        Title="郵便番号検索" Height="250" Width="800" Background="LightGray">
<Grid>
<Label x:Name="label1"  Content="郵便番号:" HorizontalAlignment="Left" Margin="32,50,0,0" VerticalAlignment="Top" FontSize="24" Width="128"/>
<im:GcMask x:Name="gcmask1" HorizontalAlignment="Left" Height="38" Margin="160,50,0,0" VerticalAlignment="Top" Width="280" FontSize="24" InputMethod.PreferredImeState="Off" WatermarkDisplayNull="<ここに郵便番号を入力>" WatermarkDisplayNullForeground="LightGray" FieldSet="〒\D{3}-\D{4}"/>
<Label x:Name="label2"  Content="住所:" HorizontalAlignment="Left" Margin="80,101,0,0" VerticalAlignment="Top" FontSize="24" Width="75"/>
<im:GcTextBox x:Name="gctextbox1" HorizontalAlignment="Left" Height="38" Margin="160,100,0,0" VerticalAlignment="Top" Width="570" FontSize="24"  WatermarkDisplayNull="<ここに住所を入力>" WatermarkDisplayNullForeground="LightGray"/>
<Button x:Name="button1" Content="住所検索" HorizontalAlignment="Left" Margin="450,60,0,0" VerticalAlignment="Top" FontSize="18" Width="100" Click="button1_Click"/>
<jpaddress:GcJPAddress x:Name="gcjpaddress1" HorizontalAlignment="Left" Height="45" Margin="100,0,0,0" VerticalAlignment="Top" Width="100"/>
</Grid>
</Window>

検索処理の実装

MainWindow.xaml.csで、button1のclickイベントに郵便番号から住所の検索処理を実装します。

using GrapeCity.Windows.JPAddress;
・
・
private void RegistorEventHadler()
{
button1.Click += new RoutedEventHandler(button1_Click);
}
private void button1_Click(object sender, RoutedEventArgs e)
{
IEnumerable<AddressInfo> addressInfo1 = gcjpaddress1.GetAddress(gcmask1.Value, false, ZipCodeQueryMode.GeneralZipCode);
foreach (AddressInfo val in addressInfo1)
{
gctextbox1.Text = val.Prefecture + val.City + val.Town + val.Area;
}
}

また、エンコーディングの問題に対処するために、App.xaml.csを以下のように書き換えます。

public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
base.OnStartup(e);
}
}

ライセンス情報ファイルの追加

次にプロジェクトにライセンス情報ファイルを追加します。.NET Framework版であれば、コントロールを配置すると自動的にlicenses.licxファイルが作成されますが、.NET Core版のInputManPlusの場合は手動で追加する必要があります。

プロジェクトを右クリック⇒「追加」⇒「新しい項目」の順にクリックし、licenses.licxという名前のテキストファイルを追加します。

ライセンス情報ファイルの追加

licenses.licxを開き、使用するコントロールに対応したライセンス情報を記載します。詳細は製品ヘルプ(InputManJPAddress)をご覧ください。今回はInputManのマスクコントロールとテキストボックスコントロール、JPAddressの3つを使用しますので、以下のようになります。

GrapeCity.Windows.InputMan.GcMask, GrapeCity.WPF.InputMan
GrapeCity.Windows.InputMan.GcTextBox, GrapeCity.WPF.InputMan
GrapeCity.Windows.JPAddress.GcJPAddress, GrapeCity.Windows.JPAddress

また、プロパティウィンドウから、「ビルドアクション」の項目を「埋め込みリソース」に設定してください。

ビルドアクションの設定

実行結果

実行すると以下のように郵便番号から住所が取得できます。
開発環境での実行結果

自己完結型の実行ファイルを配布する

.NET Coreではアプリケーションを配布する際に「自己完結型」として、.NET Coreのランタイムやサードパーティのライブラリなどすべての依存関係を含めた単一の実行可能ファイルを作成することができます。

この方式のメリットは、配布するファイル数が少なくて済むのはもちろん、アプリケーションの実行環境に.NET Coreのランタイムがインストールされているかどうかを意識する必要がないということです(その分ファイルサイズは大きくなりますが…)。

アプリケーション構成ファイルの追加

今回は住所の取得処理にJPAddressを使用しているので、配布先の環境でアプリを実行するには、辞書ファイルの配布が必要になります。

通常であれば、exeファイルと同じフォルダに辞書ファイルを配置すれば実行可能なのですが、今回紹介する「単一の実行可能ファイル」として配布するには注意が必要です。

単一の実行可能ファイルを実行すると、Tempフォルダに必要なファイルを展開し、そこから実行するようになります。

以下は実際に展開されたフォルダ配下です。アプリケーションはここで起動されます。

展開されたファイル

このため、配布先でexeファイルと同じフォルダに辞書ファイルを配置しただけでは辞書ファイルを参照することができません。この問題を回避するために、設定ファイルで辞書ファイルの参照先を定義する必要があります。
※ 配置モードが「自己完結」ではなく「フレームワーク依存」の場合も、単一ファイルとして配布する場合は同様に参照先の定義が必要です。

プロジェクトを右クリック⇒「追加」⇒「新しい項目」から「アプリケーション構成ファイル」を選択し、作成されたApp.configに参照先の設定を追加します。以下の例では、exeファイルと同じフォルダを参照するように定義しています。

<configuration>
<appSettings>
<add key="JPAddressDataFileDirectory" value="./" />
</appSettings>
</configuration>

実行可能ファイルの作成

自己完結型の実行ファイルを作成するには、プロジェクトを右クリック⇒「発行」をクリックします。

「公開先を選択」のダイアログが表示されるので、「プロファイルの作成」をクリックします。

公開先の選択

以下の画面が表示されるので、「構成」の横の編集ボタンをクリックします。

構成の編集

「プロファイル設定」のダイアログが表示されるので、「配置モード」を「自己完結」に変更し、「ファイル公開オプション」の「単一ファイルの作成」にチェックを入れ「保存」をクリックします。

プロファイルの設定

最後に「発行」をクリックして発行します。

発行の実行

プロファイルで指定した場所に単一の実行可能ファイル(.exe形式)が作成されます。すべての依存関係が含まれているのでファイルサイズが138MBとかなり大きいです。

自己完結型のファイルサイズ

ちなみに「配置モード」を「フレームワーク依存」にした場合のファイルサイズは以下のようになります。.NET Coreのランタイムが含まれない(サードパーティの依存関係のみが含まれる)ので約3.2MBとその差は一目瞭然です。

フレームワーク依存のファイルサイズ

配布して実行

最後に.NET Coreをインストールしていない環境にexeファイルと辞書ファイルを配布して実行してみます。

<配布先環境>
OS:Windows 8.1, バージョン6.3(OSビルド 9600)
フレームワーク:.NET Coreインストールなし

配布先環境

すべての依存関係がexeに含まれているので、.NET Coreをインストールしていない環境でも問題なく実行できました。

配布先で実行

おわりに

如何でしたでしょうか。今回紹介した実行するファイルのパスの問題は躓きやすいポイントなのでご注意ください。また、近日中にMSIXパッケージでの配布についてもご紹介させていただきたいと思いますので、よろしくお願いいたします。

\  この記事をシェアする  /