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);
}
}
}