构建为多个环境创建ClickOnce包的方法

时间:2012-05-15 20:34:33

标签: wpf deployment build clickonce

以下是我的情景:

我有一个WPF应用程序,我通过ClickOnce提供。该应用程序具有多个客户端的多个环境(目前有9个,但预计在不久的将来会翻倍)。

我目前使用的流程(基本上):

  • 令牌替换部分app.config
  • 令牌替换生成MSI安装程序时使用的部分WiX文件(包括签名证书和指纹)
  • 构建解决方案
  • 创建客户端/环境特定安装程序
  • 对每个客户端/环境组合重复

这样做的好处是,要安装应用程序,只需运行所需的安装程序即可。但是,缺点是,如果(当)我需要创建一个新环境,我必须使用一组新的配置参数重新运行整个构建过程。

我怎样才能让这一切变得更好?

我最近的想法是我将构建过程拆分为仅创建二进制文件。然后有一个单独的包装过程,用适当的二进制文件,修补的配置,(重新)使用MAGE等签署的清单。

这将具有“一次构建,多次部署”的持续优势,同时确保如果需要新环境,则可以重新打包而无需重建二进制文件。

这听起来像是一种明智的做法吗? 有没有人对这种情况有任何指导?

由于

2 个答案:

答案 0 :(得分:1)

我们有一个类似的场景,在多个环境中使用WPF ClickOnce应用程序,其中app.config中唯一的东西是连接字符串。

为了解决无法在clickonce包中更改配置文件而没有为每个客户端/环境构建一个包的构建过程的事实,我们提出了一个解决方案,允许您在其中放置app.config文件服务器部署文件夹,让应用程序在运行时访问它。

为此,我们创建了一个在app.xaml.cs OnStartup事件中初始化的静态类。

public static class DbConnectionString {     public static string ConnectionString {get;私人集; }     public static string ActivationPath {get;私人集; }

public static void Init()
{
    string dbContext = "myDbContext";
    string configFile = "App.config";
    ConnectionString = "";
    ActivationPath = "";

    ActivationArguments actArg = AppDomain.CurrentDomain.SetupInformation.ActivationArguments;
    if (actArg != null)
    {
        if (actArg.ActivationData != null)
        {
            try
            {
                var actData = actArg.ActivationData[0];
                var activationPath = Path.GetDirectoryName(new Uri(actData).LocalPath);
                var map = new System.Configuration.ExeConfigurationFileMap();
                map.ExeConfigFilename = Path.Combine(activationPath, configFile);
                var config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
                var connectionStringSection = config.ConnectionStrings;
                ConnectionString = connectionStringSection.ConnectionStrings[dbContext].ConnectionString;
                ActivationPath = activationPath;
            }
            catch (Exception)
            {

                ConnectionString = "";
                ActivationPath = "";
            }
        }
    }
}

}

在Publish / Options / Manifests下的Project设置中,勾选"允许URL参数传递给应用程序"

然后我使用静态类的ConnectionString属性,我需要一个连接字符串。除非您将应用程序部署为仅在线,否则不会设置它,因此我们默认使用dev / testing包中的app.config。

这有点令人费解,但效果很好,您只需要发布一次应用程序,并为每次安装之间的安装提供app.config。

它还设置属性ActivationPath,它是clickonce服务器安装目录的路径。

答案 1 :(得分:0)

这听起来像是朝着正确方向迈出的一步,与我几年来为WPF应用所做的一样,并且效果很好。

我们使用Team City构建解决方案,然后有多个后续构建步骤来处理ClickOnce发布,每个配置一步。每个配置都涉及启动使用Mage.exe的MSBuild文件。它将解决方案输出文件复制到临时目录,然后对诸如App.config之类的文件执行大量替换,并运行各种自定义MSBuild任务。

MSBuild项目文件包含ClickOnce下载URL等基本设置和环境覆盖。我们还必须对生成的清单本身进行一些hacky替换(然后重新签名),例如将特定文件标记为数据。