如何同时部署两个 ClickOnce 版本?

38

我想要建立一个测试ClickOnce服务器,让用户可以同时运行生产版本和测试版本。这种做法可行吗?

我最初尝试在AssemblyInfo.cs文件中使用以下内容,并在ClickOnce部署中更改名称,但所有这些只是用测试版本覆盖了用户的生产版本。同样地,当他们回到生产服务器时,也会发生同样的情况。

#if DEBUG
[assembly: AssemblyTitle("Product Name - Test")]
#else
[assembly: AssemblyTitle("Product Name")]
#endif

我认为我还应该澄清一下,这两个部署位置彼此不同且位于不同的服务器上。

更新

我也尝试根据调试模式设置清单的GUID,但仍然无法正常工作(下面使用虚拟GUID)。

#if DEBUG
[assembly: Guid("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA")]
#else
[assembly: Guid("BBBBBBBB-BBBB-BBBB-BBBB-BBBBBBBBBBBB")]
#endif

这两个有什么区别?安装程序似乎将它们视为两个单独的程序,因为我会得到每个程序的安装确认。但是,当我安装第二个时,“添加/删除程序”只看到后者,尽管前者仍然存在于磁盘上,因为当我稍后重新安装它时,它只是简单地运行,然后添加/删除程序会切换回前者的名称。


1
针对您关于 ClickOnce 应用程序标识的第二个问题,它与程序集 GUID 无关,而是与您发布所签名的密钥(PFX 文件)有关。 - Rob Fonseca-Ensor
1
@Rob 这很有趣,所以如果我有多个使用相同密钥签名的应用程序,这会导致Windows认为它们是同一个应用程序?这对我来说似乎是一个严重的缺陷。 - Brett Ryan
1
不,这不是问题。我安装了7个使用相同密钥签名的应用程序,这并不是问题。 - RobinDotNet
9个回答

29

这可能听起来有点没劲,但最简单的方法是在解决方案中有两个EXE项目。每个项目的Main方法只需调用您原始EXE项目的Main方法(您刚刚将其转换为DLL文件)。

这意味着每个EXE项目都可以拥有自己的ClickOnce发布设置以及自己的app.config文件。这意味着您可以为生产和测试版本设置不同的连接字符串。

另一个选项(看起来最有意义的选项)是使用MageUI.exe手动构建ClickOnce文件,从而让您每次运行工具时选择不同的配置文件和发布位置。还有一个命令行版本(Mage.exe),因此您理论上可以自动化此过程。

然而,我们发现使用两个“运行器”项目的解决方案要简单得多。我建议您先尝试这种方法。


我能看到这两个存根exe的简单性,但同时也意识到维护两套配置等方面的负担。我会先尝试使用mage,然后再尝试另一种方法。我可以看到使用这两个存根exe来维护用户设置是真正的痛苦。 - Brett Ryan
我认为你的两个存根的想法是正确的,虽然听起来不太合理,但确实比使用mage要简洁得多。然而,正如之前提到的,我担心我的团队会在配置差异方面遇到问题,我们可能需要通过构建过程从每个项目中合并app.configs来管理这些问题,这真是太糟糕了! - Brett Ryan
这可能会对此有所帮助:https://dev59.com/dHVC5IYBdhLWcg3w-WOs - Rob Fonseca-Ensor
1
关于使用命令行版本的mage自动化部署的一点说明。它可以正常工作,但是它是mageui的一个子集。有很多事情你只能用命令行mage做不了,比如设置应用程序图标。 - codeConcussion
为了解决用户设置中的重复问题,我在原始项目中创建了第二个设置文件,其中包含需要在其他项目中覆盖的设置。将文件的访问修饰符更改为Public后,您可以在其他项目中创建app.config文件以覆盖这些设置。 - Der

16

