.NET中ClickOnce/智能客户端部署的陷阱/注意事项

31

我有几个使用.NET Windows Forms编写的应用程序,我正在准备将它们转换为ClickOnce/智能客户端部署方案。我已经阅读过一些介绍,但我需要注意哪些问题或陷阱呢?

这里有几个小型应用程序会被间歇性地使用,但主要应用程序是用C#编写的,24/7运行,非常大,但每隔几周才进行更改。它还会在本地写入日志文件并与本地硬件设备交互。


被关闭为“不具建设性” - 然而,这个问题的答案对我非常有帮助...决定不使用ClickOnce部署 ;) - Steven A. Lowe
我看到很多人抱怨 ClickOnce,但事情已经改变了。不要被这些答案吓到,它很容易设置并且有很好的优势。 - meda
11个回答

12

这是我所知道的一些问题。

  1. 无法在桌面上放置图标。现在可以了。

  2. 我不能为所有用户安装。

  3. 需要跳过一些步骤才能将部署移动到另一个服务器。如果您正在内部开发,并且用户可以看到您发布到的服务器,或者如果您正在部署到公共Web,那么这不是问题,但如果您需要独立地滚动到多个客户站点,则不是很好。

  4. .NET 3.5 SP1以来,您不再需要签署部署清单,这使得将部署移至新服务器变得更加容易。

  5. 我无法在GAC中安装程序集。您可以通过创建常规安装程序包作为ClickOnce应用程序的前提条件来解决此问题。


除非您使用.NET 3.5 SP1,否则无法更改过期的签名密钥(无需重新安装)。 - Roman Starkov
实际上,您可以通过使用新的更新URL(请参阅http://robindotnet.wordpress.com/2010/01/17/how-to-move-a-clickonce-deployment/)将其发布到不同的服务器,并且您可以通过将它们放入设置和部署包中并将它们部署为先决条件来在GAC中安装程序集。 - RobinDotNet
@RobinDotNet,从我们的构建环境直接发布到多个客户内部服务器并不容易。无论如何,.net3.5 sp1通过删除签名要求解决了我所有的问题。 - Darrel Miller
@RobinDotNet 用户需要管理员权限来安装先决条件吗? - Darrel Miller
是的,用户需要管理员权限来安装先决条件。 - RobinDotNet
去除签名要求会删除其中一个主要的安全检查。如果您知道安装 URL 将是什么,您可以将应用程序发布到文件夹中,但设置安装 URL 和签署部署。然后将其压缩并发送给客户。 - RobinDotNet

9
  • 当更新被部署时,内置对话框会让它看起来像整个应用程序正在重新下载。实际上,只有更改的DLL被下载,显示的进度条是误导/错误的。不要浪费时间试图弄清楚为什么所有程序集都被重新部署,只发现它们实际上并没有。不是我这样做的。
  • 当您用于签署原始部署清单的证书过期并且您获得了新证书时,您将面临严重问题(客户端都需要卸载并重新安装)。详细信息请参见官方说明

7

3
遗憾的是,它不能被干净地卸载。 - Roman Starkov

6
我们有一个应用程序,打算将其部署为ClickOnce应用程序。我们需要用户能够在安装过程中修改一些设置(例如部署路径-IT希望从他们的网络共享提供文件,而不是在构建时就知道)。当您更改部署中的任何文件时,需要重新计算所有哈希值并重新签名所有内容。因此,如果这个解决方案是内部的,您可能不会有问题传递签名证书,但如果这是针对客户的,则需要设计一个复杂的解决方案来绕过此问题。
我听说从互联网的某个角落传来了关于未来版本的ClickOnce将消除一些这种头疼的传言。

1
我希望你听到的传言是正确的...这对我们来说是一个巨大的问题! - Aaron

4

无法静默卸载ClickOnce部署的应用程序。此外,我认为不可能向启动快捷方式添加参数。


4
ClickOnce的一个缺点是无法安装到GAC。如果您想要安装多个应用程序共享DLL文件,则会出现问题。每个应用程序都需要本地副本的DLL文件。此外,多用户安装也不支持。请参见将Windows Installer与ClickOnce进行比较的列表

如果dll已经有强名称,ClickOnce会缓存它们。因此,如果您有多个应用程序使用相同的dll(我们有几个,包括log4net),ClickOnce将只在缓存中保留一份副本。 - RobinDotNet

3

有很多事情是ClickOnce应用程序无法做到的,例如安装快捷方式到用户桌面或决定应用程序的安装位置。对于一些人来说,这些问题是不能接受的。

此外,虽然我已经有一段时间没有使用过它了,但是有一种特殊的方法可以确定和显示ClickOnce版本/构建号,这与应用程序的版本/构建号是分开的。您需要使用try/catch语句,如果ClickOnce版本/构建号引发异常,则表示该应用程序未作为ClickOnce部署应用程序运行(即从Visual Studio编译的常规应用程序)。

对于一个简单的应用程序(即不是Microsoft Word,而是一个快速且粗略的应用程序),并且需要频繁部署,ClickOnce非常适合。但是您会很快遇到"哦,ClickOnce无法完成这个操作,请选择MSI或其他东西"这样的限制。


3
在尝试获取已部署版本号时,不要使用Try/Catch,而是将其包装在"If System.Deployment.Application.ApplicationDeployment.IsNetworkDeployed Then ..."中。这样会更加清晰简洁。如果是网络部署,您可以获取版本号。否则,您就不能获取。非常简单 :) - Kevin Fairchild

