アウトオブブラウザアプリをオフラインインストール

このエントリは、Silverlight Advent Calendar 2011 への参加記事です。


さてさて、アウトオブブラウザのアプリケーションは実はオフラインでインストールが可能です。PCをどこかの部署で一括で設定してから配りたいけど、セキュリティ上ネットワークには繋がないで設定したい。とかってありますよね。たぶん。そういう時に使えます。


オフラインでインストールするにはsllauncher.exeを使います。アウトオブブラウザの実行ホストになるやつですね。


こいつをコマンドラインで動かして、引数にXAPファイル名とXAPが配置されるはずだったURLを引数に渡してやります。

  • /install:"xapFile"
    • XAPファイルのパスを指定します。
  • /origin:"xapUri"
    • XAPファイルが配置されるはずだったURLを指定します。
  • /overwrite
    • 以前にインストールされていたものを上書きします。
  • /shortcut:"desktop" or "startmenu" or "desktop+startmenu"


もうすこし、引数はいろいろ指定できるのですがインストールに限れば以上のような感じです。


ここで注意することは/originのXAPファイルが配置されるはずだったURL。Silverlightは実行時(インストール先のフォルダもやけど)にこいつを利用します。たとえば、サンドボックス権限しか無いアプリで、ネットワークアクセスするときのクロスドメイン制限とかです。なので、こいつは正確に入力しましょう。まぁ、ネットワークアクセスがない完全スタンドアロンとかだったら適当でもいけると思いますが。


さて、ここで終わったらそれで終わりなのでもう少し書きます。


上記の通りコマンドラインでインストールできるのですが、エンドユーザーにお願いしようと思った時に「コマンドラインってなによ?そんなん分からんわ!」とかって言われることないですか?まぁ、よくある話です。
そんなときはインストーラーを作ってあげましょう。Windows フォームかなんかで XAP ファイルを内包して、コマンドラインの文字列をチャチャッと組み立てて、流せば終わりです。


スクリーンショットは無いですが、コードだけ記載します。


まずはそもそもXAPファイルをどうしておくかですが、こいつはアセンブリのリソースとして埋め込んでおきましょう。そいつを実行時に添付フォルダかなんかに展開すればOKだと思います。

private string CreateTempXap() {

  //XAP ファイル名は適宜変更
  string tempFileName = Path.Combine(Path.GetTempPath(), "Sample.xap");

  using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Sample.xap"))
  using (FileStream fs = new FileStream(tempFileName, FileMode.Create, FileAccess.Write)) {
    while(true){
      int b = stream.ReadByte();
      if (b < 0) {
        break;
      }
      fs.WriteByte(Convert.ToByte(b));
    }
    fs.Close();
    stream.Close();
  }
  return tempFileName;
}


次に、sllauncher.exe の取得です。どうやら64bit環境だと Program Files(x86) に入るようなのでそっちのチェックも忘れずに。

private const string FileNameFragment = @"Microsoft Silverlight\sllauncher.exe";

private string GetSlLauncherPath() {
  string fileName = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), FileNameFragment);
  if (File.Exists(fileName)) {
    return fileName;
  }
  fileName = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), FileNameFragment);
  if (File.Exists(fileName)) {
    return fileName;
  }
  return null;
}


最後にコマンドライン引数の組み立てですね。ここでは画面上にデスクトップ、スタートメニューにショートカットを作るかのチェックボックスがある想定です。引数に最初に作ったテンプのXAPファイルへのパスを渡してやってます。

private string CreateInstallCommandArg(string xapFile) {
  StringBuilder sb = new StringBuilder();
  sb.AppendFormat("/install:\"{0}\" ", xapFile);
  sb.Append("/origin:\"http://localhost/sample.xap\" ");

  List<string> shortcuts = new List<string>();
  if (desktopCheck.Checked) {
    shortcuts.Add("desktop");
  }
  if (startMenuCheck.Checked) {
    shortcuts.Add("startmenu");
  }
  sb.AppendFormat("/shortcut:{0} ", string.Join("+", shortcuts));
  sb.Append("/overwrite");

  return sb.ToString();
}


これであとは 2 番目に取得した sllauncher.exe のパスと、最後に作ったコマンドライン引数を Process.Start に渡せば完成です。