Windows Web アプリケーション ギャラリーの統合

公開日: 2009 年 3 月 18 日 (作業者: iisteam)

更新日: 2009 年 9 月 24 日 (作業者: iisteam)

概要

Windows Web アプリケーション ギャラリー (WAG) を利用すると、アプリケーション開発者は Windows プラットフォームの広範なユーザーに対してアプリケーションを公開できます。また、Web サイトの作成者は、IIS で使用できる無料のアプリケーションを簡単に見つけたり、学習、インストールすることができます。

ホスティング業者およびコントロール パネル ベンダーは、本記事を使用して、エンド ユーザーにギャラリー内のアプリケーションへのアクセスを提供できます。また、ギャラリーでは、コントロール パネルを自動的に最新に保つ動的なフィードが提供されます。Windows アプリケーション ギャラリーを既存のコントロール パネル ソリューションに統合することで、ギャラリーで入手可能なアプリケーション用のシンプルなインストール パスをエンド ユーザーに提供できます。

必須コンポーネント

WAG をコントロール パネル ソリューションに統合するには、以下のコンポーネントが必要です。

1. Web アプリケーション ギャラリー フィード

これは、拡張 Atom XML フィードであり、WAG で使用できるアプリケーションのダウンロードとインストールに必要な情報すべてが含まれています。Web Platform Installer API を使用してフィード内のコンテンツを読み込んで操作する (推奨) か、手動でダウンロードしてフィードの XML コンテンツを解析できます。 この記事では、フィードの場所および xml コンテンツについての情報を提供します。

2. Web Platform Installer API (WebPI API)

Web Platform Installer ツール(英語)は、新しい API を使用してフィードのコンテンツにアクセスします。 開発者は、この公開 API (Microsoft Web Platform Installer (英語)) を使用できます。フィードの XML を直接操作するのではなく、この API を使用してフィードのコンテンツにアクセスすることを強く推奨します。 この API で次の機能が提供されます。

  1. XML 要素の形式およびセマンティクスの詳細からの抽象化

  2. 直感的なクラスとメソッド

  3. 分類に役立つアプリケーションのリストおよびそれらのタグへのアクセス

  4. 不足しているアプリケーション依存関係の簡単な検出

3. Web 配置 API

Web Platform Installer ツールは、新しい API を使用してアプリケーション パッケージを管理します。この API についてのドキュメントは、Microsoft Web Deployment (英語) にあります。これは、開発者が使用できる公開 API です。 この API を使用することで、作成したアプリケーションでパラメーター値の読み取りと設定を行い、関連付けられたデータベースを含めてアプリケーションを対象のサーバーに展開できます。

サンプル アプリケーション

ここで提供するサンプル アプリケーションは、WebPI API を使用して WAG XML フィードへのアクセスと操作を行い、Web 配置 API を使用してアプリケーション パッケージ、そのパラメーター、および配置を管理します (サンプル アプリケーション)。 このリンクをクリックすると .zip ファイルがダウンロードされるので、ファイルを展開して ControlPanelAppRtwAPI フォルダーに移動し、その内容をプロジェクトまたはサイトにコピーできます。さらに、この .zip ファイルは、Web 配置ツール パッケージの形式なので、msdeploy ツール、またはIntMgr の [アプリケーションのインポート**] 機能を使用して、"Default Web Site" にアプリケーションを配置できます。 この .zip ファイル パッケージの形式は、Windows アプリケーション ギャラリーのすべてのアプリケーションで使用されています。

WebPI API を使用せずにフィード xml を直接操作することもできますが、フィード ファイルに加えた変更がコード内で予期しない結果を引き起こす可能性があるので、この方法は推奨されません。

このサンプル アプリケーションついてのフィードバックや質問は、「Web アプリケーション ギャラリー: 開発者とインテグレーターのフォーラム (英語)」に自由に投稿してください。 この記事の末尾に記載したその他のリソースも参照してください。

目次

環境をセットアップする

サンプル アプリケーションをセットアップする

フィードを操作する

アプリケーション リスト フィードをダウンロードする

WebPI API を使用してアプリケーション フィードを解析する

アプリケーション エントリの XML

アプリケーションのリストを XML フィードから直接読み取る

WebPI API を使用して不足している依存関係を識別する

アプリケーション/製品の依存関係を追跡する

WebPI API を使用してアプリケーションのリストをフィルター処理する

Web 配置パッケージをダウンロードする

SHA1 ハッシュを使用してパッケージを検証する

パッケージ パラメーターを処理する

アプリケーションを配置する

ユーザーにアプリケーションの場所を表示する

まとめ

リソース

環境をセットアップする

この記事で使用できるサンプル アプリケーションを用意してあります。サンプルはコントロール パネル アプリケーションで使用できるテクニックのいくつかを説明するものです。ただし、サンプル用途としてのみ提供するものであり、運用環境には展開しないようにしてください。

このサンプルには、サンプルを使用できるように環境を構成する方法についての説明書が付属しています。これらの説明書は、MS Deploy でコントロール パネル スタイルのアプリケーションを実行する際に必要となる、ユーザーおよび特権をセットアップするための全般的なガイドとして使用してください。

ステップ 1 - Web 管理サービス (WMSVC) をセットアップする

このセクションでは、WMSVC をインストールして構成します。 このサービスは、Deployment Handler をホストしてアプリケーションをインストールする場合と、サイトの所有者を認証してその Web サイトのみにインストールする場合の両方で使用されます。

  1. [スタート] メニューの [サーバー マネージャー] をクリックし、左側のツリー ビューで [役割] ノードを選択します。

  2. 下へスクロールし、[Web サーバー (IIS)] の役割を探します。

  3. [役割サービスの追加] をクリックし、[管理サービス] を選択します。

  4. IIS マネージャーを開きます。

  5. [サーバー] ノードを選択します。

  6. 下へスクロールし、[管理サービス] アイコンを探してダブルクリックします。

  7. 下の [リモート接続を有効にする] チェック ボックスをオンにします。

  8. 作業ウィンドウで [開始] をクリックして、サービスを開始します。

