c# installer project with external file - c#

I have created an application in which every installation is differed by the configuration file.
Currently the configuration file (settings.setting) is part of the installer itself.
Is there a way to create an installer without the settings.setting embedded inside it, so will have the setup.exe and a separate settings.setting file?
(So will have 1 installation build, and the installation will copy the setting file to the relevant location as done if it is part of the installation build)
Thanks,
Yoav

Maybe you should try to extract the config file to another file and link it from default config file.
MyApp.exe.config would containt a line like this:
<appSettings configSource="pathtoconfig\MyExternalAppSettings.config" />
Here's a good blog post on this subject.

Related

C# Console Application: Visual Studio Can Not Find the Config File

I see in Best practices for deploying passwords and other sensitive data to ASP.NET and Azure App Service that I can place my sensitive information in a separate file using this syntax:
<connectionStrings configSource="ConnectionStrings.config"></connectionStrings>
Being happy that configSource supports relative path and considering the fact that I am working on MAC, I ignored the file in git and I put the file in the upper directory: ../myconfig.config. Build was fine. I ran the Program.cs and bam!
Unable to open configSource file
'/Users/a/long/path/myProj/myProj/bin/Debug/../myconfig.config'.
So does it mean I have to put the path relative to the bin/Debug directory? I know that my config is already copied in bin directory with a different name. What baffles me is that why such a simple task (using another config file out of git) should be so complex. I have seen suggestions like running post-build commands to copy the config file. I thought it's too much for a simple inclusion of a config file.
I do not have a C# experience. I'm just trying to remove bunch of passwords from github.

create visual studio solution and include settings of the applicatioon

I am building a C# application. it has some parameters saved of a file named "settings.ini" .
Of course, I managed my application to read settings ,offer an interface for editing them and finally save them back to the ini file.
Would you please tell me how to include this setting file to the installation package (VS2008)
Thanks.
Instead of using an ini file, you should be using a .config file - that's the normal configuration option for .NET application with quite a lot of built in support.
You should be able to add an app.config file to your project from the new item screen in Visual Studio.
Take a look at Configuration Files on MSDN for more detail and the AppSettings class (this page includes some examples).

Can a Console Application reference its .exe.config if the .config is in another folder?

Here is the task I have been given at work. We have a Web Application for which I created a Console Application that can be executed by the Scheduled Tasks on a daily basis. The task I have be presented with is to discover if we can place the ConApp.exe and the ConApp.exe.config in two different directories (folders) in our application. We would like to place the .exe file in the bin folder with all the .dll's and place the .exe.config file in a central configurations folder. I have been looking around in the properties and such with in Visual Studio and I do not see any options that will allow me to specify to the ConApp.exe the location of the ConApp.exe.config.
Is there a way to place these two files in separate folders or do they need to be in the same folder and have the .exe.confing reference a central .config file?
Thanks, :)
You should be able to use ConfigurationManager.OpenExeConfiguration to do that. You can add a setting in the console application's config file that points out the path and filename to the config file, and pass that value to OpenExeConfiguration (granted that the console runs as an account that has read access to the location where the config file is stored).
Note that if your console app contains statements like ConfigurationManager.AppSettings["somekey"], these will need some rewriting so that they use the Configuration object returned by the OpenExeConfiguration method.
The automatic discovery of the .exe.config works only if the files are in the same folder. But you gave the answer yourself IMHO: have the .exe.config reference another .config file in the desired central location.
No, you cannot tell your app to look in another directory for its main app.config.
What you can do is externalize certain configuration sections to external files in another directory:
<configuration>
<appSettings configSource="config\appSettings.config" />
<connectionStrings configSource="config\connections.config" />
</configuration>
This works - even though in the Visual Studio designer there will be complaints about this - on any .NET configuration section (but not on section groups, e.g. you cannot externalize the entire <system.web> or <system.serviceModel> at once - you need to do it by their sub-elements.
So with help from Fredrik Mork I was able to figure out this solution. First of all when you create your Console Applications, DO NOT, create any setting in the projects properties window. This will create an app.config file in your project which I believe the executable will try to look for and crash if it doesn't find it. When you first create the Console Application and then Build it before writing any code. Visual Studio create the Debug folder with just the executable file and a few supporting files. I then placed this code in the "main" function:
Dim fileMap As ExeConfigurationFileMap = New ExeConfigurationFileMap()
fileMap.ExeConfigFilename = "....../AppName.config"
Dim externalConfig As Configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None)
Dim appS As AppSettingsSection = externalConfig.Sections("appSettings")
Dim reportURL As String = appS.Settings("URL").Value
Console.Writeline(reportURL)
In the 2nd line "fileMap.ExeConfigFilename = "....../AppName.exe.config" then "......" represent the full pathname to the config file and AppName is the name of your file. Now I also tried to copy the code from my original Console Application and run it but it still crashed. I think it is due to the .dlls that I am using which make calls to Stored Procedures on the database. I believe these dlls are looking for the .config file to be in the same folder since that is the way they were built. However, if you are careful when you begin writing your application you can utilize Web.config information like I did above.