谢谢Robin,看起来这是一个相当简单的方法,但有一些需要记住要更改/更改回来的事情,是否有一种简单的方法可以做到这一点,也许是一个MSBuild文件,可以很简单地导入现有的csproj文件,但设置AssemblyName等?我发现你不能在属性组中更改它们,如果你尝试,它们会被忽略。 - Brett Ryan
2
你只需要更改三个东西:部署URL、程序集名称和产品名称。我们使用源代码控制,所以我会将这些更改保存在一个集合中,并在需要时还原它们。 - RobinDotNet
5
@RobinDotNet 虽然这理论上回答了问题,但最好还是在这里包含答案的基本部分,并提供链接作为参考。 - Metro Smurf
基于那个视频日志:
  1. 为“测试”版本创建源代码控制分支,将“Live”放在主分支上。
  2. 在Visual Studio 2017(VS)中,在“发布...应用程序”下,将“Test”后缀添加到“程序集名称”中。
  3. 在VS中,在“发布...发布”下,将“Test”后缀添加到“发布文件夹位置”和“安装文件夹URL”中。
  4. 在VS中,在“发布...发布...选项...”下,将“Test”后缀添加到“产品名称”中。
  5. 更改应用程序使用的任何文件或资源(例如日志文件)。
  6. 发布。
  7. 一旦测试完成,将“Test”分支合并到“master”中,并反转步骤。
- David Savage

7

我手动编辑了.csproj文件,为debug/release指定了一个不同的ProductName

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    ...
    <PublishUrl>publishbeta\</PublishUrl>
    <InstallUrl>http://www.softwareabc.com/download/beta/</InstallUrl>
    <ProductName>Software ABC Test</ProductName>
    <AssemblyName>SoftABCTest</AssemblyName>
    <ApplicationIcon>Resources\Test.ico</ApplicationIcon>
  </PropertyGroup>
  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
    ...
    <PublishUrl>publish\</PublishUrl>
    <InstallUrl>http://www.softwareabc.com/download/</InstallUrl>
    <ProductName>Software ABC</ProductName>
    <AssemblyName>SoftABC</AssemblyName>
    <ApplicationIcon>Resources\Application.ico</ApplicationIcon>
</PropertyGroup>

需要注意的是,Visual Studio 2010 在调试和发布之间切换时不会更新此设置。只有在加载解决方案时才会生效,因此请确保在切换调试/发布后关闭并重新打开解决方案。


当我尝试这样做时,PropertyGroup的ClickOnce条件实际上被覆盖了。 - kbeal2k
1
我从未见过它被覆盖,但绝对不要通过 Visual Studio 中的项目 GUI 更改任何构建设置,这可能会覆盖它。 - LongZheng
如果您使用一个配置进行发布,请切换到另一个配置并关闭解决方案 - VS 将询问您是否要保存项目(因为它实际上已经覆盖了这些属性)。选择“否”,然后重新打开解决方案。在这种情况下,您的属性不会被覆盖。显然,由于这个原因,这是一种脆弱的解决方案,但如果您小心谨慎,它确实可以工作。 - Steven Pena
@StevenPena - 是的,但这正是您试图通过自动化部署来避免的问题 - 在每次发布之前需要检查发布、安装和更新 URL。而且,您如何保证其中一个开发人员不会在某个时候错误地保存项目属性选项卡呢?必须有更可靠的解决方案。app.config 问题很容易解决 - 您只需为每个环境添加一个 .config 文件,例如 app.config.devtest、app.config.uat、app.config.prod 和一个预构建命令: xcopy /y "$(ProjectDir)app.config.$(ConfigurationName)" "$(ProjectDir)app.config" - Chris W.
1
@ChrisW。是的。这不是自动化方法。我在这里澄清了提出的答案,这是一种手动方法 - 但它确实提出了一个解决问题的方案(原始问题中没有关于自动化的内容)。您提出的问题是不同的问题,不是在这里提出和回答的问题。我建议您创建一个更具体的自动化问题。 - Steven Pena

2

