Udostępnij za pośrednictwem


Wskazówki: pobieranie zestawów na żądanie przy użyciu wdrażania interfejsu API ClickOnce

Domyślnie, wszystkie zestawy zawarte w ClickOnce aplikacji są pobierane, gdy aplikacja najpierw jest uruchomiona.Jednakże może mieć części aplikacji, które są używane przez niewielki zestaw użytkowników.W tym przypadku chcesz pobrać zestawu tylko wtedy, gdy tworzysz jeden z jego typów.Następujące instruktażu przedstawiono sposób oznaczania niektórych zespołów w aplikacji jako "optional" i jak je pobrać przy użyciu klas w System.Deployment.Application obszaru nazw podczas common language runtime (CLR) wymaga ich.

[!UWAGA]

Aplikacja będzie uruchamiane w pełne zaufanie, aby użyć tej procedury.

Wymagania wstępne

Jeden z następujących składników do przeprowadzenia tego instruktażu będą potrzebne:

  • Windows SDK.Windows SDK można pobrać z witryny Microsoft — Centrum pobierania.

  • Program Visual Studio.

Tworzenie projektów

Aby utworzyć projekt, który używa zestawu na żądanie

  1. Utwórz katalog o nazwie ClickOnceOnDemand.

  2. Otwórz okno wiersza polecenia systemu Windows SDK lub Visual Studio wiersza polecenia.

  3. Przejdź do katalogu ClickOnceOnDemand.

  4. Generuje parę kluczy publicznego i prywatnego za pomocą następującego polecenia:

    sn -k TestKey.snk
    
  5. Za pomocą Notatnika lub innego edytora tekstu, zdefiniować klasę o nazwie DynamicClass z jedną właściwość o nazwie 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. Zapisz tekst jako plik o nazwie ClickOnceLibrary.cs lub ClickOnceLibrary.vb, w zależności od języka, można użyć do katalogu ClickOnceOnDemand.

  7. Skompiluj plik do zestawu.

    csc /target:library /keyfile:TestKey.snk ClickOnceLibrary.cs
    
    vbc /target:library /keyfile:TestKey.snk ClickOnceLibrary.vb
    
  8. Aby uzyskać token klucza publicznego dla zestawu, polecenie:

    sn -T ClickOnceLibrary.dll
    
  9. Utwórz nowy plik przy użyciu tekstu edytora i wprowadź następujący kod.Kod ten tworzy aplikacji Windows Forms, który pobiera zestawu ClickOnceLibrary, gdy jest to wymagane.

    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. W kodzie, zlokalizuj wywołanie LoadFile.

  11. Ustaw PublicKeyToken do wartości, do którego został pobrany wcześniej.

  12. Zapisz plik jako Form1.cs lub Form1.vb.

  13. Skompiluj go do pliku wykonywalnego, przy użyciu następującego polecenia.

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

Oznaczanie zestawów jako opcjonalne

Aby oznaczyć zestawów jako opcjonalne w aplikacji ClickOnce przy użyciu MageUI.exe

  1. Za pomocą MageUI.exe, Utwórz manifest aplikacji w sposób opisany w Wskazówki: ręczne wdrażanie aplikacji ClickOnce.Manifest aplikacji, należy użyć następujących ustawień:

    • Nazwa manifest aplikacji ClickOnceOnDemand.

    • Na pliki w wierszu ClickOnceLibrary.dll na stronie, ustaw Typ pliku kolumny do Brak.

    • Na pliki stronie w polu Typ wiersza ClickOnceLibrary.dll ClickOnceLibrary.dll w grupy kolumny.

  2. Za pomocą MageUI.exe, Utwórz manifestu wdrażania, zgodnie z opisem w Wskazówki: ręczne wdrażanie aplikacji ClickOnce.Manifest wdrażania, należy użyć następujących ustawień:

    • Nazwę manifestu wdrażania ClickOnceOnDemand.

Testowanie nowego zestawu

Aby przetestować na zgromadzenie na żądanie

  1. Przekaż na ClickOnce wdrażania na serwerze sieci Web.

  2. Uruchomić aplikacji rozmieszczone wraz z ClickOnce z przeglądarki sieci Web, wpisując adres URL do manifestu wdrażania.Jeśli zadzwonisz your ClickOnce aplikacji ClickOnceOnDemandi przekazaniu go do katalogu głównego adatum.com, adres URL będzie wyglądać następująco:

    http://www.adatum.com/ClickOnceOnDemand/ClickOnceOnDemand.application
    
  3. Gdy pojawi się główne formularza, naciśnij klawisz Button.Powinieneś zobaczyć ciąg w okno komunikatu, który czyta "Hello, World!".

Zobacz też

Informacje

ApplicationDeployment