2

这是我的场景:

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

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

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

这意味着安装应用程序的好处是运行所需的安装程序很简单。然而,缺点是如果(何时)我需要创建一个新环境,我必须使用一组新的配置参数重新运行整个构建过程。

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

我最新的想法是我将构建过程拆分为只创建二进制文件。然后有一个单独的打包过程,该过程会提取适当的二进制文件、修补配置、使用 MAGE (重新)签名的清单等。

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

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

谢谢

4

2 回答 2

1

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

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

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

公共静态类 DbConnectionString { 公共静态字符串 ConnectionString { 获取;私人套装;} 公共静态字符串 ActivationPath { 获取;私人套装;}

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 = "";
            }
        }
    }
}

}

在发布/选项/清单下的项目设置中,勾选“允许将 URL 参数传递给应用程序”

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

这有点令人费解,但效果很好,您只需发布一次应用并为每次安装提供一个 app.config,在构建之间不会更改。

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

于 2014-06-27T12:41:55.830 回答
0

这听起来像是朝着正确方向迈出的一步,并且类似于我多年来为 WPF 应用程序所做的事情,而且效果很好。

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

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

于 2012-07-23T07:23:23.687 回答