I'm working on a setup project. In a separate library project I created a custom installer by inheriting from System.Configuration.Install.Installer and added the generated .dll as a custom action.(Install step). I added an app.config file to the library project where I store a connection string which I need to make a connection to Sql Server.
Once I run the setup project, the custom installer doesn’t retrieve the connectionString stored in the app.config file.
Where can I store the connection string? Can a setup project have an app.config? Could somebody recommend a book on deployment/setup projects?
Thanks
UPDATE
Hi, Thanks. Based on the replies I've updated my code this is what I´m doing now:
-> In setup project, I added a custom action to the install step, selecting application folder and primary output(library project). -> Added an app.config to the library project and set its build action to "content". -> Added the library project content files to the setup project.
This way the app.config file appears in the install folder.
Within the install handler from my custom install class I do the following: (in this case I access the application settings)
string appPath = "";
appPath = Path.Combine(new DirectoryInfo(Context.Parameters["assemblypath"].ToString()).Parent.FullName, "App.config");
ExeConfigurationFil开发者_开发知识库eMap map = new ExeConfigurationFileMap();
map.ExeConfigFilename = appPath;
System.Configuration.Configuration c = null;
c = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
string result = c.AppSettings.Settings["test"].Value;
You can still reuse app.config if you insist on doing so, but you need to come up with your own way to parse it.
Here is the necesary steps for this workaround:
- Create your own mechanism to read the appSettings using System.Xml.XmlReader or whatever from the app.config file that will be copied into the Application Folder.
- Use your custom xml parser to extract the value and use it in your custom action.
- Mark App.config as Content in the Build Action property window (in the custom action project).
In the Setup Project, add Project Output in the Application Folder and choose Content Files instead of Primary output. You can verify that app.config is the output by invoking context menu and choosing Outputs for the Content Files from ... item.
After you've done this, you should have 2 outputs from the Custom Installer class library project (1 for Primary output and 1 for the Content Files).
Here is an example custom installer action that will launch whatever I have in my appSettings key called launch along with my replacement ConfigurationManager implementation:
using System;
using System.Configuration.Install;
using System.Xml;
using System.IO;
using System.Reflection;
using System.ComponentModel;
using System.Collections;
namespace ClassLibrary1
{
[RunInstaller(true)]
public partial class Installer1 : System.Configuration.Install.Installer
{
public Installer1()
{
InitializeComponent();
}
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Commit(IDictionary savedState)
{
base.Commit(savedState);
System.Diagnostics.Process.Start(ConfigurationManager.AppSettings["launch"]);
}
}
public class ConfigurationManager
{
private static AppSetting _appSettings = new AppSetting();
public static AppSetting AppSettings
{
get { return _appSettings; }
}
public class AppSetting
{
public string this[string key]
{
get
{
var path = Path.Combine(Path.GetDirectoryName(Assembly.GetCallingAssembly().Location), "app.config");
var xpath = string.Format("/configuration/appSettings/add[@key='{0}']", key);
var doc = new XmlDocument();
doc.Load(path);
var node = doc.SelectSingleNode(xpath);
if (node == null)
return string.Empty;
return node.Attributes["value"].Value;
}
}
}
}
}
Instead of trying to parse the app.config
, I would suggest adding the configSource
attribute to your app.config
to externalize the connection strings, something like:
<connectionStrings configSource="connections.config" />
Then get the setup script to generate the entire connections.config
file, similar to:
<connectionStrings>
<clear />
<add name="...." connectionString="...." providerName="...." />
</connectionStrings>
Make sure you use .config
as the extension of your file so it cannot be served to the browser if someone guesses the file name.
精彩评论