覆盖嵌入到MSI中的app.config设置?

时间:2022-09-23 14:11:40

I have a .NET solution with an installer project that generates an MSI. One of the projects installed by the MSI contains an App.Config file. It appears that the values of that config file are embedded into the MSI at compile time. Is there a way to override them at runtime?

我有一个。net解决方案,安装程序项目生成MSI。MSI安装的一个项目包含一个App.Config文件。在编译时,配置文件的值似乎被嵌入到MSI中。有办法在运行时覆盖它们吗?

For instance, the App.Config I'm working with sets the URL of a web service that the installer talks to. Is it possible to override this URL at runtime, so that I don't have to recompile the MSI if the URL changes?

例如,我正在使用的App.Config设置了安装程序与之对话的web服务的URL。是否可以在运行时重写此URL,以便在URL更改时不必重新编译MSI ?

Update: I guess what I'm asking is, can I copy an App.Config file, with a certain name, into my installer directory such that it will override, at runtime, the settings embedded into the MSI?

更新:我猜我想问的是,我能否将一个带有某个名称的App.Config文件复制到我的安装程序目录中,这样在运行时,它将覆盖嵌入到MSI中的设置?

I know I can redesign the code to check for overrides in other places, like the registry or a well-known text file location, but my immediate need is to resolve this issue without a recompile. (There are lots of install disks in the hands of users)

我知道我可以重新设计代码来检查其他地方的重写,比如注册表或一个众所周知的文本文件位置,但是我现在需要的是在不重新编译的情况下解决这个问题。(用户手中有很多安装盘)

3 个解决方案

#1


1  

We had a similar challenge when developing the application that I am currently working on. We wanted to be able to have a fresh installation start up the first time pre-configured with settings ported from another machine, or a configuration utility. I honestly don't know how good our solution is in the grand scheme, but I can tell you what we did, which is working for us, for now.

在开发我目前正在开发的应用程序时,我们遇到了类似的挑战。我们希望能够在第一次预先配置来自另一台机器或配置实用程序的设置时启动一个新的安装。老实说,我不知道我们的解决方案在大计划中有多好,但我可以告诉你我们做了什么,现在对我们有用。

In our case, many of these settings end up in the app.config file, which it is not recommended to try and manipulate from outside of the application itself. It can be done, but it's dangerous in several subtle ways. If this were not the case, the best option would probably be to add a "custom action" for the setup project that would inject the data into the file, database, or whatever we were using to store our settings. A starting point for how to do that can be found in MSDN.

在我们的例子中,这些设置中有许多都以app.config文件结尾,不建议在应用程序本身之外尝试和操作该文件。这是可以做到的,但在一些微妙的方面却是危险的。如果不是这样,最好的选择可能是为安装项目添加一个“自定义操作”,将数据注入到文件、数据库或我们用来存储设置的任何东西。如何做到这一点,可以在MSDN中找到一个起点。

But since that wasn't an option, we decided that probably the simplest way to get data through the install to the app, without building it into the install package, would be to use a "ride-along" file. This is a file that your install knows about, but which is not build into the .MSI. It must simply be in a known location relative to the .MSI when you install. You tell the setup project what that file is, where it should be, and where to put it. Then your application can check for its existence on startup, and process whatever it finds there. In your case this would be a URL setting override. Then the app can delete the file, so it doesn't get loaded every time it starts.

但由于这不是一个选项,我们决定,在不将数据构建到安装包的情况下,通过应用程序的安装获取数据的最简单方法可能是使用“共乘”文件。这是一个您的安装知道的文件,但不是构建到. msi中。安装时,它必须位于相对于. msi的已知位置。告诉setup项目这个文件是什么,它应该在哪里,放在哪里。然后应用程序可以在启动时检查它是否存在,并处理它在那里找到的任何东西。在您的情况下,这将是一个URL设置覆盖。然后应用程序可以删除文件,这样每次启动时就不会加载。

In the install project, the file will need to have a few properties set to ensure it works properly with the style of package that a VS Setup project produces. Make sure you set these, or you could get errors or other weird behaviors when the ride-along file is excluded because it's not needed.

