我目前正在尝试修改我的Wix(V3.5)安装程序,以编辑我想要安装的.NET应用程序的Web.config设置。这对于普通的ASP.NET应用程序来说很好,但现在我试图将我的Wix设置项目应用到Entity Framework .NET应用程序,正如您所知,它具有更复杂的连接字符串设置,模型.csdl和.ssdl设置。 / p>
因此,如果我的web.config连接字符串设置看起来像这样:(其中[DBSERVER]& [DBNAME]是从对话框中恢复的属性)
<connectionStrings>
<add name="SSITacticalSolutionEntities" connectionString="metadata=res://*/Model.TacticalSolutionModel.csdl|res://*/Model.TacticalSolutionModel.ssdl|res://*/Model.TacticalSolutionModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=sd-sql2008r2;Initial Catalog=SsiTacticalSolution1.2.4;Integrated Security=True;MultipleActiveResultSets=True" />
</connectionStrings>
我在我的Product.Wsx文件中编辑我的Web.config,其中包含以下内容:
<util:XmlFile Id="ModifyConnectionString" Action="setValue" Permanent="yes" File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/connectionStrings/add[\[]@name='!(loc.EntityName)'[\]]" Name="connectionString"
Value="Data Source=[DBSERVER];Initial Catalog=[DBNAME];Integrated Security=true;providerName=System.Data.EntityClient;MultipleActiveResultSets=True"" Sequence="5"/>
我得到一个像这样的连接字符串:
<connectionStrings>
<add name="SSITacticalSolutionEntities" connectionString="Data Source=sd-sql2008r2;Initial Catalog=SsiTacticalSolution1.2.4;Integrated Security=true;providerName=System.Data.EntityClient;MultipleActiveResultSets=True""/>
</connectionStrings>
当然这是有道理的,因为我要求它用我在值中定义的内容替换当前的连接字符串属性。
但我真正需要的是编辑我的连接字符串的特定部分并留下余数(我可以在这里使用某种替换操作),即。保留我的所有模型设置,并根据需要更换数据库服务器和名称等。我以前使用Visual Studio安装程序执行此操作没有问题,并且它非常易于使用。
所以我的问题是可以使用util.XMLFile或者util:XmlConfig来完成吗?我没有运气就试过了。
或者这不可能与util.XMLFile一起使用,我是否必须在CustomAction中执行此操作? 任何想法都会有很大帮助,提前谢谢......
答案 0 :(得分:8)
我最终得到了这个工作,最后我没有对这个特定设置使用自定义操作,我使用在我的本地化文件中设置的变量。
我这样做是因为它会是开发人员,而不是那个知道模型名称和实体名称的用户(不是用户通过安装对话框,他们不会知道这个信息),所以我有一个本地化文件它的不同属性,如产品名称等,所以我添加了一个模型名称,并为此命名。我从用户输入的对话框中获得的所有其他内容:即数据库名称,虚拟目录,模拟用户等......
如果它对任何人都有帮助,这就是我最终为我的web.config提出的内容;这是我的product.wxs中处理此问题的部分。正如您所看到的,我在顶部有一个连接字符串属性,并在我的本地化文件中设置了loc.ModelName的占位符:
<Property Id="CONNECTION_STRING"
Value="metadata=res://*/Model.!(loc.ModelName).csdl|res://*/Model.!(loc.ModelName).ssdl|res://*/Model.!(loc.ModelName).msl;provider=System.Data.SqlClient;provider connection string=""/>
<!-- The root of the installer. -->
<Directory Id='TARGETDIR' Name='SourceDir'>
<!-- Install into the inetpub/wwwroot directory -->
<Directory Id="IISMain" Name='inetpub'>
<Directory Id="WWWMain" Name='wwwroot' ComponentGuidGenerationSeed='C38ED13E-E1E3-40DB-B1FA-39400C6B2BC4'>
<Directory Id='INSTALLLOCATION' Name="!(loc.ProductName)">
<!-- The component to define the Virtual Directory.-->
<Component Id="WebVirtualDirComponent"
Guid="D814F88F-6E0C-4365-A411-2F9807522C3D">
<!-- WebVirtualDir: The virtual directory we are installing. -->
<!-- Alias: Alias attribute is the name that we will see in IIS.-->
<!-- Directory: The Directory attribute is the "Physical Path" property in
IIS and needs to tie to the ID specified above as the install location. -->
<!-- WebSite: The WebSite attribute ties to a <WebSite> element in the
setup file(see below). As this is an example of installing into the
"Default Web Site" so that element is not under a component.-->
<iis:WebVirtualDir Id="VDir" Alias="[VIRTUALDIRECTORYVALUE]"
Directory="INSTALLLOCATION"
WebSite="DefaultWebSite">
<!-- This turns the Virtual Directory into a web application. -->
<iis:WebApplication Id="MyWebAppApplication"
Name="[VIRTUALDIRECTORYVALUE]" WebAppPool="AppPool"/>
<iis:WebDirProperties Id="WebSite_Properties" AnonymousAccess="no"
WindowsAuthentication="yes" DefaultDocuments="!(loc.DefaultDocument)"
Script="yes" Read="yes" />
</iis:WebVirtualDir>
<CreateFolder/>
<RemoveFolder Id= "GuidFolders" On= "uninstall"/>
</Component>
<!-- Components - this decides what we want to incude in our install
Here we will alter our web.config for Impersonation , debug to false and connection string. -->
<Component Id="Web.config" Guid="2ED81B77-F153-4003-9006-4770D789D4B6">
<!--install our web.config file , this isnt part of our initial MSBUILD-->
<File Id="Web.config" Name="Web.config" Source="$(var.SolutionDir)!(loc.WebApplicationProjectName)\Web.config" DiskId="1" KeyPath="yes" />
<!--Modify our web.config - here we need to add Identity impersonation , changes session settings , add connection string settings and set debug setting-->
<!--Ensure that the identity setting exists-->
<util:XmlFile Id="system.webidentity"
File="[INSTALLLOCATION]Web.config"
Action="createElement"
ElementPath="/configuration/system.web"
Name="identity"
SelectionLanguage="XPath"
Sequence="1" />
<util:XmlFile Id="system.webIdentityAttribute"
Action="setValue"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/system.web/identity"
Name="impersonate"
Value="true"
SelectionLanguage="XPath"
Sequence="2" />
<util:XmlFile Id="system.webIdentityAttribute2"
Action="setValue"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/system.web/identity"
Name="password"
Value="[IMPERSONATIONUSERPASSWORD]"
SelectionLanguage="XPath"
Sequence="3" />
<util:XmlFile Id="system.webIdentityAttribute3"
Action="setValue"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/system.web/identity"
Name="userName"
Value="[IMPERSONATIONUSER]"
SelectionLanguage="XPath"
Sequence="4" />
<util:XmlFile Id="ModifyConnectionString"
Action="setValue"
Permanent="yes"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/connectionStrings/add[\[]@name='!(loc.EntityName)'[\]]"
Name="connectionString"
Value="[CONNECTION_STRING]Data Source=[DBSERVER];Initial Catalog=[DBNAME];Integrated Security=True;MultipleActiveResultSets=True""
SelectionLanguage="XPath"
Sequence="5"/>
<!--<authentication mode="Forms">-->
<util:XmlFile Id="AuthenticationModeWindows"
Action="setValue"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/system.web/authentication"
Name="mode"
Value="Windows"
Sequence="6" />
<!--Switch off debug-->
<util:XmlConfig Sequence="7"
Id="SwitchOffDebug"
File="[INSTALLLOCATION]\web.config"
Action="create" On="install"
Node="value"
ElementPath="/configuration/system.web/compilation"
Name="debug"
Value="false" />
<!--Session configuration <sessionState mode="InProc" timeout="15" />-->
<util:XmlFile Id="system.websessionState"
File="[INSTALLLOCATION]Web.config"
Action="createElement"
ElementPath="/configuration/system.web"
Name="sessionState"
Sequence="8" />
<util:XmlFile Id="system.websessionStateAttribute"
Action="setValue"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/system.web/sessionState"
Name="mode" Value="InProc"
Sequence="9" />
<util:XmlFile Id="system.websessionStateAttribute2"
Action="setValue"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/system.web/sessionState"
Name="timeout"
Value="15"
Sequence="10" />
<util:XmlFile Id="system.websessionStateAttribute3"
Action="setValue"
File="[INSTALLLOCATION]Web.config"
ElementPath="/configuration/system.web/sessionState"
Name="cookieName"
Value="[VIRTUALDIRECTORYVALUE]"
Sequence="11" />
</Component>
<iis:WebSite Id='DefaultWebSite'
Description='Default Web Site'
Directory='INSTALLLOCATION' SiteId ='[WEBSITEVALUE]' >
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
<iis:WebAppPool Id="AppPool" Name="[APPPOOLVALUE]" />
<CustomAction Id="MapVirtualDirectory" Directory="INSTALLLOCATION" Return="asyncNoWait"
ExeCommand='[ASPNETREGIIS] -norestart -s "W3SVC/[WEBSITEVALUE]/ROOT/[VIRTUALDIRECTORYVALUE]"' />
<InstallExecuteSequence>
<Custom Action="MapVirtualDirectory" After="InstallFinalize" >ASPNETREGIIS AND NOT Installed</Custom>
</InstallExecuteSequence>
<CustomAction Id="GetIISWebSites" BinaryKey="IisManager" DllEntry="GetWebSites" Execute="immediate" Return="check" />
<CustomAction Id="GetIISAppPools" BinaryKey="IisManager" DllEntry="GetAppPools" Execute="immediate" Return="check" />
<InstallUISequence>
<Custom Action="GetIISWebSites" After="CostFinalize" Overridable="yes">NOT Installed</Custom>
<Custom Action="GetIISAppPools" After="CostFinalize" Overridable="yes">NOT Installed</Custom>
</InstallUISequence>
<Feature Id='ApplicationFeatures' Title="!(loc.ProductName)" Level='1'>
<ComponentRef Id='WebVirtualDirComponent' />
<ComponentGroupRef Id="MyWebApp_Project" />
<ComponentRef Id="Web.config" />
</Feature>
<!-- Specify UI -->
<Property Id="WIXUI_INSTALLDIR">INSTALLLOCATION</Property>
<UIRef Id="MyCustomUI"/>
这是我的本地化文件:
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="en-us" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<!--application settings-->
<String Id="LANG">1033</String>
<String Id="ProductName">MyTestWebSite</String>
<String Id="ProductVersion">1.0.0.0</String>
<String Id="CompanyName">MyCompanyName</String>
<String Id="DefaultDocument">Default.aspx</String>
<String Id="WebApplicationProjectName">MyWebApp</String>
<!--database settings-->
<String Id="EntityName">MyEntities</String>
<String Id="ModelName">MyModel</String>
</WixLocalization>
答案 1 :(得分:2)
XmlFile
和XmlConfig
都在原子级别写入属性。要获得所需的行为,您需要立即编写自定义操作来读取XML文件并将结果存储在Property
中。然后根据您的需要操作Property
(如果操作很复杂,您可能需要在自定义操作中执行此操作),然后让XmlFile
或XmlConfig
将整个操作值写回
通过允许XmlFile
和XmlConfig
执行繁重的处理和处理回滚以及所有这些内容,此方法将需要代码中最不复杂的自定义操作集。只需修改Property
幂等。