Sdílet prostřednictvím


Podrobné pokyny: Stahování sestavení na požádání s rozhraním API nasazení ClickOnce

Dle výchozího nastavení jsou všechna sestavení, která jsou součástí aplikace ClickOnce, stažena při prvním spuštění aplikace. Můžete však mít části aplikace, které jsou používány malou skupinu uživatelů. V tomto případě chcete stáhnout sestavení pouze tehdy, když vytváříte jeden z jeho typů. Následující návod ukazuje, jak označit určité sestavení v aplikaci jako "volitelné" a jak je stáhnout pomocí tříd v oboru názvů System.Deployment.Application, když je modul CLR (Common Language Runtime) požaduje.

Poznámka

Aplikace bude muset být spuštěna v úplném vztahu důvěryhodnosti k použití této procedury.

Požadavky

Budete potřebovat jednu z následujících komponent k dokončení tohoto postupu:

  • Sadu Windows SDK. Sadu Windows SDK lze stáhnout ze serveru Microsoft Download Center.

  • Visual Studio.

Vytváření projektů

Chcete-li vytvořit projekt, který používá sestavení na vyžádání

  1. Vytvořte adresář s názvem ClickOnceOnDemand.

  2. Otevřete příkazový řádek sady Windows SDK nebo příkazový řádek Visual Studio.

  3. Přejděte do adresáře ClickOnceOnDemand:

  4. Vygenerujte dvojici veřejný/soukromý klíč pomocí následujícího příkazu:

    sn -k TestKey.snk
    
  5. Pomocí Poznámkového bloku nebo jiného textového editoru definujte třídu s názvem DynamicClass s jedinou vlastností s názvem Message.

    Public Class DynamicClass
        Sub New()
    
        End Sub
    
        Public ReadOnly Property Message() As String
            Get
                Message = "Hello, world!"
            End Get
        End Property
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Microsoft.Samples.ClickOnceOnDemand
    {
        public class DynamicClass
        {
            public DynamicClass() {}
    
            public string Message
            {
                get
                {
                    return ("Hello, world!");
                }
            }
        }
    }
    
  6. Uložte text jako soubor s názvem ClickOnceLibrary.cs nebo ClickOnceLibrary.vb v závislosti na jazyku, který použijete v adresáři ClickOnceOnDemand.

  7. Zkompilujte soubor do sestavení.

    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
    vbc /target:library /keyfile:TestKey.snk ClickOnceLibrary.vb
    
  8. Chcete-li získat token veřejného klíče pro sestavení, použijte následující příkaz:

    sn -T ClickOnceLibrary.dll
    
  9. Vytvořte nový soubor pomocí textového editoru a zadejte následující kód. Tento kód vytvoří aplikaci modelu Windows Forms, která stáhne sestavení ClickOnceLibrary, pokud je požadováno.

    Imports System
    Imports System.Windows.Forms
    Imports System.Deployment.Application
    Imports System.Drawing
    Imports System.Reflection
    Imports System.Collections.Generic
    Imports Microsoft.Samples.ClickOnceOnDemand
    
    
    Namespace Microsoft.Samples.ClickOnceOnDemand
       <System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Unrestricted:=true)> _
       Class Form1
          Inherits Form
    
            ' Maintain a dictionary mapping DLL names to download file groups. This is trivial for this sample,
            ' but will be important in real-world applications where a feature is spread across multiple DLLs,
            ' and you want to download all DLLs for that feature in one shot. 
            Dim DllMapping as Dictionary(Of String, String) = new Dictionary(of String, String)()
    
          Public Sub New()
             ' Add button to form.
                Dim GetAssemblyButton As New Button()
                GetAssemblyButton.Location = New Point(100, 100)
                GetAssemblyButton.Text = "Get assembly on demand"
                AddHandler GetAssemblyButton.Click, AddressOf GetAssemblyButton_Click
    
                Me.Controls.Add(GetAssemblyButton)
    
                DllMapping("ClickOnceLibrary") = "ClickOnceLibrary"
                AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf CurrentDomain_AssemblyResolve
          End Sub
    
            <STAThread()> _
            Shared Sub Main()
                Application.EnableVisualStyles()
                Application.Run(New Form1())
            End Sub
    
            Private Function CurrentDomain_AssemblyResolve(ByVal sender As Object, ByVal args As ResolveEventArgs) As Assembly
                If ApplicationDeployment.IsNetworkDeployed Then
                    Dim deploy As ApplicationDeployment = ApplicationDeployment.CurrentDeployment
    
                    ' Get the DLL name from the Name argument.
                    Dim nameParts() as String = args.Name.Split(",")
                    Dim dllName as String = nameParts(0)
            Dim downloadGroupName as String = DllMapping(dllName)
    
                    Try
                        deploy.DownloadFileGroup(downloadGroupName)
                    Catch de As DeploymentException
    
                    End Try
    
                    ' Load the assembly.
                    Dim newAssembly As Assembly = Nothing
    
                    Try
                        newAssembly = Assembly.LoadFile(Application.StartupPath & "\\" & dllName & ".dll," & _  
                "Version=1.0.0.0, Culture=en, PublicKeyToken=03689116d3a4ae33")
                    Catch ex As Exception
                        MessageBox.Show("Could not download assembly on demand.")
                    End Try
    
                    CurrentDomain_AssemblyResolve = newAssembly
                Else
                    CurrentDomain_AssemblyResolve = Nothing
                End If
            End Function
    
            Private Sub GetAssemblyButton_Click(ByVal sender As Object, ByVal e As EventArgs)
                Dim ourClass As New DynamicClass()
                MessageBox.Show("DynamicClass string is: " + ourClass.Message)
            End Sub
        End Class
    End Namespace
    
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Reflection;
    using System.Deployment.Application;
    using Microsoft.Samples.ClickOnceOnDemand;
    
    namespace ClickOnceOnDemand
    {
        [System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Unrestricted=true)]
        public class Form1 : Form
        {
            // Maintain a dictionary mapping DLL names to download file groups. This is trivial for this sample,
            // but will be important in real-world applications where a feature is spread across multiple DLLs,
            // and you want to download all DLLs for that feature in one shot. 
            Dictionary<String, String> DllMapping = new Dictionary<String, String>();
    
            public static void Main()
            {
                Form1 NewForm = new Form1();
                Application.Run(NewForm);
            }
    
            public Form1()
            {
                // Configure form. 
                this.Size = new Size(500, 200);
                Button getAssemblyButton = new Button();
                getAssemblyButton.Size = new Size(130, getAssemblyButton.Size.Height);
                getAssemblyButton.Text = "Test Assembly";
                getAssemblyButton.Location = new Point(50, 50);
                this.Controls.Add(getAssemblyButton);
                getAssemblyButton.Click += new EventHandler(getAssemblyButton_Click);
    
                DllMapping["ClickOnceLibrary"] = "ClickOnceLibrary";
                AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
            }
    
            /*
             * Use ClickOnce APIs to download the assembly on demand.
             */
            private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
            {
                Assembly newAssembly = null;
    
                if (ApplicationDeployment.IsNetworkDeployed)
                {
                    ApplicationDeployment deploy = ApplicationDeployment.CurrentDeployment;
    
                    // Get the DLL name from the Name argument.
                    string[] nameParts = args.Name.Split(',');
                    string dllName = nameParts[0];
                    string downloadGroupName = DllMapping[dllName];
    
                    try
                    {
                        deploy.DownloadFileGroup(downloadGroupName);
                    }
                    catch (DeploymentException de)
                    {
                        MessageBox.Show("Downloading file group failed. Group name: " + downloadGroupName + "; DLL name: " + args.Name);
                        throw (de);
                    }
    
                    // Load the assembly.
                    // Assembly.Load() doesn't work here, as the previous failure to load the assembly
                    // is cached by the CLR. LoadFrom() is not recommended. Use LoadFile() instead.
                    try
                    {
                        newAssembly = Assembly.LoadFile(Application.StartupPath + @"\" + dllName + ".dll," +  
                "Version=1.0.0.0, Culture=en, PublicKeyToken=03689116d3a4ae33");
                    }
                    catch (Exception e)
                    {
                        throw (e);
                    }
                }
                else
                {
                    //Major error - not running under ClickOnce, but missing assembly. Don't know how to recover.
                    throw (new Exception("Cannot load assemblies dynamically - application is not deployed using ClickOnce."));
                }
    
    
                return (newAssembly);
            }
    
            private void getAssemblyButton_Click(object sender, EventArgs e)
            {
                DynamicClass dc = new DynamicClass();
                MessageBox.Show("Message: " + dc.Message);
            }
        }
    }
    
  10. V kódu nalézněte volání do LoadFile.

  11. Nastavte hodnotu PublicKeyToken na hodnotu, kterou jste načetli dříve.

  12. Uložte soubor buďto jako Form1.cs nebo Form1.vb.

  13. Zkompilujte jej do spustitelného souboru pomocí následujícího příkazu.

    csc /target:exe /reference:ClickOnceLibrary.dll Form1.cs
    
    vbc /target:exe /reference:ClickOnceLibrary.dll Form1.vb
    