在安装项目中,文件需要设置一些属性,以确保它与VS安装项目生成的包的样式一致。确保您设置了这些,否则在不需要这个共乘文件时,您可能会得到错误或其他奇怪的行为。

  • Condition: NOT REINSTALL
  • 条件:不重新安装
  • PacakgeAs: vsdpaLoose
  • PacakgeAs:vsdpaLoose
  • Vital: False
  • 重要:假

We call our file AutoImport.Settings.xml. This is a custom XML file that stores any data that we want to be able to initialize our app with when it is installed. It follows the same format that we use when we manually export/import configurations from the application at run-time, and uses the same mechanism. It just does it automatically on start-up, if it finds the file there. This allows us to configure one "prototype" machine with all the network-specific settings we want it to have, export those settings, and then send along that import file for automatic loading with any other installs we do in that network environment.

我们调用文件AutoImport.Settings.xml。这是一个定制的XML文件,它存储我们希望在安装应用程序时使用的任何数据。它遵循我们在运行时手动从应用程序导出/导入配置时使用的格式,并使用相同的机制。如果在启动时找到文件,它会自动执行。这允许我们配置一台“原型”机器,使用我们希望它具有的所有特定于网络的设置,导出这些设置,然后发送那个导入文件,以便与我们在该网络环境中所做的任何其他安装一起自动加载。

As I said, it feels like there should be a "better" way. The only ones we could come up with meant departing from the app.config and user.config mechanisms, which do have their benefits. So in the end we decided this was the lowest-friction alternative that fully addressed our needs.

就像我说的,感觉应该有更好的方法。我们唯一能想到的就是离开app.config和user。配置机制也有其优点。所以最后我们决定这是最低摩擦的选择完全满足了我们的需求。

#2


0  

If you need the installer to talk to a web service, where are you going to store the URL, if not in the installer itself?

如果您需要安装程序与web服务对话,那么如果不是在安装程序本身中,您将在哪里存储URL ?

If you have a well-known place where to look for the URL (a "constant" URL, database, file share etc.), you could include its address in the installer. Otherwise there is just no place to get the URL from...

如果您有一个可以查找URL的知名位置(“常量”URL、数据库、文件共享等),您可以在安装程序中包含它的地址。否则就没有地方可以从…

#3


0  

