チュートリアル: ClickOnce アプリケーションのカスタム インストーラーの作成

.exe ファイルに基づく ClickOnce アプリケーションは、カスタム インストーラーによってサイレント インストールおよび更新できます。 カスタム インストーラーでは、セキュリティ操作とメンテナンス操作のためのカスタム ダイアログ ボックスなど、インストール時のカスタムのユーザー エクスペリエンスを実装できます。 インストール操作を実行するために、カスタム インストーラーでは InPlaceHostingManager クラスを使用します。 このチュートリアルでは、ClickOnce アプリケーションをサイレント インストールするカスタム インストーラーを作成する方法について説明します。

Note

NET Core および .NET 5 以降のバージョンでは、System.Deployment.Application 名前空間内の ApplicationDeployment クラスと API はサポートされていません。 .NET 7 では、アプリケーションの配置プロパティにアクセスするための新しいメソッドがサポートされています。 詳細については、.NET の ClickOnce 配置プロパティへのアクセスに関するページを参照してください。 .NET 7 では、ApplicationDeployment メソッドと同等のメソッドはサポートされていません。

前提条件

カスタム ClickOnce アプリケーション インストーラーを作成するには

  1. ClickOnce アプリケーションで、System.Deployment と System.Windows.Forms への参照を追加します。

  2. アプリケーションに新しいクラスを追加し、任意の名前を指定します。 このチュートリアルでは、名前 MyInstaller を使用します。

  3. 次の Imports ディレクティブまたは using ディレクティブを新しいクラスの先頭に追加します。

    using System.Deployment.Application;
    using System.Windows.Forms;
    
  4. 次のメソッドをクラスに追加します。

    これらのメソッドでは、InPlaceHostingManager メソッドを呼び出して配置マニフェストをダウンロードし、適切なアクセス許可をアサートし、インストールのアクセス許可をユーザーに要求してから、アプリケーションを ClickOnce キャッシュにダウンロードしてインストールします。 カスタム インストーラーでは、ClickOnce アプリケーションが事前に信頼されていることを指定できます。また、AssertApplicationRequirements メソッド呼び出しに対して信頼の決定を保留することもできます。 このコードによって、アプリケーションが事前に信頼されます。

    Note

    事前信頼によって割り当てられるアクセス許可は、カスタム インストーラー コードのアクセス許可を超えることはできません。

    InPlaceHostingManager iphm = null;
    
    public void InstallApplication(string deployManifestUriStr)
    {
        try
        {
            Uri deploymentUri = new Uri(deployManifestUriStr);
            iphm = new InPlaceHostingManager(deploymentUri, false);
        }
        catch (UriFormatException uriEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "The deployment manifest URL supplied is not a valid URL. " +
                "Error: " + uriEx.Message);
            return;
        }
        catch (PlatformNotSupportedException platformEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "This program requires Windows XP or higher. " +
                "Error: " + platformEx.Message);
            return;
        }
        catch (ArgumentException argumentEx)
        {
            MessageBox.Show("Cannot install the application: " + 
                "The deployment manifest URL supplied is not a valid URL. " +
                "Error: " + argumentEx.Message);
            return;
        }
    
        iphm.GetManifestCompleted += new EventHandler<GetManifestCompletedEventArgs>(iphm_GetManifestCompleted);
        iphm.GetManifestAsync();
    }
    
    void iphm_GetManifestCompleted(object sender, GetManifestCompletedEventArgs e)
    {
        // Check for an error.
        if (e.Error != null)
        {
            // Cancel download and install.
            MessageBox.Show("Could not download manifest. Error: " + e.Error.Message);
            return;
        }
    
        // bool isFullTrust = CheckForFullTrust(e.ApplicationManifest);
    
        // Verify this application can be installed.
        try
        {
            // the true parameter allows InPlaceHostingManager
            // to grant the permissions requested in the applicaiton manifest.
            iphm.AssertApplicationRequirements(true) ; 
        }
        catch (Exception ex)
        {
            MessageBox.Show("An error occurred while verifying the application. " +
                "Error: " + ex.Message);
            return;
        }
    
        // Use the information from GetManifestCompleted() to confirm 
        // that the user wants to proceed.
        string appInfo = "Application Name: " + e.ProductName;
        appInfo += "\nVersion: " + e.Version;
        appInfo += "\nSupport/Help Requests: " + (e.SupportUri != null ?
            e.SupportUri.ToString() : "N/A");
        appInfo += "\n\nConfirmed that this application can run with its requested permissions.";
        // if (isFullTrust)
        // appInfo += "\n\nThis application requires full trust in order to run.";
        appInfo += "\n\nProceed with installation?";
    
        DialogResult dr = MessageBox.Show(appInfo, "Confirm Application Install",
            MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
        if (dr != System.Windows.Forms.DialogResult.OK)
        {
            return;
        }
    
        // Download the deployment manifest. 
        iphm.DownloadProgressChanged += new EventHandler<DownloadProgressChangedEventArgs>(iphm_DownloadProgressChanged);
        iphm.DownloadApplicationCompleted += new EventHandler<DownloadApplicationCompletedEventArgs>(iphm_DownloadApplicationCompleted);
    
        try
        {
            // Usually this shouldn't throw an exception unless AssertApplicationRequirements() failed, 
            // or you did not call that method before calling this one.
            iphm.DownloadApplicationAsync();
        }
        catch (Exception downloadEx)
        {
            MessageBox.Show("Cannot initiate download of application. Error: " +
                downloadEx.Message);
            return;
        }
    }
    
    /*
    private bool CheckForFullTrust(XmlReader appManifest)
    {
        if (appManifest == null)
        {
            throw (new ArgumentNullException("appManifest cannot be null."));
        }
    
        XAttribute xaUnrestricted =
            XDocument.Load(appManifest)
                .Element("{urn:schemas-microsoft-com:asm.v1}assembly")
                .Element("{urn:schemas-microsoft-com:asm.v2}trustInfo")
                .Element("{urn:schemas-microsoft-com:asm.v2}security")
                .Element("{urn:schemas-microsoft-com:asm.v2}applicationRequestMinimum")
                .Element("{urn:schemas-microsoft-com:asm.v2}PermissionSet")
                .Attribute("Unrestricted"); // Attributes never have a namespace
    
        if (xaUnrestricted != null)
            if (xaUnrestricted.Value == "true")
                return true;
    
        return false;
    }
    */
    
    void iphm_DownloadApplicationCompleted(object sender, DownloadApplicationCompletedEventArgs e)
    {
        // Check for an error.
        if (e.Error != null)
        {
            // Cancel download and install.
            MessageBox.Show("Could not download and install application. Error: " + e.Error.Message);
            return;
        }
    
        // Inform the user that their application is ready for use. 
        MessageBox.Show("Application installed! You may now run it from the Start menu.");
    }
    
    void iphm_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
    {
        // you can show percentage of task completed using e.ProgressPercentage
    }
    
  5. コードからインストールを試みるには、InstallApplication メソッドを呼び出します。 たとえば、クラスに MyInstaller という名前を付けた場合は、次のように InstallApplication を呼び出すことができます。

    MyInstaller installer = new MyInstaller();
    installer.InstallApplication(@"\\myServer\myShare\myApp.application");
    MessageBox.Show("Installer object created.");
    

次のステップ

ClickOnce アプリケーションでは、更新プロセス中に表示するカスタム ユーザー インターフェイスを含む、カスタムの更新ロジックを追加することもできます。 詳細については、UpdateCheckInfoを参照してください。 ClickOnce アプリケーションでは、<customUX> 要素を使用して、[スタート] メニューの標準エントリ、ショートカット、および [プログラムの追加と削除] エントリを抑制することもできます。 詳細については、「<entryPoint> 要素」および「ShortcutAppId」を参照してください。