.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
MainWindows.xaml
をデザイナで開くと、ツールボックスにInputManとJPAddressのコントロールが自動で登録されていることがわかります。
アプリのデザイン
今回作成するのは郵便番号から住所を検索するアプリです。標準コントロールのほか、InputManのマスクコントロールとテキストボックスコントロール、JPAddressの3つを使用します。
WPFのXAMLデザイナーは.NET Coreへの対応が完了しているので、.NET Framework版と同様に、ツールボックスからコントロールをドロップしてデザインができます。
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
を開き、使用するコントロールに対応したライセンス情報を記載します。詳細は製品ヘルプ(InputMan/JPAddress)をご覧ください。今回は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パッケージでの配布についてもご紹介させていただきたいと思いますので、よろしくお願いいたします。