3
你的 .NET 应用程序将比正常情况下拥有更少的系统访问权限。 这是因为您将获得较低的信任级别。关于这个问题,可以参考.NET Framework 开发人员指南:ClickOnce 部署和安全
我对此最大的问题是无法使用机器密钥加密配置文件的部分内容,因为您无法访问该密钥(考虑到保护该密钥是有意义的)。

2
嗯,不确定...你可以请求更高的信任级别,用户可能会得到一个警告对话框。你可以在第一次运行时在代码中加密配置文件的各个部分,但不能在部署期间这样做,因为那是部署机器的密钥,而不是客户端的密钥,客户端无法读取。 - Nicholas Piasecki
正确,但要解密它,您始终需要具有更高的信任级别... - Davy Landman

3
如果有人在搜索中提到这个问题,我们发现许多客户担心“分发”他们的应用程序缺乏安全性。应用程序必须在公共位置上可用——没有任何身份验证——才能检查更新。唯一的例外是如果您有Windows NT身份验证。我认为Securing ClickOnce Applications解释了我的意思。
桌面图标通过代码相当容易实现,而且如上所述,在3.5 SP1中内置——因此这不再是一个问题。
xmlSerializer仍然存在一个未修复的bug——在某些情况下它无法正确部署。一个简单的解决方法是手动将此文件添加到部署中。很烦人,但足够简单...... 当您的部署突然失败时可能会令人震惊...

3

我不知道SP1允许您创建桌面图标。
这是我们一直在做的方式(现在被称为“艰难的方式”):

try
{
    string company = string.Empty;
    string product = string.Empty;
    if (Attribute.IsDefined(asm, typeof(AssemblyCompanyAttribute)))
    {
        AssemblyCompanyAttribute asCompany = (AssemblyCompanyAttribute)Attribute.GetCustomAttribute(asm, typeof(AssemblyCompanyAttribute));
        company = asCompany.Company;
    }
    if (Attribute.IsDefined(asm, typeof(AssemblyProductAttribute)))
    {
        AssemblyProductAttribute asProduct = (AssemblyProductAttribute)Attribute.GetCustomAttribute(asm, typeof(AssemblyProductAttribute));
        product = asProduct.Product;
    }
    if (!string.IsNullOrEmpty(company) && !string.IsNullOrEmpty(product))
    {
        string desktopPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
            product + ".appref-ms");
        string shortcutPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Programs),
            Path.Combine(company, product + ".appref-ms"));
        File.Copy(shortcutPath, desktopPath, true);
    }
}
catch 
{
    // Shortcut could not be created
}

SP1 是指什么?.NET 3.5? - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接