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?
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?
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?
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 d开发者_如何学编程isks in the hands of users)
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.
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.
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.
- Condition: NOT REINSTALL
- 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.
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.
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?
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...
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.
精彩评论