かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

もうすぐリリースされる(はずの) MSIX の Modification Package を試してみよう

MSIX が発表されて久しいですが、Windows 10 October 2018 Update でついにリリースされると思われます。 現状も Insider Preview の Windows 10 を入れると MSIX Packaging Tool (Preview) をストアから入れて試すことが出来ます。

普通に MSIX Packaging Tool (Preview) を使ってアプリのパッケージを作るのは Desktop App Converter を使ってアプリをパッケージングするのと似たような感じです。ちょっと違うのはサイレントインストールのインストーラーじゃなくてもよくなってる点です。xcopy によるインストールにも対応しています。

さらに、今回試してみる Modification package というものを使うとメインのアプリの差分を別の msix としてパッケージングすることが出来ます。何に使えるのかというと、よくありがちなのがパッケージソフトだけど、実はお客さんごとに設定やらなんやらをカスタマイズしたインストーラーを個別に作って提供するというパターンです。 msix の Modification package を使うとアプリのコアとなる本体部分と、お客さんごとのカスタマイズ部分を個別にパッケージングしてお客さん先では、2つの msix をインストールすると 1 つのアプリとして振る舞うみたいなことが出来ます。

msix は別々にインストール出来るので、お客さん固有のものが入った msix だけアップデートとかアプリ本体だけアップデートとかをする場合は、該当する方の msix の更新版をインストールして完了です。

ちょっとやってみましょう。

メインのアプリの作成

とりあえず、HKEY_LOCAL_MACHINE の下あたりから設定値を読み取って表示するだけのアプリを作ってみました。

XAML がこんな感じで

<Window x:Class="MsixDemoApp.MainWindow"
        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:MsixDemoApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <StackPanel Margin="10">
        <Button Content="Reload"
                Click="ReloadButton_Click" />
        <TextBlock x:Name="brandTextBlock" 
                   HorizontalAlignment="Center"
                   FontSize="64" />
    </StackPanel>
</Window>

C# がこんな感じです。

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MsixDemoApp
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void ReloadButton_Click(object sender, RoutedEventArgs e)
        {
            var registoryKeyName = @"SOFTWARE\MsixDemoApp";
            using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
            using (var key = hklm.OpenSubKey(registoryKeyName))
            {
                brandTextBlock.Text = key?.GetValue("BrandText") as string ?? "Not found";
            }
        }
    }
}

何も設定値がない状態で起動してボタンを押すと以下のような感じになります。

f:id:okazuki:20180927174429p:plain

以下のようなレジストリを追加して実行すると

f:id:okazuki:20180927174657p:plain

ちゃんと表示されます

f:id:okazuki:20180927174737p:plain

動作確認が終わったらレジストリーの値は消しておきます。

メインアプリのパッケージング

ここまで出来たら MSIX Packaging Tool (Preview) を起動しましょう。 Application package を選択します。

f:id:okazuki:20180927174959p:plain

次のページでインストーラーやパッケージを署名するための証明書の設定が出来ます。 今回は xcopy でインストールしてみたいと思うので証明書だけ設定しました。makecert コマンドで作ったテスト用証明書を使用しています。

f:id:okazuki:20180927175142p:plain

次の画面は仮想マシン上にインストールするか、このコンピューター上に作るかという選択になります。今回は、このコンピューター上ということで、そのまま次へ行きます。

次はアプリのバージョンは名前などを入れていきます。最後の Installation location は、この後インストール作業を行うアプリがどこにインストールされるのかというのを指定しておきます。今回は C;\Work\MsixDemoApp にコピーしようと思うので、このような感じにしました。

f:id:okazuki:20180927175542p:plain

次の画面は MSIX 用のドライバーや、これからインストール作業するときの diff を取るときにノイズを減らすための推奨事項が出てきます。本番は、とりあえず推奨事項(検索系サービスを止めたりとか)に従った方が余計なものが出来なくていいです。

次へを押すと Create new package 画面になります。ここでインストール作業を行います。 インストーラーを最初の画面で指定してたら、ここからインストーラーでの作業です。

私はC;\Work\MsixDemoApp に対して Visual Studio のプロジェクトの bin\Release の下にあるファイルをまるっとコピーしました。最後に MSIX Packaging Tool がアプリのエントリーポイントをみつけるためのヒントとしてデスクトップに exe へのショートカットを作ります。

f:id:okazuki:20180927180001p:plain

ここまで出来たら次へを押します。次の画面は、エントリーポイントや post-installation tasks とかの画面ですが、ここでは必要ないので素直に次へ行きます。

パッケージを作る画面になるので保存場所を選んで Create を押しましょう。 msix の署名に使った証明書が信頼されている場合は(オレオレ証明書を使った場合は、その証明書をコンピューターの信頼されたルート証明書機関へ入れてください)msix をダブルクリックするとインストール出来ます。

f:id:okazuki:20180927180407p:plain

動きました。レジストリーの値がないので以下のような結果になります。

f:id:okazuki:20180927180457p:plain

Modification Package の作成

では、Modification Package を作っていきます。 これは Desktop Bridge アプリの時と同じで VFS や実行時にレジストリーとマージされたりするファイルが同梱されてる感じになります。

詳細は以下のドキュメントにありますが

デスクトップ ブリッジの内側 - UWP app developer | Microsoft Docs

System32 やら Program Files やらのフォルダーや、レジストリーなどに対応しています。

では、MSIX Packaging Tool を起動して Modification Package を選択しましょう。ここでもインストーラーの設定などが出来ますが、今回は手作業でやっていきます。 とりあえず、主となるパッケージの名前と証明書を指定します。

f:id:okazuki:20180927181117p:plain

また、インストール作業をするマシンを選ぶ画面になるので今使ってるマシンにして次へ。

そして、Modification Package の名前とかを入れます。今回はレジストリーの設定だけなので Installation location は空欄です。

f:id:okazuki:20180927181257p:plain

推奨事項(検索サービスの停止やら)の画面になるので次へ

Create modification package の画面になるのでレジストリーに値を設定します。

f:id:okazuki:20180927181531p:plain

レジストリーの編集が終わったら次へ行きます。本番では各種ファイルを置いたりとか色々することになると思います。指示に従って msix の作成までいきます。msix が出来たら動作確認のため作成したレジストリーの値は消しておきます。

では、今できた Modification Package をインストールします。

f:id:okazuki:20180927181808p:plain

そして、アプリ本体のほうを起動します。左が単純に exe を起動したものです。右が msix でインストールしたものを起動したものです。

f:id:okazuki:20180927181936p:plain

実際のレジストリーには値が設定されてないので、Not found と表示されますが msix からインストールしたほうは Modification Package に含まれる変更が適用された状態で動いていることが確認できます。

因みに同じ手順でレジストリーの値を変えた Modification Package をもう一度作ってインストール(更新)をすると…

f:id:okazuki:20180927182741p:plain

ばっちり更新されました。

まとめ

msix に固めてさえしまえば、手元のテスト環境でテストした後にお客さんさきに展開すれば同じ設定がされたアプリをばらまける(本体と差分は別パッケージとして管理できる)ので、結構便利なのではと思ってます。

正式リリースが楽しみですね!