LoginSignup
2
2

More than 3 years have passed since last update.

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

Posted at

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

...という事で、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; //バージョン取得に必要

private void Form1_Load(object sender, EventArgs e)
{
    //バージョン情報取得&表示
    //(後に、ちゃんとバージョンアップされたかの確認用)
    FileVersionInfo ver = 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

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

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

呼び元アプリケーション側コード
//ターゲットアプリ起動
string app = 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さんのページ
...を参考にさせて頂きました。多謝!

2
2
0

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