If you expose the url as a public property (i.e. any property in the Proeprties table that is all in capitals is considered public - i don't know if you have this level of control in an installer project in VS), then you can set it from the command line when you run the MSI. This is not a good long term solution for your particular problem though - maybe a better idea is to make an initial connection to a known address that is not going to change, and it can return the current address of the real web service you want to talk to.

如果你公开的url作为公共财产(即Proeprties表中的任何属性都是在首都被认为是公众——我不知道你有这种级别的控制在一个安装程序项目在VS),然后你就可以把它从命令行运行MSI时。这不是一个好的长期的解决方案为您的特定问题尽管——也许是一个更好的主意是让一个初始连接到一个已知的地址不会改变,它可以返回当前地址你想跟真正的web服务。

#1


1  

We had a similar challenge when developing the application that I am currently working on. We wanted to be able to have a fresh installation start up the first time pre-configured with settings ported from another machine, or a configuration utility. I honestly don't know how good our solution is in the grand scheme, but I can tell you what we did, which is working for us, for now.

在开发我目前正在开发的应用程序时,我们遇到了类似的挑战。我们希望能够在第一次预先配置来自另一台机器或配置实用程序的设置时启动一个新的安装。老实说,我不知道我们的解决方案在大计划中有多好,但我可以告诉你我们做了什么,现在对我们有用。

In our case, many of these settings end up in the app.config file, which it is not recommended to try and manipulate from outside of the application itself. It can be done, but it's dangerous in several subtle ways. If this were not the case, the best option would probably be to add a "custom action" for the setup project that would inject the data into the file, database, or whatever we were using to store our settings. A starting point for how to do that can be found in MSDN.

在我们的例子中,这些设置中有许多都以app.config文件结尾,不建议在应用程序本身之外尝试和操作该文件。这是可以做到的,但在一些微妙的方面却是危险的。如果不是这样,最好的选择可能是为安装项目添加一个“自定义操作”,将数据注入到文件、数据库或我们用来存储设置的任何东西。如何做到这一点,可以在MSDN中找到一个起点。

But since that wasn't an option, we decided that probably the simplest way to get data through the install to the app, without building it into the install package, would be to use a "ride-along" file. This is a file that your install knows about, but which is not build into the .MSI. It must simply be in a known location relative to the .MSI when you install. You tell the setup project what that file is, where it should be, and where to put it. Then your application can check for its existence on startup, and process whatever it finds there. In your case this would be a URL setting override. Then the app can delete the file, so it doesn't get loaded every time it starts.

但由于这不是一个选项,我们决定,在不将数据构建到安装包的情况下,通过应用程序的安装获取数据的最简单方法可能是使用“共乘”文件。这是一个您的安装知道的文件,但不是构建到. msi中。安装时,它必须位于相对于. msi的已知位置。告诉setup项目这个文件是什么,它应该在哪里,放在哪里。然后应用程序可以在启动时检查它是否存在,并处理它在那里找到的任何东西。在您的情况下,这将是一个URL设置覆盖。然后应用程序可以删除文件,这样每次启动时就不会加载。

In the install project, the file will need to have a few properties set to ensure it works properly with the style of package that a VS Setup project produces. Make sure you set these, or you could get errors or other weird behaviors when the ride-along file is excluded because it's not needed.

在安装项目中,文件需要设置一些属性,以确保它与VS安装项目生成的包的样式一致。确保您设置了这些,否则在不需要这个共乘文件时,您可能会得到错误或其他奇怪的行为。

  • Condition: NOT REINSTALL
  • 条件:不重新安装
  • PacakgeAs: vsdpaLoose
  • PacakgeAs:vsdpaLoose
  • Vital: False
  • 重要:假

We call our file AutoImport.Settings.xml. This is a custom XML file that stores any data that we want to be able to initialize our app with when it is installed. It follows the same format that we use when we manually export/import configurations from the application at run-time, and uses the same mechanism. It just does it automatically on start-up, if it finds the file there. This allows us to configure one "prototype" machine with all the network-specific settings we want it to have, export those settings, and then send along that import file for automatic loading with any other installs we do in that network environment.

我们调用文件AutoImport.Settings.xml。这是一个定制的XML文件,它存储我们希望在安装应用程序时使用的任何数据。它遵循我们在运行时手动从应用程序导出/导入配置时使用的格式,并使用相同的机制。如果在启动时找到文件,它会自动执行。这允许我们配置一台“原型”机器,使用我们希望它具有的所有特定于网络的设置,导出这些设置,然后发送那个导入文件,以便与我们在该网络环境中所做的任何其他安装一起自动加载。

As I said, it feels like there should be a "better" way. The only ones we could come up with meant departing from the app.config and user.config mechanisms, which do have their benefits. So in the end we decided this was the lowest-friction alternative that fully addressed our needs.

就像我说的,感觉应该有更好的方法。我们唯一能想到的就是离开app.config和user。配置机制也有其优点。所以最后我们决定这是最低摩擦的选择完全满足了我们的需求。

#2


0  

If you need the installer to talk to a web service, where are you going to store the URL, if not in the installer itself?

如果您需要安装程序与web服务对话,那么如果不是在安装程序本身中,您将在哪里存储URL ?

If you have a well-known place where to look for the URL (a "constant" URL, database, file share etc.), you could include its address in the installer. Otherwise there is just no place to get the URL from...

如果您有一个可以查找URL的知名位置(“常量”URL、数据库、文件共享等),您可以在安装程序中包含它的地址。否则就没有地方可以从…

#3


0  

If you expose the url as a public property (i.e. any property in the Proeprties table that is all in capitals is considered public - i don't know if you have this level of control in an installer project in VS), then you can set it from the command line when you run the MSI. This is not a good long term solution for your particular problem though - maybe a better idea is to make an initial connection to a known address that is not going to change, and it can return the current address of the real web service you want to talk to.

如果你公开的url作为公共财产(即Proeprties表中的任何属性都是在首都被认为是公众——我不知道你有这种级别的控制在一个安装程序项目在VS),然后你就可以把它从命令行运行MSI时。这不是一个好的长期的解决方案为您的特定问题尽管——也许是一个更好的主意是让一个初始连接到一个已知的地址不会改变,它可以返回当前地址你想跟真正的web服务。