5
7

More than 5 years have passed since last update.

[C#/DesktopBridge] WPFをUWPパッケージしたときのUWPとしての動作確認のやりかた

Last updated at Posted at 2019-08-20

■やりたいこと

WPFを、DAC(Desktop App Converter)を使ってUWP(appx)パッケージにするアプリにて、appxにしたときの動作を確認したい。

■やり方

「アプリケーションパッケージプロジェクト」を使って、UWPと同じように動作する環境を作る。

■手順

appx(UWP)パッケージしたいUWPでないアプリをつくる

今回は、.NetFramework(4.7.2)のコンソールアプリを作成することにした。

下記のアプリでやっているのは、UWPパッケージしたアプリでしか動作しないUWPのAPIが動くかどうかで、UWPパッケージとして動いているかどうかを確認するということ。

Program.cs
using System;
using System.Diagnostics;

namespace ConsoleApp12
{
    class Program
    {
        static void Main(string[] args)
        {
            string path = string.Empty;
            try
            {
                // UWPアプリ
                var localDir = Windows.Storage.ApplicationData.Current.LocalFolder;
                path = localDir.Path;
            }
            catch (Exception ex)
            {
                // UWPアプリでない
                Debug.WriteLine(ex.Message);
                path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
            }
            Debug.WriteLine("target paht is : " + path);
        }
    }
}

アプリケーションパッケージプロジェクトを追加する

ソリューションに、下図のアプリケーションパッケージプロジェクトを追加する。

image.png

アプリケーションパッケージプロジェクトに対象のアプリを追加する

アプリケーションパッケージプロジェクトの中の「アプリケーション」を右クリックして「参照の追加」をク選択し、パッケージしたいプロジェクト(ここではConsoleApp12)を追加する。
image.png

ビルドして、アプリケーションパッケージプロジェクトをスタートアップPJに設定する

ソリューション全体をビルドした後、アプリケーションパッケージプロジェクトを右クリックして、「スタートアッププロジェクトに設定」をクリックし、F5を押したらこちらのPJから起動するようにする。

F5(デバッグ実行)を押す

アプリケーションパッケージプロジェクトを起動する。
これで、デバッグできる。Breakを貼れば、そこでとめることもできる。

■実行結果

WPFの場合

コンソールアプリをスタートアップにして起動した場合は、Windows.Storage.ApplicationData.Current.LocalFolderで例外発生して、catchのほうを通る。

実行結果.txt
target path is : C:\Users\masa\AppData\Local

UWP(パッケージPJから起動した)場合

パッケージPJをスタートアップにして起動した場合は、Windows.Storage.ApplicationData.Current.LocalFolderで例外発生せず、パスを取得できる。

実行結果.txt
target path is : C:\Users\masa\AppData\Local\Packages\6c840429-c91b-4fbf-9592-af26324a4a1e_erpevgh2z069r\LocalState



■気になったところ

ここまでで、一旦デバッグはできるようになった。
以下は、調べる中で気になったことや、注意すべき点をメモしておく。
(調べながらのメモなので、まとまりありません)

出力フォルダはどこか?

アプリケーションパッケージプロジェクトの設定としては、デフォで下記のようになっている。
image.png

ので、ビルドすると、下記のようなフォルダにexe一式ができた。
<ソリューションフォルダ>\<プロジェクトフォルダ>\bin\<プラットフォーム>\<コンフィグレーション>\<アプリ名フォルダ> の中。
image.png

出力フォルダは上記だが、F5を押して行う「デバッグ」で動く際は、別のフォルダに、パッケージに含まれるもの一式が出来上がって動くっぽい。
<ソリューションフォルダ>\<プロジェクトフォルダ>\bin\<プラットフォーム>\<コンフィグレーション>\AppX\ の中。
image.png
image.png

この中に、アプリのexeと、exeが参照してるdllなどが、一式入る。

(参考)パッケージの作成

いろいろ調べてると、DACはすでにマイクロソフトの推奨から外れているらしい。

現状にわか状態なので詳しくはあとで調べるとして、とりあえず下記のようにすると、パッケージを作れる様子。

- パッケージPJを右クリックして [ストア] > [アプリ パッケージの作成]を選択

ここでパッケージを作成すると、下記のようなものができる。

<プロジェクトフォルダ>\AppPackages フォルダ

その中の<PJ名>_<バージョン>_<コンフィグ>_Testフォルダに、.appxbundleまたは.msixbundleを含むインストーラー一式が出来上がる。(.cerの証明書ファイルも一緒にできてる)

<プロジェクトフォルダ>\bin\<プラットフォーム>\<コンフィグレーション> フォルダ

ここに、.appxまたは.msixができてる。

(参考)パッケージ作成時、appxとmsixのどちらができるのか?

.appxbundleができるときと、.msixbundleができるときがある。どっちができるか決める条件はなんなのか?

19/08/21 追記
⇒VS2019 v16.1.6で試してみたところ、下記っぽい。
image.png

パッケージプロジェクトの「最小バージョン」1803(10.0 ビルド17134)以前にすると、appxとappxbundleが出来上がり、1809(10.0 ビルド17763)以降にすると、msixとmsixbundleが出来上がる。
image.png

なんとなく試してみて上記だと分かったが、どこかに説明かいているのか???
MSdocs色々見たつもりだが、appxとmsixのできる条件、見つけられなかった...

19/08/21 追記その2
下記が、そういうことか??
image.png
MSDocsより引用。

(参考)注意・ハマりかけた事

アプリが参照してるdllの配置についての注意

アプリが使うdllは、パッケージPJが、参照の設定をもとに自動でアプリのexeと同じ階層に入れてくれる。試したところ、

  1. アプリの参照設定に入っていて「ローカルにコピー」がtrueになっているもの
  2. アプリが参照しているdllが、さらに参照しているdll

は、自動で入れてくれるっぽい。

但し、上の2.は、「アプリが参照しているdll」と同じフォルダに「さらに参照しているdll」が入っていないと自動で配置してくれないっぽい。
なので、dll類を、ビルド後イベントで、別のところからコピーしてきているような場合については、パッケージプロジェクトでは自動で配置してくれなかった。
(そういう時は、パッケージPJの方でもビルド後イベントでコピーなどしないといけないっぽい。未検証)

UWPのAPIを使うときの注意

やりたいことの本筋から少々れるが、この実験をやるうえで、パスを取得するためのUWPのAPI(Windows.Storage.ApplicationData.Current.LocalFolder)を使いたかったので、NugetでMicrosoft.Windows.SDK.Contractsを追加して使えるようにしようとしたが、下記のようなエラーが出た。

image.png

エラーの主語(アプリケーションは、...)が何を指しているのかあいまいで混乱したが、どうやらMicrosoft.Windows.SDK.Contractsが、Windowsの10.0.18362.0、つまり1903を必要とするので、それ(Contracts)を使っているConsoleApp12(今回作った実験用コンソールアプリ)のMinVerを下げろ、と言っている様子。
Microsoft.Windows.SDK.ContractsはNugetしてきていて、MinVerを下げることはできないので困った。

解決法としては、Microsoft.Windows.SDK.Contractsを使うのをやめて、以前の方法(こちら参照。.winmdファイルを参照するやり方)でUWPのAPIを呼ぶようにして対応した。

参考

WPF などの .NET Framework のアプリから UWP の API を呼ぶ
https://blog.okazuki.jp/entry/2018/03/29/101601

.NET のプロジェクトから WinRT API を呼ぶのが凄く簡単になってます
https://blog.okazuki.jp/entry/2019/05/09/115020

5
7
1

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
5
7