Using ClickOnce, I do not believe you can or should change files within the installation folder because it is read-only... Therefore, you have a choice: go with an MSI install and a custom install action to switch in the appropriate config file or build up some custom configuration elements to encapsulate your different environments.
In our application, we have done the latter. We have something like the following custom configuration section in our main app.config.
<myApp defaultEnvironmentName="prod">
<environments>
<add name="prod" title="Production" description="Full production environment" injectionContainers="prod">
...
<!-- Add custom elements the affect your environment -->
...
</add>
<add name="qa" title="Quality Assurance" description="Full production environment except running off our mock database" injectionContainers="prod qa">
...
<!-- Add custom elements the affect your environment -->
...
</add>
</environments>
</myApp>
... <!-- Other elements that are common to all environments --> ...
Then we use a run-time flag or command line argument to enable you to switch between environments easily. The value of the environment in use is stored in a user Settings file so that on subsequent use the application will load the last used environment.
When we need to access something that varies per environment we directly call upon the custom configuration section's CurrentEnvironment
property which utilised the above mentioned setting to work it out:
var title = MyAppSection.Configured.CurrentEnvironment.Title;
Note that here, MyAppSection.Configured
is just a singleton instance that loads based on ConfigurationManager.GetSection(...)
.
I realise the prospect of a boat-load of configuration code is the last thing you want but it will let you clearly define and isolate your environment variables within the config files.