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.
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();
}
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
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);
}
}
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-
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.