ステップ 2 - Web Deployment Handler をセットアップする

このセクションでは、Deployment Handler をインストールして構成します。

  1. Web 配置ツールをダウンロードしてサーバーにインストールします。 Web Platform Installer (https://www.microsoft.com/web/downloads/platform.aspx) を使用して、Web 配置ツール 1.0 をダウンロードし、インストールできます。 [最新情報] タブの [Web Platform の新しい拡張機能] セクションでこのツールを探します。

  2. インストール中に、[カスタム] または [完全] を選択します。

  3. [カスタム] を選択した場合は、[Web 管理サービス統合] コンポーネントを必ず選択するようにしてください。

  4. Deployment Handler は、規則を使用して、インストール中のアクションを実行するユーザーを認証します。 たとえば、一般的なアクションとして、データベース スクリプトの実行があります。 このアクションは、ユーザーが既に所有している低い権限のデータベース アカウントとして実行する必要があります。 アクションの中には、フォルダーをアプリケーションとしてマークするアクションなど、サイトの所有者が持つ権限よりも高い権限を必要とするものがあります。 この操作のために、このハンドラーをより高い権限のアカウントに昇格するように構成できます。 このアクションを実行するアクセス権のみを持つアカウントを 1 つ作成するようにしてください。

  5. 以下のサブステップに従うと、ユーザーは、IIS 7.0 の構成ファイルである applicationHost.config に書き込めるようになり、フォルダーをアプリケーションとしてマークできます。

    1. フォルダーをアプリケーションとしてマークするためのカスタム ユーザーを作成します。

    2. このユーザーに、%windir%\system32\inetsrv\config に対する読み取り権限を許可します。

    3. このユーザーに、%windir%\system32\inetsrv\config\applicationHost.config に対する変更権限を許可します。

  6. ユーザーが administration.config ファイルを開いて該当セクションに移動し、コンテンツ、アプリケーションおよびデータベースを配置できるように、一連の規則を追加します。

        <system.webServer>
            <management>
    
  7. サイトの所有者に、アプリケーションの作成、ACL の設定、およびデータベース データの展開を許可するには、<management> セクション内の administration.config ファイルに、次の規則を追加する必要があります。 必ず <runAs> 要素を変更して、先のステップ 5 で作成したユーザー資格情報を含めてください。 これらの規則は、MWA を使用してプログラム的に追加することができます。

  8. administration.config ファイルの <sectionGroup name="system.webServer"> 内の <sectionGroup name="management"> 要素を探し、その中に <section name="delegation" overrideModeDefault="Deny" allowDefinition="MachineToWebRoot" /> 要素が記述されていることを確認します。 記述されていない場合は、追加します。

  9. WMSVC を再開します。

 

ステップ 3 - コンテンツのリモート UNC 共有を使用している場合は、次のアクセス権を適用する

次の部分を除き、/page.aspx/194/configuring-share-and-ntfs-permissions の記事に指定されているアクセス権に従います。

パス \\server\share$ (共有) では、Domain Users に "変更" ではなく "フルコントロール" を設定します。

ステップ 4 - 共有構成を使用している場合は、次の更新プログラムを適用する

この更新プログラムは、Windows Server 2008 で共有構成が有効の場合に、WMSVC が接続を許可しない問題を解決します。

サンプル アプリケーションをセットアップする

このセクション内の情報は、本記事の「概要」セクションで言及したサンプル アプリケーションに適用されます。 このセクションでは、このサンプル コードをホストするための Web サイト、アプリケーション プール、およびカスタム ID を作成します。

環境をセットアップする

ステップ:

  1. サンプル Web サイト用に物理ディレクトリを作成します。

    md %systemdrive%\inetpub\controlpanel
    
  2. サンプルの実行とアプリケーションのインストールに使用する、新しいユーザー アカウントを作成します。 権限を昇格したコマンド プロンプトで、次のコマンドを実行します。

    net user ControlPanelAppId <PasswordHere> /add
    
  3. 次のユーザー アカウントに対してアクセスを許可します。

    icacls %systemdrive%\inetpub\controlpanel /grant ControlPanelAppId:R
    
  4. サンプルをホストするための新しい Web サイトを作成します。

  5. IIS マネージャーを開き、[Web サイト] ノードに移動します。

  6. [Web サイト] ノードを右クリックし、[Web サイトの追加] を選択します。

  7. "ControlPanel" という名前の新しい Web サイトを作成します。 このサイトを作成すると、自動的に "ControlPanel" という名前を持つ、関連付けられたアプリケーション プールが作成されます。

  8. IIS マネージャーを開き、[アプリケーション プール] ノードに移動します。

  9. [ControlPanel] アプリケーション プールを右クリックし、[詳細設定] を選択します。

  10. [プロセス モデル] ヘッダーの下で、ID の [NetworkService] をクリックします。

  11. [カスタム アカウント] に設定し、ステップ 2 で作成したユーザーのための資格情報「ControlPanelAppId」を入力します。 サンプル アプリケーション内の依存関係の確認を正しく動作させるには、該当コンピューターに対して管理者権限を持つアカウントを使用する必要があります。 これは、依存関係を確認するために、管理者のみが使用できるレジストリとディレクトリにアクセスする必要があるからです。 依存関係を確認しない場合は、依存関係の確認のコードをコメント アウトできます。

  12. サンプル アプリケーションのコンテンツを、Web サイトの作成時に選択した物理パスにコピーします。

  13. アプリケーションが完全な信頼(英語)の下で実行されていることを確認します。 完全な信頼は、アプリケーションの web.config ファイルで有効化(英語)できます。許可されていない場合、管理者がルートの web.config ファイルに完全な信頼を追加できます。

WMSVC の既定の SSL 証明書を使用する

WMSVC サービスは、既定では自己署名入り証明書をインストールします。 WMSVC 用の完全に信頼された証明書をインストールするのが理想的ですが、 テスト目的なので、この既定の証明書を使用できます。 このセクションでは、サンプル アプリケーションでこの既定の証明書を使用するために必要な手順を示します。

サンプル アプリケーションが既定の証明書と連携するように、以下のステップに従います。

  1. サンプル アプリケーションで Global.asax ファイルを開きます。

  2. Application_Start 関数を探し、次の行のコメントを解除します。

    //ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    

    上の行を下記のように変更します。

    ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
    
  3. ファイルを保存します。

ユーザーサイトを作成し、サイトの所有者を認証する

このセクションでは、サイトの所有者のために Web サイトを作成し、IIS マネージャーのリモート管理を使用した接続、およびサンプル アプリケーションを使用したアプリケーション パッケージのインストールの両方についてサイトの所有者を認証します。

  1. IIS マネージャーを開きます。

  2. [Web サイト] ノードに移動します。

  3. 「MySite」という名前の新しい Web サイトを作成するか、既に準備済みの Web サイトを使用します。

  4. 「MySiteUser」という名前の新しいサイトの所有者アカウントを作成するか、既に準備済みのアカウントを使用します。

    net user MySiteUser PasswordHere /add
    
  5. Web サイト [MySite] を選択します。

  6. [機能ビュー] で、[IIS マネージャーのアクセス許可] をダブルクリックします。

  7. [IIS マネージャーのアクセス許可] ページの [操作] ウィンドウで、[ユーザーの許可] をクリックします。

  8. [ユーザーの許可] ダイアログ ボックスで、Windows ユーザーを追加します。

  9. [選択] をクリックして [ユーザー] ダイアログ ボックスを開きます。

  10. [ユーザー] ダイアログ ボックスで、「MySiteUser」と入力してから [OK] をクリックします。

  11. [OK] をクリックして [ユーザーの許可] ダイアログ ボックスを閉じます。

詳細については、https://technet.microsoft.com/ja-jp/library/cc770968.aspx を参照してください。

アプリケーション パッケージのインストールをテストする

このセクションでは、サンプル アプリケーションをテストし、アプリケーションをインストールします。

  1. IIS マネージャーを開きます。

  2. [Web サイト] ノードに移動します。

  3. Web サイト [ControlPanel] を選択し、[操作] ウィンドウで [参照] をクリックします。

  4. インストールするアプリケーション パッケージをクリックします。

  5. 最初の 3 つのパラメーターに対して、サイト名として「MySite」 (またはパート 4 で作成したサイト)、ユーザー名に「MySiteUser」、このアカウントのパスワードを入力します。

  6. 残りのパラメーターに、アプリケーション (データベース サーバーなど) が理解できる値を入力します。

  7. [インストール] をクリックします。

フィードを操作する

ギャラリーのフィードは、拡張された Atom フィードとして提供されます。リリース バージョンは以下から入手できます。

これらは、サンプル アプリケーションの以下の操作で使用されるフィードです。

  • インストールするアプリケーションのリストを生成する。

  • パッケージのダウンロード情報を取得する。

  • 任意のアプリケーションについての依存関係の情報を取得する。

アプリケーション リスト フィードをダウンロードする

フィードを解析する前に、ローカルにダウンロードする必要があります。 このサンプル アプリケーションは、WebClient.DownloadFile メソッドを使用してフィード (前述したアプリケーション リストの URL) をダウンロードし、Path.GetTempFileName(英語) メソッドで取得される一時ファイルに保存します。これらの呼び出しは、GetXmlLocationFromFeed メソッドの中から行われます。ControlPanelAppRtwAPI\App_Code\Packges.cs ファイル内の Reload メソッドを参照してください。

WebPI API を使用してアプリケーション フィードを解析する

また、Reload メソッドの中に、Microsoft.Web.PlatformInstaller.ProductManager (英語) クラスの呼び出しが含まれています。 このクラスは、フィード内のデータ (アプリケーションおよび製品のリスト) を管理する機能を提供します。

1. ProductManager オブジェクトを初期化する

次のコードは、ProductManager オブジェクトをインスタンス化して初期化します。

ProductManager pm = new ProductManager();
string fileLocation = GetXmlLocationFromFeed(feedUrl);
pm.Load(new Uri(fileLocation));

2. 各アプリケーションのインストーラー情報を抽出する

ユーザー インターフェイスを構築するときに、Atom フィードのどのフィールドを表示するかを選択できます。最小限の機能にするアプローチは、title 要素から取り出したアプリケーション名のみを表示することです。フィードから他のメタデータを取り込んだり、アイコン、スクリーンショットなどのグラフィック要素を活用して、もっと手の込んだ UI を作成することもできます。 アプリケーションの情報を表示し、各インストール パッケージへのリンクを作成するために、サンプル アプリケーションは、各オブジェクトに対して、Microsoft.Web.PlatformInstaller.Installer (英語) オブジェクトを使用します。 Reload メソッドを参照してください。このオブジェクトに到達するための、以下のようないくつかのステップがあります。

最初に、**foreach ループ内で、Microsoft.Web.PlatformInstaller.ProductManager.Products コレクションに含まれている各 Microsoft.Web.PlatformInstaller.Product (英語) オブジェクトを検査します。必要とされるのは、アプリケーションとしてマークされているものです。

foreach (Product p in pm.Products) {
  if (!p.IsApplication) {
     continue;
  }
[...]

次に、foreach ループ内でさらに、アプリケーションのインストーラーを取得し、ユーザー インターフェイスとインストール プロセスに必要とされるオブジェクトにアクセスします。これらの中で最も重要なものは、InstallerFile.InstallerUrl.AbsoluteUri (英語) で、これにはアプリケーション用の Web 配置パッケージをダウンロードできる場所が含まれています。

[...]
Installer installer = p.GetInstaller(english);
if (installer == null) {
       if (p.Installers.Count > 0) {
         installer = p.Installers[0];
        }
        else {
           // some products are just for detection
           continue;
        }
}
// if there's no install location we'll skip as well
if (installer.InstallerFile == null) {
        continue;
}
Package package = new Package {
    ID = p.ProductId,
    Description = p.Summary,
    Title = p.Title,
    Version = p.Version,
    SartPage = installer.MSDeployPackage.StartPage ?? String.Empty,
    DownloadUrl = installer.InstallerFile.InstallerUrl.AbsoluteUri,
    DownloadHash = installer.InstallerFile.SHA1Hash
};
[...] 

 

こうして、各パッケージ オブジェクトを自分のパッケージ コレクションに追加して、ユーザー インターフェイスに表示できるようになります。

アプリケーション エントリの XML

アプリケーションは、属性が type='application' で識別されたフィード内のエントリとして表示されます。フィードのアプリケーション エントリの例は、以下のようになります。

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <webpiFile version="2.0.1.0" />
[…] 
  <!-- BlogEngine.NET ASP.NET app-->
  <entry type="application">
    <productId>BlogEngineNET</productId>
    <title resourceName="Entry_BlogEngineNET_Title">BlogEngine.NET</title>
    <version>1.5.0</version>
    <summary resourceName="Entry_BlogEngineNET_Summary">BlogEngine.NET is a fully featured, open source blogging platform written in ASP.NET.  BlogEngine.NET is easily customizable with many downloadable themes, widgets, and extensions.</summary>
    <id>https://www.microsoft.com/web/webpi/2.0/blogengine</id>
    <updated>2009-3-18T18:30:02Z</updated>
    <published>2009-03-18T18:30:02Z</published>
    <longSummary resourceName="Entry_BlogEngineNET_LongSummary">BlogEngine.NET is an open source ASP.NET blogging project that was born out of desire for a better blog platform. We focused on simplicity, ease of extendibility, and innovative features while taking advantage of the latest .NET features. BlogEngine.NET is easily customizable. We have many downloadable themes, widgets, and extensions or you could make your own with some basic .NET skills.  With BlogEngine.NET, it is easy to make your blog look and function exactly how you’d like.</longSummary>
    <link href="http://www.dotnetblogengine.net/" />
    <author>
      <name>dotnetblogengine.net</name>
      <uri>http://www.dotnetblogengine.net/</uri>
    </author>
    <images>
      <screenshot>BlogEngine200x200.jpg</screenshot>
      <icon>https://www.microsoft.com/web/media/gallery/apps-screenshots/BlogEngine200x200.jpg</icon>
    </images>
    <keywords>
      <keywordId>Blogs</keywordId>
      <keywordId>ASPNET</keywordId>
    </keywords>
    <dependency idref="ASPNETApp" />
    <installers>
      <installer>
        <id>1</id>
        <languageId>en</languageId>
        <osList idref="SupportedAppPlatforms" />
        <installerFile>
          <fileSize>1342</fileSize>
          <installerURL>https://blogengine.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=66012</installerURL>
          <trackingURL>https://go.microsoft.com/fwlink/?LinkId=146340</trackingURL>
          <sha1>C1EA7BF684D85A0CAD2EE6DE859011A61264CF2C</sha1>
        </installerFile>
        <helpLink>https://forums.iis.net/1155.aspx</helpLink>
        <msDeploy>
          <startPage />
        </msDeploy>
      </installer>
    </installers>
    <addToFeedDate>3-10-2009</addToFeedDate>
    <pageName>BlogEngine</pageName>
  </entry>
[…] 

アプリケーションのリストを XML フィードから直接読み取る

フィードから直接 XML にアクセスできますが、このアプローチは推奨されません。 アプリケーションの主要な要素にアクセスする方法の例を以下に示します。

public static void Reload() {
    lock (_packagesLock) {
        string feedUrl = ConfigurationManager.AppSettings["FeedXmlUrl"];
        if (String.IsNullOrEmpty(feedUrl)) {
            throw new InvalidOperationException("Could not find FeedXmlUrl in application settings");
        }
        // Parse the XML feed with the packages in them
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(GetXmlFromFeed(feedUrl));
        // Feed uses the Atom XML schema
        XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
        nsmgr.AddNamespace("atom", "http://www.w3.org/2005/Atom");
        _packages = new Dictionary<string, Package>();
        foreach (XmlNode app in doc.SelectNodes("//atom:entry[@type='application']", nsmgr)) {
            Package package = new Package {
                ID = GetXmlNodeText(app, nsmgr, "atom:productId"),
                Description = GetXmlNodeText(app, nsmgr, "atom:summary"),
                Title = GetXmlNodeText(app, nsmgr, "atom:title"),
                Version = GetXmlNodeText(app, nsmgr, "atom:version"),
                StartPage = GetXmlNodeText(app, nsmgr, "atom:pageName"),
                DownloadUrl = GetXmlNodeText(app, nsmgr, "atom:installers/atom:installer/atom:installerFile/atom:installerURL"),
                DownloadHash = GetXmlNodeText(app, nsmgr, "atom:installers/atom:installer/atom:installerFile/atom:sha1")
            };
            _packages.Add(package.ID, package);
        }
    }
}   

  

WebPI API を使用して不足している依存関係を識別する

サンプル アプリケーションにおける重要なステップは、アプリケーションをインストールする先のサーバーに不足しているすべての依存関係の識別です。 このサンプルはこの情報を収集し、依存関係が不足しているアプリケーション パッケージをユーザーがインストールしようとした場合に、エラーとして表示します。 この目的のために、Web.PlatformInstaller で、不足している製品のコレクションを返す Microsoft.Web.PlatformInstaller.Product.GetMissingDependencies (英語) メソッドが提供されています。 このメソッドを呼び出す前に、ProductManager のインスタンスを作成して製品リスト フィード (アプリケーション フィードではありません) で初期化する必要があります。 次のコード スニペットは、不足している依存関係を確認する方法の例です。このコードは、サンプル アプリケーションの ControlPanelAppRtwAPI\App_Code\Package.cs ファイルに含まれています。 GetMissingDependencies は、管理者のみ使用できるレジストリとディレクトリへのアクセスが必要なので、GetMissingDependencies に対するすべての操作は、コンピューターに対する管理者権限を持つユーザーのコンテキスト内で作成されたときにのみ機能します。

public string GetMissingRequirements() {
    string displayString = String.Empty;
    try {
        ProductManager pm = new ProductManager();
        // we need to load the whole product list since app will depend on products in that file
        // the "true" parameter says filter the installer set to only installers available on this
        // architecture
        pm.Load(new Uri(ConfigurationManager.AppSettings["PLFeedXmlUrl"]), true);
        Product p = pm.GetProduct(ID);
        ICollection<Product> missingProducts = p.GetMissingDependencies(null);
        if (missingProducts.Count > 0) {
            displayString = "The server is missing the following products that are required to run this app: ";
            foreach (Product missing in missingProducts) {
                displayString += " " + missing.Title + ",";
            }
            displayString = displayString.Trim(',');
        }
    }
    catch {
    }
    return displayString;
} 

コントロール パネル アプリケーションでは、インストール プロセスに進む前に、対象とするサーバーで特定のパッケージに対応する依存関係が使用可能なことを確認できる必要があります。 この機能を使用できない場合、インストールが成功した後でユーザーがアプリケーションの起動に失敗するリスクがあります。 依存関係の確認を使用できない状況下では、ホスト業者はフィード アプリケーションおよびそれらの依存関係を監視して、対象のサーバーが適切にセットアップされることを確認する必要があります。

GetMissingDependencies メソッドは、実行中のプロセスのビット数のスコープ内で依存関係を探すことに注意してください。 このメソッドは、32 ビット プロセスに対しては 32 ビットの依存関係を探し、64 ビット プロセスに対しては 64 ビットの依存関係を探します。 64 ビット コンピューター上の 32 ビット モード アプリケーション プールで実行する場合は、このことに注意する必要があります。

アプリケーション/製品の依存関係を追跡する

ソリューション内の不足している依存関係を識別するための最善のアプローチは、前のセクションで言及した WebPI API を使用することです。しかし、フィード XML を確認して各アプリケーションに必要な依存関係を識別する必要がある場合には、このセクションの情報が役立ちます。

WebApplicationList.xml フィード ファイル内の最も重要な要素は、<dependency> 要素です。 この要素には、特定のアプリケーション パッケージが正しく動作するために必要な依存関係が記述されています。

製品リスト フィードである WebProductList.xml は、ルート フィードです。 これには、製品情報 (Web Platform コンポーネント) への参照だけではなく、子フィードである WebApplicationList.xml への参照も含まれています。 WebApplicationList.xml には、アプリケーション パッケージへの参照が含まれ、さらに各アプリケーション パッケージ エントリには、WebProductList.xml で定義された製品パッケージに対する一連の依存関係の参照が含まれています。 この関係の実装方法の例を以下に示します。

  1. WebProductList.xml には、WebApplicationList.xml へのリンクが含まれています。

    <link rel="enclosure" href="http://feedserver/WebApplicationList.xml"/>

  2. WebApplicationList.xml には、<entry> 要素に含まれているアプリケーション パッケージへの参照が含まれています。 各パッケージ エントリには、依存関係のリストが含まれています。MySQL も使用する WordPress などの PHP アプリケーション用の依存関係の例を次に示します。

        <dependency>
          <and>
            <dependency idref="PHPApp" />
            <dependency idref="MySQLApp" />
          </and>
        </dependency>
    
  3. <dependency> 要素は、依存関係のリストの開始を意味します。 <and> 要素は、中に含まれるすべての依存関係がアプリケーションとって必須であることを意味します。

  4. idref="PHPApp" および idref="MySQLApp" に注目してください。これらは、対応する "id" 値を持つ実際の依存関係を定義している別の <dependency> 要素を参照しています。 たとえば、WebApplicationList.xml ファイルの PHPApp の依存関係要素を見ると、PHPApp の一連の依存関係がわかります。

    <dependency id="PHPApp">
          <and>
            <!--msdeploy-->
            <dependency>
              <productId>WDeployNoSMO</productId>
            </dependency>
            <!--php-->
            <dependency>
              <or>
                <dependency>
                  <productId>PHP</productId>
                </dependency>
                <dependency>
                  <productId>LegacyPHP</productId>
                </dependency>
              </or>
            </dependency>
            <!-- bring along IIS for PHP-->
            <dependency idref="IISForPHP" />
          </and>
        </dependency> 
    
  5. <productId> 要素には、親フィード WebProductList.xml 内の対応する製品への参照が含まれています。以下に例を示します。

    • ID "WDeployNoSMO" は SMO なしの Web 配置に対応します

    • ID "PHP" は PHP エンジン (現在 5.2.11) に対応します

  6. <or> エントリは、依存関係がどちらか一方、または両方に対応することを意味します。

  7. WebProductList.xml の製品エントリには、<discoveryHint> 要素が含まれています。この要素では、対象のコンピューターにその製品が既に存在しているかどうかを判断するために何を探す必要があるかが示されています。 たとえば、製品 ID が "MySQLConnector" の場合は次のようになります。

     <discoveryHint<
          <or<
            <discoveryHint<
              <registry<
                <keyPath<HKEY_LOCAL_MACHINE\SOFTWARE\MySQL AB\MySQL Connector/Net</keyPath<
                <valueName<Version</valueName<
                <valueValue<5.2.5</valueValue<
              </registry<
            </discoveryHint<
            <discoveryHint<
              <registry<
                <keyPath<HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\MySQL AB\MySQL Connector/Net</keyPath<
                <valueName<Version</valueName<
                <valueValue<5.2.5</valueValue<
              </registry<
            </discoveryHint<
          </or<
        </discoveryHint< 
    
  8. この <or> 要素は、<discoveryHint> 要素の少なくとも 1 つが満たされる必要があることを示しています。

WebPI API を使用してアプリケーションのリストをフィルター処理する

アプリケーション リスト フィードで提供されている情報に基づいてアプリケーションを並べ替えることができるユーザー インターフェイスをユーザーに提供できます。

<Keywords> 要素の下にある、各アプリケーションに関連付けられたキーワードを使用して、アプリケーションをフィルター処理できます。 前述のアプリケーション エントリの例に次の記述があります。
    <keywords>
      <keywordId>Blogs</keywordId>
      <keywordId>ASPNET</keywordId>
    </keywords>
 

次は、キーワードを使用してアプリケーションをフィルター処理する方法を示したコード スニペットです。

  ProductManager pm = new ProductManager();
    pm.Load(new Uri(appXml), false, false);
    foreach (Keyword k in pm.Keywords) {
        tw.WriteLine("******** Keyword " + k.Text + " Products *********");
        foreach (Product p in k.Products) {
            tw.WriteLine(p.Title + " (id = '" + p.ProductId + "')");
        }
    } 

この例では、Web.PlatformInstaller API を使用してアプリケーション リスト フィードを読み込んでから、アプリケーションをキーワード順にリストにしています。 ProductManager.Keywords (英語) コレクションは、読み込んだフィードから使用できるすべてのキーワードをリストにします。 次の例は、"PHP" キーワードを持つすべてのアプリケーションを一覧に表示し、続けて "ASPNET" キーワードを持つアプリケーションを一覧に表示します。

// get the php keyword
    Keyword phpKeyword = pm.GetKeyword("PHP");
    tw.WriteLine("******** PHP apps ********");
    foreach (Product p in phpKeyword.Products) {
        tw.WriteLine(p.Title + "(id = '" + p.ProductId + "')");
    }
    tw.Write("\r\n");
    // get aspnet keyword
    Keyword aspnetKeyword = pm.GetKeyword("ASPNET");
    tw.WriteLine("******** ASPNET apps ********");
    foreach (Product p in aspnetKeyword.Products) {
        tw.WriteLine(p.Title + "(id = '" + p.ProductId + "')");
    } 

Web 配置パッケージをダウンロードする

ユーザーがアプリケーションを選択したときに、アプリケーションがインストールされるサーバーの場所に Web 配置パッケージをダウンロードする必要があります。パッケージは HTTP 経由で入手可能になります。入手場所は、<installer> 要素内のデータとしてフィードに含まれています。 次に例を示します。

<installers>
      <installer>
        <id>1</id>
        <languageId>en</languageId>
        <osList idref="SupportedAppPlatforms" />
        <installerFile>
          <fileSize>1342</fileSize>
          <installerURL>https://blogengine.codeplex.com/Project/Download/FileDownload.aspx?DownloadId=66012</installerURL>
          <trackingURL>https://go.microsoft.com/fwlink/?LinkId=146340</trackingURL>
          <sha1>C1EA7BF684D85A0CAD2EE6DE859011A61264CF2C</sha1>
        </installerFile>
        <helpLink>https://forums.iis.net/1155.aspx</helpLink>
        <msDeploy>
          <startPage />
        </msDeploy>
      </installer>
    </installers>

インストーラー情報の抽出を説明したセクションで、WebPI API を使用してこの情報にアクセスする方法を示しました。このサンプル アプリケーションは、WebClient.DownloadFile メソッドを使用してパッケージ ファイルをダウンロードし、ダウンロード後にハッシュを確認してパッケージに必要とされるパラメーターを表示します。詳細については、以下の各セクションを参照してください。

SHA1 ハッシュを使用してパッケージを検証する

前の例に <sha1> 要素があります。 これには、ダウンロードするパッケージの SHA1 ハッシュが含まれています。 これは、パッケージの署名としての役割を果たしています。 このハッシュを使用して、ダウンロードしたパッケージが期待したものと確かに同じであることを検証できます。 このサンプル アプリケーションは、フィード xml ファイル内の各アプリケーションのハッシュ値を収集し、このハッシュを使用してダウンロードしたアプリケーションのハッシュを検証します。 サンプルの次のコード スニペットは、この検証の例です。

// Verify SHA1 Hash
    SHA1 sha1 = SHA1.Create();
    byte[] hash = sha1.ComputeHash(File.ReadAllBytes(_downloadTempFile));
    string hashString = hash.Aggregate("", (acc, value) => acc + value.ToString("X2"));
    if (DownloadHash.ToUpperInvariant() != hashString) {
        File.Delete(_downloadTempFile);
        _downloadTempFile = null;
        throw new InvalidOperationException("The download file appears to be corrupt.");
    }

パッケージ パラメーターを処理する

パッケージ内に定義されているパラメーターを収集する

ほとんどのパッケージには、任意の環境にインストールするために必要なパラメーターが含まれています。パネルの設計の一部として、計算して設定できるパラメーターの種類と、ユーザーからの入力を要求するパラメーターの種類を選択できます。

Web 配置 API を使用すると、Web 配置の DeploymentObject (英語) 内のコレクションにアクセスして、パッケージからパラメーターを取得できます。次のコード スニペットは、サンプル アプリケーションから引用したもので、後で使用するパラメーターを "_parameters" というコレクションとして生成する方法の 1 つを示しています。

private void LoadParameters() {
        string zipFile = GetDownload();
        if (!File.Exists(zipFile)) {
            throw new InvalidOperationException("Could not download package for ID=" + ID + ", Title=" + Title);
        }
        using (DeploymentObject iisApplication = DeploymentManager.CreateObject(DeploymentWellKnownProvider.Package, zipFile)) {
            _parameters = (from parameter in iisApplication.SyncParameters
                           where !IsHidden(parameter)
                           select parameter).ToList();
        }
    } 

このサンプルでは、上記の例の "_parameters" データ リストを Install.aspx ファイル内のリストビュー コントロールにバインドするために、 Parameters という名前の ReadOnlyCollection を使用しています。

ParameterList.DataSource = _package.Parameters;
ParameterList.DataBind();

パラメーターの名前とタグを使用する

典型的なパッケージでは、以下のパラメーター名の入力を求めます。

Application Path – これは、アプリケーションの Web サーバー パスです。Default Web Server/application_name のように、"Web サイト/アプリケーション" の形式になります。

Application database info – これは、アプリケーションがデータベースと通信するために必要なデータベース情報です。通常、4 つのパラメーターで構成されます。

  • Database Server – データベース サーバーのホスト名または IP アドレスです。
  • Database Name – データベースの名前です。
  • Database Username – アプリケーションがデータベースと通信する際に使用する ID です。
  • Database Password – データベース ユーザー名用のパスワードです。

Database Administrator info – これらは、データベースおよび上記のユーザーを作成するために必要な資格情報です。

これらのパラメーター名は推奨であり、必須ではありません。たとえば、どのパラメーターがデータベース接続の部分なのかをパネルで判断するには、そのパラメーターに含まれている tags を参照することで実現できます。

以下のタグをパラメーターと一緒に使用して、パラメーターの表示方法および使用方法を UI に伝えることができます。

  • iisApp - これは、パラメーターを、アプリケーションをインストールするアプリケーション パスとして識別します。 アプリケーションがどのサイトにインストールされるのかを既に知っている場合を除いて、defaultValue を表示する必要があります。 defaultValue は、通常 (強制ではありません)、"Default Web Site/application1" のような形式になります。 たとえば、ユーザーがログインし、そのユーザーが MySite.com の所有者であると判断した場合、その defaultValue を解析して "/application1" を取得し、ホストするサイト名にこれを追加できます。
  • Hidden – これは、ユーザー入力ではなくプログラムによって設定されるパラメーターを識別します。たとえば、接続文字列は、他のパラメーターの値から計算された既定値を持ちます。このエントリの {} で囲まれた部分は、これらのパラメーターの値で置換されます。
  • SQLConnectionString または MySQLConnectionString – これらのパラメーターは、データベースに接続するための接続文字列の構築に使用されます。
  • SQL または MySQL – これらのパラメーターは、特定のデータベースに関連して使用されます。パッケージは、そのデータベースとして SQL または MySQL のどちらでも使用できます。パラメーターには、これらのどちらか、または両方をタグ付けできます。使用するデータベースをユーザーが UI で選択するようにすることもできます。ConnectionString タグがあるすべてのパラメーターには、対応するデータベースのタグもあります。
  • Password - これは、既知のパスワードとして使用されるフィールドを識別します。UI では、値はそのまま表示されません。
  • New - Password タグと一緒に使用したときに、新しいパスワードの設定に使用されるフィールドを識別します。 UI では、パスワードの値がそのまま表示されることはなく、ユーザーに確認が求められます。 "New, Password" のように記述します。
  • dbUsername、dbUserPassword、dbAdminUsername、dbAdminPassword - アプリケーション パッケージをインストールする UI の中には、データベース作成を自動的に処理するものがあります。 ユーザーが既にデータベースを作成している場合は、ユーザーがデータを 2 回入力する必要がないように、これらの UI は管理資格情報をシームレスに隠して埋め込む操作を正しく行います。 UI がデータベース作成を処理する場合は、変更するパラメーターがこれらのタグで識別されます。
  • dbServer – データベース サーバー名を書き込むことができるパラメーターの識別に使用されます。
  • dbServer – データベースの名前を書き込むことができるパラメーターの識別に使用されます。

これらのタグは、DeploymentSyncParameter.Tags プロパティを使用して取得できます。これは、パラメーターに関連付けられた文字列を含む、コンマ区切りの文字列です。

パラメーターの中には、syncParameters コレクションから取得できる既定値を持つものがあります。環境に応じて、これらの既定値を使用するか、既定値が表示されたフォームを表示してユーザーに新しい値を求めるか、または既定値を無視するかを選択できます。

パラメーター検証データを使用する

上記のタグに加えて、適切なユーザー インターフェイスを構築するために使用できる検証データがあります。 各 DeploymentSyncParameter(英語) は、以下を 1 種類以上含むパラメーターを識別する DeploymentSyncParameterValidation オブジェクトを 1 つ持っています。

  • AllowEmpty: パラメーターは、空の値を許容します。
  • Boolean: パラメーターは、True または False のみを許容します。
  • Enumeration: パラメーターは、DeploymentSyncParameterValidation.ValidationString 内で指定された値のみを許容します。これはコンマ区切りの文字列です。  
  • RegularExpression: パラメーターは、DeploymentSyncParameterValidation.ValidationString 内に指定された正規表現に一致する文字列のみを許容します。

サンプル アプリケーションは、このデータを活用して、UI 入力コントロールを適切にセットアップします。 例として、いずれかのサンプル内で次のコード スニペットを探し、IsBooleam()、SplitValidationValues()、AllowEmpty()、および HasReg() の各定義を追跡してください。

 /// <summary>
    /// Gets the package's parameters.
    /// </summary>
    public ReadOnlyCollection<PackageParameter> Parameters {
        get {
            Initialize();
            return new ReadOnlyCollection<PackageParameter>(
                (from syncParam in _parameters
                 select new PackageParameter {
                     Name = syncParam.Name,
                     Description = syncParam.Description,
                     Value = syncParam.DefaultValue,
                     IsPassword = IsPassword(syncParam),
                     IsBoolean = IsBoolean(syncParam),
                     ValidationValues = SplitValidationValues(syncParam),
                     AllowEmpty = AllowEmpty(syncParam),
                     RegEx = HasRegEx(syncParam) ? syncParam.Validation.ValidationString : null // if there is no RegEx, allow any value
                 }).ToArray());
        }
    } 

アプリケーションを配置する

パラメーター用のデータすべてを収集したら、次はアプリケーションのインストールです。DeploymentObject を使用して、設定されたパラメーターを適用し、アプリケーションをインストールします。これを行うための API のステップを以下に示します。

DeploymentObject を初期化する

DeploymentObject に対して、アプリケーションをインストールする方法を伝える必要があります。次に例を示します。

using (DeploymentObject iisApplication =  
  DeploymentManager.CreateObject(providerOptions, 
  sourceOptions)) {
            DeploymentBaseOptions destinationOptions = new DeploymentBaseOptions {
                ComputerName = agentUri,
                UserName = userName,
                Password = password,
                AuthenticationType = "basic",
            }; 

この例では、ComputerName は MS Deploy Agent の URI です。UserName および Password は、このエージェントを使用する権限を持つ ID の資格情報です。

パラメーターを設定する

元のパッケージ内の各パラメーターは、値を持つ必要があります。パラメーターが DefaultValue を持っている場合は、この時点で新しい値を指定する必要はありません。DefaultValue を持っていないその他すべてのパラメーターには値を設定する必要があります。

// for each parameter that was specified in the UI, set its value 
foreach (PackageParameter updatedValue in updatedValues) {
    DeploymentSyncParameter parameter;     if (String.IsNullOrEmpty(updatedValue.Name)) {
       throw new InvalidOperationException("A value without a name was passed to the installer");
    }
 
    // find the parameter to which a value should be set
    if (! iisApplication.SyncParameters.TryGetValue(updatedValue.Name, out parameter)) {
       throw new InvalidOperationException("Could not find a parameter with the name " + updatedValue.Name);
     }
     // Set the value
     parameter.Value = updatedValue.Value;
} 
The 

アプリケーションをインストールするために MS Deploy で使用される Web サイトおよびアプリケーションは、Application Path パラメーターで指定されます。

アプリケーションをインストールする

アプリケーションは、DeploymentObject.SyncTo() メソッドを使用してインストールされます。サンプル アプリケーションからの SyncTo への呼び出しは次のとおりです。

// Install the application
DeploymentSyncOptions syncOptions = new DeploymentSyncOptions();
iisApplication.SyncTo(DeploymentWellKnownProvider.Auto, String.Empty, destinationOptions, syncOptions);

ここで、

  • DeploymentWellKnownProvider.Auto は、アプリケーションのインストールに MS Deploy Auto プロバイダーを使用することを指定しています。 このプロバイダーは、パッケージのマニフェスト、コンテンツ、およびパラメーター値を検査し、展開する必要のあるリソースを判断します。
  • destinationOptions は、アプリケーションのインストールに使用する、対象のコンピューター、資格情報、および認証の種類を指定しています。

対象のサーバーを変更する

サンプル アプリケーションは、対象のサーバーが localhost であることを前提としています。 Package.cs ファイルの Install メソッド内で、このコードが localhost を指定していて、SiteName は対応する UI フィールドにユーザーが入力した名前が入ることに注目してください。

    // change localhost to a computer name to do remote deployments
    string agentUri = "https://localhost:8172/msdeploy.axd?Site=" + Uri.EscapeDataString(siteName);

前述の例のように MySite という名前のサイトを作成する場合、サイト名を示す UI フィールドに「MySite」と入力する必要があります。

ユーザーにアプリケーションの場所を表示する

インストールが完了したときに、エンド ユーザーに対して、パネル上でそのアプリケーションへのリンクが提供されるようにしてください。この URL は、Web サイトのセットアップからの計算に基づいたものである必要があります。Atom フィード内のアプリケーション エントリに StartPage 要素が含まれているアプリケーションもあります。StartPage 要素が存在する場合は、ユーザーに提示するリンクにその値を追加する必要があります。

まとめ

本記事では、アプリケーションに Windows Web アプリケーション ギャラリーを含めるために必要な情報を提供しています。ギャラリーについての質問、ギャラリー フィードや MS Deploy API の使用に関する質問は、「Web アプリケーション ギャラリー: 開発者とインテグレーターのフォーラム (英語)」に自由に投稿してください。

リソース

MSDN:

Microsoft.Web.Deployment 名前空間 (英語): https://msdn.microsoft.com/en-us/library/microsoft.web.deployment.aspx(英語)

フォーラム:

Web アプリケーション ギャラリー: 開発者とインテグレーター (英語)
アプリケーションを Microsoft Web アプリケーション ギャラリーに提出する方法についてのディスカッションに利用してください。
https://forums.iis.net/1158.aspx

Web アプリケーション ギャラリー: ユーザー (英語)
Microsoft Web アプリケーション ギャラリーの使用についての一般的な質問のディスカッションに利用してください。
https://forums.iis.net/1159.aspx

**Web Platform Installer (英語)
**Web Platform Installer の使用についての質問と提案です。
https://forums.iis.net/1155.aspx

記事:

Windows Web アプリケーション ギャラリー向けアプリケーション パッケージング ガイド
/page.aspx/578/application-packaging-guide-for-the-windows-web-application-gallery/

Web アプリケーション ギャラリーの概要
/page.aspx/606/microsoft-web-application-gallery-overview/

Web アプリケーション ギャラリーの基本方針
/page.aspx/605/web-application-gallery-principles/ 

ベスト プラクティス: IIS での PHP アプリケーションの実行
/page.aspx/606/microsoft-web-application-gallery-overview/

ベスト プラクティス: IIS での ASP.NET アプリケーションの実行
 /page.aspx/23/building-and-running-aspnet-applications/