基于那个视频日志:
  1. 为“测试”版本创建源代码控制分支,将“Live”放在主分支上。
  2. 在Visual Studio 2017(VS)中,在“发布...应用程序”下,将“Test”后缀添加到“程序集名称”中。
  3. 在VS中,在“发布...发布”下,将“Test”后缀添加到“发布文件夹位置”和“安装文件夹URL”中。
  4. 在VS中,在“发布...发布...选项...”下,将“Test”后缀添加到“产品名称”中。
  5. 更改应用程序使用的任何文件或资源(例如日志文件)。
  6. 发布。
  7. 一旦测试完成,将“Test”分支合并到“master”中,并反转步骤。
- David Savage

1

尝试在属性窗口的应用程序选项卡中更改程序集名称。


3
很不幸,这只解决了问题的部分,客户端仍然认为它是一个不同名称的相同应用程序,因此任何ApplicationSettingsBase对象的数据存储都会被共享,测试版本最终会破坏生产版本。 - Brett Ryan

1

可以在不更改AssemblyName的情况下部署同一应用程序的2个版本,以下是操作步骤...

  1. 创建ClickOnce部署
  2. 打开.application文件并进行以下编辑:

输入图像说明 3. 运行设置程序,MyApp将被安装。根据之前的尝试,您可能需要使用mage -cc清除应用程序缓存。

  1. 再次编辑.application文件,将MyApp替换为MyApp2

  2. 运行设置程序,将安装MyApp2


0

我经常这样做。我甚至在我的应用程序中有一个屏幕,可以更改特定用户将获得哪个版本。而且我在应用程序端没有做任何复杂的操作,所有的魔法都在托管ClickOnce文件的Web服务器上。

看看我的朋友写的文章,使用ClickOnce进行细粒度版本控制。它解释了我们是如何做到的。


我实际上正在尝试允许同一应用程序的两个 ClickOnce 安装,尽管它们是不同版本,一个是生产树版本,另一个是位于另一个更新服务器上的测试树。 - Brett Ryan
在另一台服务器上...是的,听起来你需要使用MageUI进行操作。 - Jonathan Allen
这个能在Linux上运行吗(比如,在Web服务器上的Apache)?或者甚至在Web服务器上的IIS上也可以吗? - Peter Mortensen
我不认为有什么问题。归根结底,ClickOnce只是下载一个或两个文件。它不知道也不关心您用什么来托管文件。 - Jonathan Allen

0

这是基于Peter Mortensen的两个项目场景的变化。我想要开发、客户测试和客户发布。在我的情况下,我希望客户测试提供一些视觉线索,表明它是测试而不是实时环境(例如标题中的“TEST”和不同的视觉主题)。

我发现最简单的方法是有两个解决方案以及两个存根项目。每个项目都有自己的目录、自己的stub program.cs、app.config和assemblyinfo.cs。

在开发/测试解决方案中,调试配置用于开发,发布配置用于客户测试。我使用SlowCheetah来转换后者的app.config。

在客户发布解决方案中,我只需要一个发布配置。


0

在至少配置了一次项目以发布Click Once应用程序后,您必须手动编辑csproj。

将一些与Click Once相关的属性从<PropertyGroup>移动到<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">属性组,并在<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">属性组下进行复制。

要复制的属性包括ApplicationRevision(仅在您想要单独的修订计数器时),PublishUrlProductNameSuiteName(最后两个是必需的,以便能够区分目标机器上的配置)。您还需要覆盖AssemblyName属性(但不要将其从第一组中删除)。

如果您想在任何配置下调试项目,还必须在每个覆盖AssemblyName属性的组中添加StartActionStartProgram属性。

在为这些属性赋予充分的(即不同的)值之后,您将能够发布两个配置,而无需修改您的项目,只需选择所需的配置即可。但请注意,您必须在发布不同配置之间卸载项目,否则Visual Studio会混淆您的参数。

此外,您还可以在同一目标机器上安装两个版本。


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