Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9763

ClickOnceアプリを引数付きで起動したい話

$
0
0

職場で作っているアプリを、他の自社製アプリから起動させる時に引数を付けたいな~...

...という事で、ClickOnceアプリを引数を付けて起動する話ですが、
前提条件が弊社環境依存でキツ目なので、汎用性としてはイマイチかもしれません...(;^_^A

実現したいこと

  • 外部アプリから引数を付けて起動できる事
  • 新バージョンが存在する場合もバージョンアップ後に起動して引数を受け取れる事

今回の前提条件

  • .NET Frameworkのアプリ ※WinForms/4.7.2で確認
  • ClickOnce発行のアプリで、
    • 公開のインストールモードが"アプリケーションはオフラインでも利用できる"である事
    • マニフェスト"デスクトップショートカットを作成する"がON
    • 更新オプション"アプリケーションの更新プログラムを確認する"がONで、"アプリケーションの開始前に行う"を選択

※"URLパラメータをアプリケーションに渡す事を許可する"はOFFで大丈夫です。

実装

※VisualStudio2019で検証しています。

先ずは.NET FrameworkのWinFormsアプリを作成。 ※"FWWinFormsClickOnce1"としています。
Form1にListBoxを1つ配置(listBox1)、Form1のLoadイベントを下記の通り記述します。

Form1_Load
////usingは下記が必要//using System.Deployment.Application; //必要//using System.Diagnostics; //バージョン取得に必要//using System.Reflection; //バージョン取得に必要privatevoidForm1_Load(objectsender,EventArgse){//バージョン情報取得&表示//(後に、ちゃんとバージョンアップされたかの確認用)FileVersionInfover=FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);listBox1.Items.Add($"<Ver.{ver.ProductVersion}>");if(ApplicationDeployment.IsNetworkDeployed){//ClickOnceで起動した場合listBox1.Items.Add("<<< ClickOnceで起動 >>>");if(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData!=null&&AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData.Count()>0){//(第2引数以降は来ない模様)listBox1.Items.AddRange(AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData);}}else{//EXEを直接起動した場合(デバッガで動かしている時とか)listBox1.Items.Add("<<< EXEを直接起動 >>>");string[]args=Environment.GetCommandLineArgs();listBox1.Items.AddRange(args);}}

上記が実行できる事を確認("EXEを直接起動"が動いて表示されるハズ)して、アプリを公開します。

※アプリケーションのアセンブリ情報を公開するバージョンと合わせておきます。
 その他"今回の前提条件"に内容を揃えます。

公開後、公開フォルダに作成された"setup.exe"を実行してインストールします。
 →上手く行けばデスクトップにショートカット"FWWinFormsClickOnce1.appref-ms"が作成されます。

実行&検証

さて、先ずはデスクトップのショートカットで起動してみましょう。
 →バージョン情報と"ClickOnceで起動"だけが表示されているはずです。

続いて引数を付けて起動して見ましょう。
お手軽にコマンドプロンプトを開いて、ショートカットを落として引数2つを足しましょう。

コマンドプロンプト
C:\Users\xxxxx>C:\MyDesktop\FWWinFormsClickOnce1.appref-ms hoge1 hoge2

20201222_qiita_01.png

第1引数は無事に表示されました。
(もうソースのコメントには書いちゃっていますがw)
しかしAppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData には第2引数以降は入らないようです。

そこは工夫で何とかするという事で、空白を含めたい場合は呼び出し側で引数をダブルクォーテーションで括り、(ここでは扱いませんが)受け取り側で都合の良いように加工します。

コマンドプロンプト
C:\Users\xxxxx>C:\MyDesktop\FWWinFormsClickOnce1.appref-ms "hoge1 hoge2"

20201222_qiita_02.png

残るはバージョンアップ後に起動して引数を受け取れる事の確認。

アプリケーションのアセンブリ情報のバージョンを上げて、もう一度"公開"します。
(※手元の環境では公開バージョンを自動インクリメントにしています)

公開後に再度、コマンドプロンプトから以下を実行します。

コマンドプロンプト
C:\Users\xxxxx>C:\MyDesktop\FWWinFormsClickOnce1.appref-ms "hoge1 hoge2"

20201222_qiita_03.png

アプリケーションのバージョンアップと共に、無事に引数も渡せました!

最後に、呼び元のアプリケーション側のコードです。

呼び元アプリケーション側コード
//ターゲットアプリ起動stringapp=Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)+@"\FWWinFormsClickOnce1.appref-ms";if(!File.Exists(app)){//インストールされていないMessageBox.Show("アプリをインストールして下さい");return;}Process.Start(app,"\"hoge1 hoge2 hoge3!\"");

こちらは単純に、デスクトップのショートカットの存在有無でインストール判定、存在すれば引数を付けて実行します。

以上、使える前提は厳しめですが上手くハマるケースなら比較的お手軽に引数付き実行可能でした。
少しでも参考になれば幸いです!

参考サイト

ApplicationDeployment.IsNetworkDeployedについて、Kazzz's diaryさんの記事を、
スペシャルフォルダの取得方法について、DOBON.NETさんのページ
...を参考にさせて頂きました。多謝!


Viewing all articles
Browse latest Browse all 9763

Trending Articles