问题
I need to create an address string in app.config as:
<client>
<endpoint address="http://ServerName/xxx/yyy.svc"
binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IClientIInfoService"
contract="DocuHealthLinkSvcRef.IClientIInfoService" name="BasicHttpBinding_IClientIInfoService" />
</client>
The ServerName
need to be entered by the user during installation.
For that i have created a new UI dialog in the Installer. I have also written an Installer.cs
class and overrided the install ()
as:
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
string targetDirectory = Context.Parameters["targetdir"];
string ServerName = Context.Parameters["ServerName"];
System.Diagnostics.Debugger.Break();
string exePath = string.Format("{0}myapp.exe", targetDirectory);
Configuration config = ConfigurationManager.OpenExeConfiguration(exePath);
config.AppSettings.Settings["ServerName"].Value = ServerName;
config.Save();
}
}
But how do i use this ServerName
in my app.config
to create the specified string.
I'm working on VS2010.
回答1:
Assuming you are using the full ServiceModel section group in the app.config
Essentially you follow these steps:
- Load ServiceModel config section
- Get Client Section
- Get ChannelEndpoint Element
- Change Address value by replacing string "ServerName" with entered value
- Set Address attribute to new value
Save config
public override void Install(System.Collections.IDictionary stateSaver) { base.Install(stateSaver); string targetDirectory = Context.Parameters["targetdir"]; string ServerName = Context.Parameters["ServerName"]; System.Diagnostics.Debugger.Break(); string exePath = string.Format("{0}myapp.exe", targetDirectory); Configuration config = ConfigurationManager.OpenExeConfiguration(exePath); config.AppSettings.Settings["ServerName"].Value = ServerName; //Get ServiceModelSectionGroup from config ServiceModelSectionGroup group = ServiceModelSectionGroup.GetSectionGroup (config); //get the client section ClientSection clientSection = group.Client; //get the first endpoint ChannelEndpointElement channelEndpointElement = clientSection.Endpoints[0]; //get the address attribute and replace servername in the string. string address = channelEndpointElement.Address.ToString().Replace("ServerName", ServerName); //set the Address attribute to the new value channelEndpointElement.Address = new Uri(address); config.Save(); }
回答2:
You could use WiX (Windows Installer XML toolset) to build your MSI, in which case you can use the XmlFile utility tag to update the server name:
<util:XmlFile Id="UpdateServerName" File="[INSTALLLOCATION]AppName.exe.config" Action="setValue" ElementPath="/client/endpoint" Name="address" Value="http://[SERVERNAME]/xxx/yyy.svc" />
You can capture the server name during installation using a WixUI extension form.
Advantages of WiX: WiX is msbuild compliant (unlike .vdproj files), and gives you much finer-grained control over your installer, among other things
回答3:
At the end of the day, app.config
is xml
file. You can use Linq To XML or XPathNavigator to replace the address
attribute of endpoint
element.
Below code uses Linq to Xml
using System.Xml.Linq;
public override void Install(System.Collections.IDictionary stateSaver)
{
base.Install(stateSaver);
string targetDirectory = Context.Parameters["targetdir"];
string ServerName = Context.Parameters["ServerName"];
System.Diagnostics.Debugger.Break();
string configPath = string.Format("{0myapp.exe.config", targetDirectory);
XElement root = XElement.Load(configPath);
var endPointElements = root.Descendants("endpoint");
foreach(var element in endPointElements)
{
element.Attribute("address").Value = ServerName;
}
root.Save(configPath);
}
}
回答4:
Since you have a windows-installer tag, I assume you either have an MSI package, or can create one...
Then:
- You can create a public MSI property like ENDPOINTSERVER you require during installation.
- Add a custom action that modifies app.config to run after "InstallFinalize" with the value of ENDPOINTSERVER
A silent installation will be possible using:
msiexec /i app.msi ENDPOINTSERVER=www.MyServer.com /qb-
回答5:
try to use below two lines before saving the config file changes:
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("Section Name");
root.Save(configPath);
P.S: it doesn't update the solution item 'app.config', but the '.exe.config' one in the bin/ folder if you run it with F5.
来源:https://stackoverflow.com/questions/14135364/modifying-app-config-via-custom-msi-installer