Click Onceアプリケーションにコマンドラインから引数を渡す

Visual StuidioのExpress版の発行機能を使って作成したClick Onceアプリケーションには、コマンドラインから直接引数を渡すことができません。
(通常、HTTPサーバに配備し、.applicationのURLに、URLパラメータで渡す必要があると思います。)
HTTPサーバを用意できる場合であれば、それで全く問題ありません。
ただし、種々の事情でそれが難しいケースもあると思います。
その場合に、コマンドラインでなんとか引数を渡す方法を考えてみました。

アプリ側でexeのパスを記憶する

Click Onceからアプリケーションをセットアップすると、インストール後にexeが起動されます。
ただし、exeは

C:\Users\[ユーザー名]\AppData\Local\Apps\2.0\L4AX7N83.7TE\B80T7A4X.MEW

Windows7調べ。最後の2階層は環境によって違うかも?)
の下にバージョン毎にコピーされ、静的に決定することができません。
そこで、exeが起動された際に、テキストファイル等に自分自身のexeのパスを記録しておくようにしておきます。

static class Program
...
        /// <summary>
        /// アプリケーションのメイン エントリ ポイントです。
        /// </summary>
        [STAThread]
        static void Main()
        {
            ...
            WriteExePathToStartupConfig();
            ...
        }

        /// <summary>
        /// EXEパスを設定ファイルに書き込みます。
        /// </summary>
        private static void WriteExePathToStartupConfig()
        {
            using (StreamWriter writer = new StreamWriter(@"C:\MyApp\startup.txt", false, Encoding.GetEncoding(932)))
            {
                writer.Write(Assembly.GetEntryAssembly().Location);
            }
        }
...
}

すると、C:\MyApp\startup.txtには次のような文字列が残ります。

C:\Users\jfuruya\AppData\Local\Apps\2.0\L4AX7N83.7TE\B80T7A4X.MEW\myap..tion_bb87480e67debe12_0001.0000_9a89019a5cc6f2c5\MyApp.exe

こういった要件では、アプリは引数なしでは動作できないと思われますので、引数が渡されなかった場合は、exeのパスの記録だけ行って終了するなどの動作にすれば、ユーザには、アプリのインストールがされただけのように見えます。

上記の情報を利用した起動プログラムを用意する

上記のexeのパスの情報を利用し、アプリの起動を行うプログラムを用意します。
呼び出し側は、このプログラムに引数を渡して起動します。
下記は、vbsを利用した例です。

Set arg = WScript.Arguments
If arg.Count < 2 Then
	MsgBox("プログラムの呼び出し方法が正しくありません。")
	WScript.Quit
End If

company_code = arg(0)
emp_id = arg(1)

Set fso = CreateObject("Scripting.FileSystemObject")
Set file = fso.OpenTextFile("C:\MyApp\startup.txt")

exe_path = file.ReadAll

file.Close
Set file = Nothing
Set fso = Nothing

command_line = """" & exe_path & """ " & company_code & " " & emp_id

Set shell = CreateObject("WScript.Shell")

shell.Run command_line

Set shell = Nothing

こうすれば、HTTPサーバに配備されていないClick Onceアプリケーションでも、アップグレード時などにexeのパスが最新になりますので、常に最新のexeパスでアプリを起動することができます。

トリッキーな方法にはなるので、呼び出しそのものだけを考えると、クラスライブラリとして作成し、外部から呼び出す方がすっきりしているかもしれません。
それと、[コントロールパネル] -> [プログラムと機能]からアプリをロールバックされた場合、exeのパスは戻らないので、スタートメニューから手動で1回アプリを起動する必要があると思います。