Označování sestavení jako volitelné

Pro označení sestavení jako volitelné v aplikaci ClickOnce pomocí MageUI.exe

  1. Vytvořte manifest aplikace pomocí MageUI.exe způsobem popsaným v Podrobné pokyny: Ruční nasazení aplikace ClickOnce. Pro manifest aplikace použijte následující nastavení:

    • Nazvěte manifest aplikace ClickOnceOnDemand.

    • Na stránce Soubory v řádku ClickOnceLibrary.dll nastavte sloupec Typ souboru na None.

    • Na stránce Soubory v řádku ClickOnceLibrary.dll napište ClickOnceLibrary.dll do sloupce Skupina.

  2. Pomocí MageUI.exe vytvořte manifest nasazením jak je popsáno v Podrobné pokyny: Ruční nasazení aplikace ClickOnce. Pro manifest nasazení použijte následující nastavení:

    • Nazvěte manifest nasazení ClickOnceOnDemand.

Testování nového sestavení

Pro testování Vašeho sestavení na vyžádání

  1. Odešlete vaše nasazení ClickOnce na webový server.

  2. Spusťte aplikaci nasazenou s ClickOnce z webového prohlížeče zadáním adresy URL manifestu nasazení. Pokud zavoláte vaši aplikaci ClickOnce ClickOnceOnDemand a odešlete ji do kořenového adresáře serveru adatum.com, adresa URL by měla vypadat takto:

    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. Po zobrazení hlavního formuláře, stiskněte Button. Měli byste vidět řetězec v okně zprávy s nápisem "Hello, World!"

Viz také

Odkaz

ApplicationDeployment