.NET TIPS

ClickOnceアプリの起動時にパラメータを渡すには?[2.0のみ、C#、VB]

デジタルアドバンテージ 一色 政彦
2006/10/20

 主にコンソール・アプリケーションなどでは、その起動時にコマンドライン経由でパラメータやオプションを指定することがあるが、ClickOnceアプリケーション(以降、ClickOnceアプリ)ではこれと同じような機能をWebページ上のハイパーリンク(=<a>タグのhref属性の内容)経由で実現できる。ClickOnceではこの機能を「URLパラメータ」と呼んでいる。

 ただし、このURLパラメータの利用にはいろいろと制限があるので、注意が必要だ。

 例えば、このURLパラメータは、Webページ上のハイパーリンクを利用しているため、ClickOnceアプリがオンライン・モード(=ネットワーク上から起動するモード)の場合には常にURLパラメータを渡せるのだが、オンライン/オフライン・モード(=ローカル環境へインストールするモード)の場合にはハイパーリンクから起動した場合でしか渡すことができないのだ。

 つまり、オンライン/オフライン・モードを採用した場合、初回インストール時には必ずWebページ上からハイパーリンクをクリックしてインストールさせる必要があり、2回目以降の起動で[スタート]メニューにあるショートカットが利用されるのに備えて、初回起動時に取得したURLパラメータを保存しておくなど、何らかの工夫をする必要がある(なお、この保存先はどこでもよいが、例えば、分離ストレージやアプリケーション構成ファイル、ClickOnceデータ・ディレクトリ上に作成したファイルなどが考えられる)。

 また、通常の配置マニフェスト(.applicationファイル)ではなくsetup.exe経由でClickOnceが起動された場合にも、このURLパラメータは利用できない。これはオンライン/オフライン・モードのみならず、オンライン・モードの場合にも発生する問題である。

 setup.exeは、必須コンポーネントをインストールするためのもので、必須コンポーネントのインストール後、配置マニフェストをURLパラメータなしで呼び出してしまう。従って、必須コンポーネントがインストールされていない環境の場合、(最初にsetup.exeが実行されることになるので)問題となる。なお、Visual Studio 2005(以降、VS 2005)はClickOnceアプリ・インストール用のHTMLファイル(publish.htm)を生成してくれるが、必須コンポーネントがインストールされていない環境でこのHTMLファイルが表示されると、(JavaScriptにより)ハイパーリンク先が自動的に(配置マニフェストから)setup.exeに切り替わることに注意してほしい。

 それでは以下でURLパラメータの具体的な実装方法を紹介していこう。

URLパラメータの有効化

 URLパラメータはデフォルトでは利用不可になっている。これを有効化するには、ClickOnce配置の発行オプションの設定で、[URL パラメータをアプリケーションに渡すことを許可する]チェック・ボックスにチェックを入れる必要がある。この設定方法については、「ClickOnceの真実 第3回 Visual Studio 2005でClickOnceを極めよう」を参考にしてほしい。

URLパラメータの設定

 URLパラメータの設定は、直接ハイパーリンクの内容を書き換えて行う。要するに、次の例のように<a>タグのhref属性の内容を直接書き換えるわけである。

<a href="http://dapc89/WindowsApplication1/WindowsApplication1.application?username=Isshiki&message=%e3%81%93%e3%82%93%e3%81%ab%e3%81%a1%e3%81%af">
URLパラメータの設定方法
太字が書き足した部分、「%e3%81%93%e3%82%93%e3%81%ab%e3%81%a1%e3%81%af」は「こんにちは」をURLエンコードしたものである(詳細後述)。
なお、VS 2005で自動生成されるpublish.htmファイルでは、JavaScript部分のdirectLinkの部分(本稿の例では「directLink = "WindowsApplication1.application";」)にこのようなパラメータ(この例では「directLink = "WindowsApplication1.application?username=Isshiki&message=%e3%81%93%e3%82%93%e3%81%ab%e3%81%a1%e3%81%af";」)を指定すればよい。

 この例を見れば分かるように、URLパラメータの指定は、配置マニフェストへのURL(「〜.application」)の後に“?”を挟んで(基本的に)「パラメータ名=値」という構文で指定する。複数のパラメータを指定する場合には、「パラメータ名=値」という構文を“&”でつなげればよい。

 また、パラメータで指定したい文字列に日本語が含まれる場合、厳密には下記以外の文字を使う場合では、URLエンコードを施した文字列を指定する必要がある。

「a〜z」「A〜Z」「0〜9」「.」「-」「_」「(」「)」「*」「'」

 URLエンコードの方法については、「TIPS:文字列をURLエンコードするには?」を参照してほしい。

URLパラメータの取得

 ClickOnceアプリ内部で(先ほど設定した)URLパラメータを取得するには、まずClickOnceアプリが起動されたときの呼び出し元ハイパーリンクのURL(以降、起動URL)を取得する。この起動URLは、ApplicationDeploymentオブジェクト(System.Deployment.Application名前空間)のActivationUriプロパティから取得できる*1。なお、現在実行中のClickOnceアプリのApplicationDeploymentオブジェクトはApplicationDeploymentクラスの静的プロパティCurrentDeploymentから取得できる。

*1 同様の内容は、現在のアプリケーション・ドメインの起動情報に格納されている起動データからも取得可能だ。具体的には「AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData[0]」(C#の場合。VBは「AppDomain.CurrentDomain.SetupInformation.ActivationArguments.ActivationData(0)」)というコードにより取得できる。

 次に、取得した起動URLからクエリ部分(=すべてのURLパラメータ)を抽出する。これには、Uriオブジェクト(System名前空間)のQueryプロパティが利用できる。このUriオブジェクトの生成は、そのコンストラクタのパラメータに起動URLを指定してインスタンス化すればよい。

 最後にクエリ部分を各パラメータに分離してそれぞれの値を取得する。これには、Stringクラス(System名前空間)のSplitメソッドなどを駆使すればよい。Splitメソッドの利用方法については、「TIPS:Stringクラスにより文字列を文字列で分割するには?」を参考にしてほしい。

 次のサンプル・プログラムでは、以上の流れに沿ってURLパラメータを取得している例だ。

using System.Deployment.Application;
using System.Web;

public Form1()
{
  InitializeComponent();

  GetUrlParameters();
}

private void GetUrlParameters()
{
  // ClickOnceアプリの場合のときのみ以下のコードを実行
  if (ApplicationDeployment.IsNetworkDeployed == false)
  {
    return;
  }

  // 起動URLを取得
  string url =
    ApplicationDeployment.CurrentDeployment.ActivationUri.AbsoluteUri;

  // クエリ部分を抽出
  Uri myUri = new Uri(url);
  string queryString = myUri.Query;
  if (String.IsNullOrEmpty(queryString))
  {
    return;
  }

  // 各パラメータを分離して抽出
  string userName = "名無し";
  string message = "メッセージはありません";
  string[] nameValuePairs = queryString.Split('&');
  foreach (string pair in nameValuePairs)
  {
    string[] vars = pair.Split('=');
    if (vars.Length != 2)
    {
      continue;
    }
    vars[0] = vars[0].Replace("?", "");  // “?”は削る
    if (string.Compare(vars[0], "username", true) == 0)
    {
      userName = HttpUtility.UrlDecode(vars[1]);
    }
    else if (string.Compare(vars[0], "message", true) == 0)
    {
      message = HttpUtility.UrlDecode(vars[1]);
    }
  }

  // 取得した各パラメータをメッセージボックスで表示
  MessageBox.Show(userName + "さん、" + message + "。");
}
Imports System.Deployment.Application
Imports System.Web

Public Sub New()
  InitializeComponent()

  GetUrlParameters()
End Sub

Private Sub GetUrlParameters()

  ' ClickOnceアプリの場合のときのみ以下のコードを実行
  If ApplicationDeployment.IsNetworkDeployed = False Then
    Return
  End If

  ' 起動URLを取得
  Dim url As String = _
    ApplicationDeployment.CurrentDeployment.ActivationUri.AbsoluteUri

  ' クエリ部分を抽出
  Dim myUri As Uri = New Uri(url)
  Dim queryString As String = myUri.Query
  If String.IsNullOrEmpty(queryString) Then
    Return
  End If

  ' 各パラメータを分離して抽出
  Dim userName As String = "名無し"
  Dim message As String = "メッセージはありません"
  Dim nameValuePairs() As String = queryString.Split("&"c)
  For Each pair As String In nameValuePairs
    Dim vars() As String = pair.Split("="c)
    If vars.Length <> 2 Then
      Continue For
    End If
    vars(0) = vars(0).Replace("?", "")  ' “?”は削る
    If String.Compare(vars(0), "username", True) = 0 Then
      userName = HttpUtility.UrlDecode(vars(1))
    ElseIf String.Compare(vars(0), "message", True) = 0 Then
      message = HttpUtility.UrlDecode(vars(1))
    End If
  Next

  ' 取得した各パラメータをメッセージボックスで表示
  MessageBox.Show(userName & "さん、" & message & "。")
End Sub
URLパラメータを取得するサンプル・プログラム(上:C#、下:VB)

 このサンプル・プログラムでは、Windowsフォームのコンストラクタでフォームの初期化(InitializeComponentメソッド)を行った後、GetUrlParametersメソッドを呼び出している。このGetUrlParametersメソッドは、URLパラメータを取得するために本稿で用意したメソッドだ。

 GetUrlParametersメソッドの冒頭に記述されているApplicationDeploymentクラスの静的プロパティIsNetworkDeployedは、ClickOnceアプリかどうかを取得するためのものだ(falseの場合はClickOnceアプリではない)。ClickOnceアプリではない場合、メソッドの実行を中断している。

 そして先ほどの説明どおり、まず起動URLを取得している。この起動URLの取得では、前述した「URLパラメータの有効化」([URL パラメータをアプリケーションに渡すことを許可する]チェック・ボックスの設定)を忘れていると、ApplicationDeployment.CurrentDeployment.ActivationUriがnull(Nothing)になってしまい、エラーとなるので注意すること。

 次にクエリ部分を抽出し、最後に各パラメータに分離している。分離した後、最初のパラメータ名の中に、URLの構文で使用した“?”が含まれてしまうので、StringクラスのReplaceメソッドを使って“?”を削除している。さらに、HttpUtilityクラス(System.Web名前空間)の静的メソッドUrlDecodeを使って、URLエンコードされた文字列をデコードして元に戻している。

サンプル・プログラムの実行結果

 以上のサンプル・プログラムを実行したのが、次の画面である。

サンプル・プログラムの実行結果

 このようにURLパラメータを活用することで、ClickOnceアプリの実行時にパラメータを設定することができる。End of Article

利用可能バージョン:.NET Framework 2.0のみ
カテゴリ:Windowsフォーム 処理対象:ClickOnce
使用ライブラリ:ApplicationDeploymentクラス(System.Deployment.Application名前空間)
使用ライブラリ:Uriクラス(System名前空間)
使用ライブラリ:Stringクラス(System名前空間)
使用ライブラリ:HttpUtilityクラス(System.Web名前空間)
関連TIPS:文字列をURLエンコードするには?
関連TIPS:Stringクラスにより文字列を文字列で分割するには?

この記事と関連性の高い別の.NET TIPS
ClickOnceアプリケーションをデバッグするには?
ClickOnceデータ・ディレクトリのパスを取得するには?
ClickOnceアプリのディレクトリ・パスを取得するには?
相対URLを絶対URLに変換するには?
ClickOnceのログ・ファイルを特定の場所に作成するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間