演练:在设计器中使用 ClickOnce 部署 API 按需下载程序集
默认情况下,ClickOnce 应用程序中包含的所有程序集都会在应用程序首次运行时进行下载。 但是,可能有一小部分用户使用部分应用程序。 在这种情况下,你希望仅当创建其类型之一时才下载程序集。 下面的演练演示如何将应用程序中的某些程序集标记为“可选”,以及如何在公共语言运行时需要它们时使用 System.Deployment.Application 命名空间中的类下载它们。
备注
.NET Core 和 .NET 5 及更高版本中不支持 System.Deployment.Application 命名空间中的 ApplicationDeployment 类和 API。 在 .NET 7 中,支持一种访问应用程序部署属性的新方法。 有关详细信息,请参阅访问 .NET 中的 ClickOnce 部署属性。 .NET 7 不支持等效的 ApplicationDeployment 方法。
注意
应用程序必须在完全信任下运行才能使用此过程。
注意
显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于你现用的设置或版本。 若要更改设置,请单击 “工具” 菜单上的 “导入和导出设置” 。 有关详细信息,请参阅重置设置。
创建项目
通过 Visual Studio 创建使用按需程序集的项目
在 Visual Studio 中创建新的 Windows Forms 项目。 在 “文件” 菜单上,指向 “添加”,再单击 “新建项目”。 在对话框中选择“类库” 项目,并将它命名为
ClickOnceLibrary
。备注
在 Visual Basic 中,我们建议修改项目属性以将此项目的根命名空间更改为
Microsoft.Samples.ClickOnceOnDemand
或更改为所选的命名空间。 为简单起见,此演练中的两个项目处于同一个命名空间中。定义一个名为
DynamicClass
的类,它具有名为Message
的单个属性。在“解决方案资源管理器” 中选择 Windows 窗体项目。 添加对 System.Deployment.Application 程序集的引用以及对
ClickOnceLibrary
项目的项目引用。备注
在 Visual Basic 中,我们建议修改项目属性以将此项目的根命名空间更改为
Microsoft.Samples.ClickOnceOnDemand
或更改为所选的命名空间。 为简单起见,此演练中的两个项目处于同一个命名空间中。右键单击窗体,在菜单中单击“查看代码” ,然后将以下引用添加到窗体。
添加以下代码以按需下载此程序集。 此代码演示如何使用泛型 Dictionary 类将一组程序集映射到一个组名称。 因为我们在此演练中只下载单个程序集,所以组中只有一个程序集。 在实际应用程序中,你可能要同时下载与应用程序中的单个功能相关的所有程序集。 通过映射表可以将属于某个功能的所有 DLL 与下载组名称关联,从而使你可以轻松地实现此目标。
// 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>(); [SecurityPermission(SecurityAction.Demand, ControlAppDomain=true)] public Form1() { InitializeComponent(); 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"); } 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); }
在“视图”菜单上,单击“工具箱”。 将 Button 从“工具箱” 拖动到窗体上。 双击按钮并将下面的代码添加到 Click 事件处理程序。
将程序集标记为可选
使用 Visual Studio 在 ClickOnce 应用程序中将程序集标记为可选
在“解决方案资源管理器” 中右键单击 Windows 窗体项目,然后单击“属性” 。 选择“发布” 选项卡。
单击“应用程序文件” 按钮。
在列表中找到 ClickOnceLibrary.dll。 将“发布状态” 下拉框设置为“包括” 。
展开“组” 下拉框,然后选择“新建” 。 输入名称
ClickOnceLibrary
作为新的组名称。继续发布应用程序,如操作说明:使用发布向导发布 ClickOnce 应用程序中所述。
使用清单生成和编辑工具在 ClickOnce 应用程序中将程序集标记为可选 — 图形客户端 (MageUI.exe)
创建 ClickOnce 清单,如演练:手动部署 ClickOnce 应用程序中所述。
关闭 MageUI.exe 之前,选择包含部署应用程序清单的选项卡,然后在该选项卡中选择“文件” 选项卡。
在应用程序文件的列表中找到 ClickOnceLibrary.dll,然后将其“文件类型” 列设置“无” 。 对于“组” 列,输入
ClickOnceLibrary.dll
。
测试新程序集
测试按需程序集:
启动使用 ClickOnce 部署的应用程序。
在主窗体显示时按 Button。 你应在消息框窗口中看到一个显示为“Hello, World!”的字符串