Why doesn't app.config get added after installing from windows installer?

I have a Windows application developed using Visual Studio 2008 (C#).
It has a app.config file, where various configuration related information are kept. After creating an installer for the project and installing it, there are no app.config file being copied to the installed directory. However, the functionalities that rely on settings in this file seem to work.
Now one of these settings is a database connection string, which obviously needs changing when installed in a different PC. My question is, how to have the app.config file available with the Setup file so that it can be configured later?
The app.config is copied/renamed <assembly name>.config as part of the compilation process, and placed in the bin directory. If you're using a Visual Studio Installer project (blech!), then it should have picked it up also and included it in the installer, IIRC.
(In response to your comment to both answers)
You can't keep using it as "app.config". The .NET config system searches for the configuration file whose name is the same as the entry assembly. If you renamed the file back to "app.config", then the configuration classes would stop working.
Your app.config file gets renamed on compilation, with the name of the binary. I.e. if your binary is myapp.exe then your app.config will be renamed to either myapp.config or myapp.exe.config.
This is the file that you should add to the setup package in order to use it on deployment for configuration.

Multiple .NET Configuration Files and Setup Project Problem

In order to handle settings for different deployment targets, I moved application settings from app.config to its own file and included that file in app.config via configSource. I also created a settings file for each target.Here is an illustration:
Project A
app.config (references settings.config)
settings.config
settings.Release.config
settings.Debug.config
During post-build, I copy the appropriate settings.{configuration}.config to the output directory. This is working fine so far and I can see settings.config file in the project output directory containing settings for the current build configuration: Release, Debug, etc.
However, I am having a problem with the setup project that I have for this project (Project A). Initially, it was not including settings.config file. So I set the build action for settings.config file as Content and I added content files from Project A to the setup project. This ensured that settings.config file was included in the setup. However, since the setup project appears to be picking settings.config file from the project directory instead of the output directory, settings.config file included in the setup is not what it should be. I want the one from the output directory to be included in the setup program since that one is the correct one for the current build configuration. I tried the following:
Added settings.config as a file to the setup project. However, it seems like I can only specify absolute path. So when I add it from the output directory of a particular build configuration (..bin\debug\settings.config), it does not work in other build configuration since (..bin\debug\settings.config) does exist in the directory specified. I looked into using relative paths or dynamic paths in the setup project where the build configuration could be specifed as part of the path but I could not find anything.
I considered using pre-build event to actually modify settings.config file in the project directory and then have it copied over the output directory by setting its 'Copy to Output Directory' to copy always or copy if newer. This should ensure that the appropriate settings.config is copied to the output directory just like the post-build based solution and should also ensure that the contents of settings.config file is updated before the setup project includes it. However, I don't like this solution because I would have to make sure settings.config file is writeable before I can make any changes since it is source controlled. If it is readonly, then I need to flip it to writeable, make changes, and then set it to readonly again. It is adding extra complexity.
I was wondering if anyone has a better idea or knows a setup project trick that allows me to include settings.config file appropriate for the current build configuration in the setup program.
Thanks
If I had to approach this problem, I'd start by asking the following question:
Why does settings.config have to be under source code control if settings.Debug.config or settings.Release.config provide the same information?
The answer, if I read your question correctly, is because you needed to force a settings.config file to appear as part of the build output. I'm guessing this is because your setup project is using the built in "Primary output" choice.
What you can do instead is add that file to your setup project as an explicit file reference. Right-click on the setup project and choose add / file, then select the file you want to include. As you'll notice (unless it's been fixed in VS2008 which sadly I'm not yet allowed to use at work), there is a very annoying limitation placed on manually added files - there is no way to make the path build configuration aware. You can work around that by copying the appropriate settings.config file to a common location (e.g. bin/Configuration) and picking it up from there. This does limit you to building Debug and Release versions sequentially, rather than in parallel, but for many this probably isn't a huge problem.
If you aren't required to use VS setup projects, I strongly encourage you to take a look at WiX (Windows Installer XML - see http://wix.sourceforge.net/ for more information). That will easily allow you to accomplish what is necessary, although if you are unfamiliar with the internal workings of Microsoft Installer the initial learning curve could be a little steep. Microsoft use WiX themselves for some pretty significant setup tasks (e.g. Office 2007, SQL Server, etc.). It had been hoped that WiX would become part of Visual Studio (for VS 2010), but sadly that is no longer the case.
I decided to go about achieving the same result (being able to have different configuration settings for different target environments) in a different way. So here is how I implemented it and it is working great. I read some of the posts here at SO about XmlMassUpdate task from MSBuild Community Tasks and decided to utilize it. Here is what I did:
1) For each project that needs to have different settings depending on the target environment, I added an xml file called app.config.substitutions.xml or web.config.substitutions.xml to the project. So, the project looked like
Project A
app.config
app.config.substitutions.xml
app.config.substitutions.xml file has the settings substitutions that XmlMassUpdate will process and apply to app.config file. Below is a sample substitution file that I use:
<configuration xmlns:xmu="urn:msbuildcommunitytasks-xmlmassupdate">
<substitutions>
<Development>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="DevValue" />
</appSettings>
</Development>
<Test>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="TestValue" />
</appSettings>
</Test>
<Release>
<appSettings>
<add xmu:key="key" key="SomeSetting" value="ReleaseValue" />
</appSettings>
</Release>
</substitutions>
</configuration>
For details on how to specify substitutions, take a look at the documentation for XmlMassUpdate or just do a search on it.
2) Now I need to run XmlMassUpdate as part of build automation (TeamBuild/MSBuild). So in BeforeCompile in TeamBuild build definition file (basically a proj file), I added the following to run XmlMassUpdate on config files that have a corresponding .substitution.xml file
<PropertyGroup>
<SubstitutionFileExtension>.substitutions.xml</SubstitutionFileExtension>
<TargetEnvironment>Test</TargetEnvironment>
</PropertyGroup>
<Target Name="BeforeCompile" Condition="'$(IsDesktopBuild)'!='true'">
<CreateItem Include="$(SolutionRoot)\**\app.config;$(SolutionRoot)\**\web.config">
<Output ItemName="ConfigurationFiles" TaskParameter="Include"/>
</CreateItem>
<CreateItem Include="#(ConfigurationFiles)" Condition="Exists('%(FullPath)$(SubstitutionFileExtension)')">
<Output ItemName="ConfigFilesWithSubstitutions" TaskParameter="Include"/>
</CreateItem>
<Message Text="Updating configuration files with deployment target specific settings..."/>
<XmlMassUpdate
ContentFile="%(ConfigFilesWithSubstitutions.FullPath)"
SubstitutionsFile="%(ConfigFilesWithSubstitutions.FullPath)$(SubstitutionFileExtension)"
ContentRoot="/configuration"
SubstitutionsRoot="/configuration/substitutions/$(TargetEnvironment)"/>
</Target>
Note that config files are read-only during the build, I make sure to set them writeable before running this task. I actually have another custom MSBuild task that runs before XmlMassUpdate that handles common settings throughout all of the config files such as connection strings. That task makes the config files writeable. I also don't check modified config files back to the source control. They're (appropriate config file for the deployment target) included in the installer.

Categories