I have a wix project that installs a web site. One of the steps adds several xml tags to web.config file. Whenever adding xml tags WIX adds xmlns="" attribute which I don't want.
PluginSettings.wxi
<?xml version="1.0" encoding="utf-8"?>
<Include>
...
<?define PluginProbingPath="<probing privatePath="IntegrityChecker\bin\" />" ?>
</Include>
ConfigFiles.wxs
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<?include PluginSettings.wxi ?>
<Fragment>
<!-- WEB.CONFIG -->
<Component Id="Web.ConfigPortal" Guid="3ED81B77-F153-4003-9006-4770D789D4B7" Directory ="INSTALLDIR">
<CreateFolder/>
...
<util:XmlConfig Id = "AppConfigAddPlugin1" ElementPath = "//configuration/runtime/assemblyBinding" Action = "create" Node = "document"
On = "install" File = "[INSTALLDIR]web.config" Value = "$(var.PluginProbingPath)" Sequence = "1"/>
</Component>
</Fragment>
</Wix>
Which results in web.config having this after install:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
...
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-2.1.0.0" newVersion="2.1.0.0"/>
</dependentAssembly>
<probing xmlns="" privatePath="IntegrityChecker\bin\"/></assemblyBinding>
</runtime>
As you can see nowhere did I specify xmlns tag (which I DON"T want).
I've tried removing that attribute with additional tag but it doesn't work:
<util:XmlFile Id="AppConfigAddPlugin8" Action="deleteValue" Permanent="yes" File="[INSTALLDIR]web.config"
ElementPath="//configuration/runtime/assemblyBinding/probing" Name="xmlns" Sequence = "2"/>
what am I doing wrong?
The WIX XmlConfig extension uses MSXML to modify the XML file on the target computer. Specifically the attributes action="create" and node="document", results in this simplified sequence of MSXML calls:
selectSingleNode("//configuration/runtime/assemblyBinding")
Create new xml document from: <probing privatePath=\"IntegrityChecker\bin\" />
Get the top level document element
call appendChild() to append the new document element
The problem is the probing element has no name space, but the parent assemblyBinding element has the namespace "urn:schemas-microsoft-com:asm.v1". When MSXML adds the probing element, xmlns="" is added to reset the default namespace. Without xmlns="", the probing element inherits the "urn:schemas-microsoft-com:asm.v1" namespace.
The article, MSXML inserted blank namespaces, describes this behaviour. Unfortunately this article (and others) recommend changing the call sequence to specify a default namespace when adding the probing element. Since this is WIX we can't easily change how WIX uses MSXML.
You could try adding a namespace to the probing element:
<?define PluginProbingPath="<probing xmlns="urn:schemas-microsoft-com:asm.v1" privatePath="IntegrityChecker\bin\" />" ?>
This will result in:
<probing xmlns="urn:schemas-microsoft-com:asm.v1" privatePath="IntegrityChecker\bin\" />
I'm not an expert on xml namespaces, but the effect of the explicit xmlns="urn:schemas-microsoft-com:asm.v1" should be benign in that the probing element will now have the same default namespace as its parent assemblyBinding. Whether this is a suitable work around depends on what is consuming the xml.
Related
I was trying to give a dynamic file name based on its version for WIX Component file as given below. But I would like to know how the dynamic file name will be picked up in this. Got some reference from some other WXS file but not clear how it is working. Even the file is still not working properly.
Tried this : File - icsharpcode.sharpziplibmarquee_w64.d.wxs
<?xml version='1.0' encoding='UTF-8'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:inin='http://www.inin.com/i3WixExtensions'>
<Fragment>
<DirectoryRef Id='IWP_MARQUEE'>
<Component Id='icsharpcode.sharpziplibmarquee_w64.d' Guid='YOUR-GUID' >
<File Name='icsharpcode.sharpziplib-w64r-$(ININExtension.TierVersionEicName).dll' ReadOnly='no' KeyPath='yes' Id='icsharpcode.sharpziplib-w64r.dll' Source="FindFirstInDirs(TIER_ROOT_EIC, pub/gen/bin/w64/ICSharpCode.SharpZipLib-w64r-$(ININExtension.TierVersionEicName).dll)" />
<?ifdef DebugBuild?>
<File Name='icsharpcode.sharpziplib-w64d-$(ININExtension.TierVersionEicName).dll' ReadOnly='no' Id='icsharpcode.sharpziplib-w64d.dll' Source="FindFirstInDirs(TIER_ROOT_EIC, pub/gen/bin/w64/ICSharpCode.SharpZipLib-w64d-$(ININExtension.TierVersionEicName).dll)" />
<?else ?>
<File Name='icsharpcode.sharpziplib-w64r-$(ININExtension.TierVersionEicName).pdb' ReadOnly='no' Id='icsharpcode.sharpziplib-w64r.pdb' Source="FindFirstInDirs(TIER_ROOT_EIC, pub/gen/bin/w64/ICSharpCode.SharpZipLib-w64r-$(ININExtension.TierVersionEicName).pdb)" />
<?endif ?>
</Component>
</DirectoryRef>
</Fragment>
</Wix>
Must read files like ICSharpCode.SharpZipLib-w64r-23-1.dll, ICSharpCode.SharpZipLib-w64d-23-1.dll, ICSharpCode.SharpZipLib-w64r-23-1.pdb. Where 23-1 is 2023R1 (dynamically updating based on release version)
I am working on a web application. the Web.config file is set to NeverOverwrite (=yes) in its initial installation. Now i need to add DBproviderfactories like below. Can i add this entire block using XmlFile in a patch.msp? I do not want to write a custom action. All I need is to add this block in the web.config. Any suggestion here is appreciated.
<system.data>
<DbProviderFactories>
<!-- Remove in case this is already defined in machine.config -->
<remove invariant="Oracle.ManagedDataAccess.Client" />
<add name="Oracle Data Provider for .NET" invariant="Oracle.ManagedDataAccess.Client" description="Oracle Data Provider for .NET, Managed Driver" type="Oracle.ManagedDataAccess.Client.OracleClientFactory, Oracle.ManagedDataAccess, Version=4.122.19.1, Culture=neutral, PublicKeyToken=89b483f429c47342" />
</DbProviderFactories>
</system.data>
Sample: Maybe try this:
https://github.com/glytzhkof/WiXUpdateXmlFile
Below is the gist of it - please use the sample above for testing. The markup below is just for illustration.
Set the XML file both permanent and never overwrite.
See inline instructions in the sample above for testing.
Check what happens on uninstall - this markup will remove the entries it added.
<!-- Set app.config permanent and never overwrite to yes -->
<Component Feature="ProductFeature" NeverOverwrite="yes" Permanent="yes">
<File Source="app.config" />
</Component>
<!-- The XML update -->
<!-- Use a NEW GUID here, do not go live with this one -->
<Component Id="XmlFileUpdate" Guid="{00000000-0000-0000-0000-7405EED51B57}" Feature='ProductFeature'>
<!--Create New Element-->
<util:XmlFile Id='XmlSettings1' File='[INSTALLFOLDER]app.config' Action='createElement' Name='MyConfig' ElementPath='//configuration' Sequence='1' />
<!--Set New Value-->
<util:XmlFile Id='XmlSettings2' File='[INSTALLFOLDER]app.config' Action='setValue' Name='newVersion' Value='6.6.8' ElementPath='//configuration/MyConfig' Sequence='2' />
<!--Set New Value-->
<util:XmlFile Id='XmlSettings3' File='[INSTALLFOLDER]app.config' Action='setValue' Name='Server' Value='Pusevov' ElementPath='//configuration/MyConfig' Sequence='3' />
<!--Update Existing Value, Existing Element-->
<util:XmlFile Id='XmlSettings4' File='[INSTALLFOLDER]app.config'
Action='setValue' Name='newVersion' Value='7.7.7' ElementPath='//configuration/ExistingConfig/bindingRedirect' Sequence='4' />
<CreateFolder />
</Component>
</Directory>
</Directory>
Link:
Added new application setting to app.config but MSI won't install it (doesn't overwrite)
I have create an installer by using WiXBaStd and customize the UI by edit the theme.xml. Besides, I have apply localization in bootstrapper and set the thm.wxl(en-us) Build Action to EmbeddedResource and thm.wxl(ja-jp) to None.
Then when I run the bootstrapper.exe in JP OS, the !(loc.ProductManufacturer) and !(loc.TransformsCode) always be EN-US but the UI display Japanese !.
If I reserve Build Action setting, set the thm.wxl(ja-jp) Build Action to EmbeddedResource and thm.wxl(en-us) to None.
Then when I run the bootstrapper.exe in JP OS, the !(loc.ProductManufacturer) and !(loc.TransformsCode) always be JA-JP ! and UI display Japanese also !.
How come the !(loc.ProductManufacturer) and !(loc.TransformsCode) not being change correctly in localization ? How to solve this problem ? Thanks.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:bal="http://schemas.microsoft.com/wix/BalExtension">
<?define ProductName = "Product A" ?>
<?define ProductManufacturer = "!(loc.ProductManufacturer)" ?>
<?define ProductUpgradeCode = "AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA" ?>
<Bundle Name="$(var.ProductName)" Version="$(var.BuildVersion)" Manufacturer="$(var.ProductManufacturer)" UpgradeCode="$(var.ProductUpgradeCode)">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense">
<bal:WixStandardBootstrapperApplication SuppressOptionsUI="yes" LicenseFile="Localization\1033\LICENSE.rtf" ThemeFile="Custom\CustomRtfTheme.xml" />
<Payload Name="1033\thm.wxl" SourceFile="Localization\1033\thm.wxl" />
<Payload Name="1041\thm.wxl" SourceFile="Localization\1041\thm.wxl" />
<Payload Name="1041\LICENSE.rtf" SourceFile="Localization\1041\LICENSE.rtf" />
</BootstrapperApplicationRef>
<Chain>
<MsiPackage Id="MSI_A" SourceFile="A.msi">
<MsiProperty Name="TRANSFORMS" Value="!(loc.TransformsCode)" />
</MsiPackage>
<MsiPackage Id="MSI_B" SourceFile="B.msi">
<MsiProperty Name="TRANSFORMS" Value="!(loc.TransformsCode)" />
</MsiPackage>
</Chain>
</Bundle>
</Wix>
<?xml version="1.0" encoding="utf-8"?>
<WixLocalization Culture="ja-jp" Language="1041" xmlns="http://schemas.microsoft.com/wix/2006/localization">
<String Id="TransformsCode">:ja-jp.mst</String>
<String Id="ProductManufacturer">XXXXXX</String>
<String Id="Caption">[WixBundleName] Setup</String>
<String Id="Title">[WixBundleName]</String>
</WixLocalization>
Localisation strings !(loc.whatever), and !(wix.variables) are applied by the binder at the end of the overall build process, after light.exe has completed linking the compiled objects.
This statement is a pre-processor statement so the payload is not available to be resolved at the pre-compile stage:
<?define ProductManufacturer = "!(loc.ProductManufacturer)" ?>
I have a website that I am installing for one of our internal products, and would like to know if there is a way to set up multiple <WebAddress/> blocks to be conditionally installed along with this one website?
Consider my basic website authoring below:
<Component
Id="WebsiteComp"
Directory="INSTALLDIR"
Guid="{702AF20D-F9F3-45A1-B966-890855904591}"
KeyPath="yes">
<iis:WebAppPool
Id="AppPool"
Name="OurSite"
ManagedPipelineMode="Integrated"
ManagedRuntimeVersion="v4.0"/>
<iis:WebSite
Id="Website"
Description="[WEBSITENAME]"
Directory="INSTALLDIR">
<iis:WebApplication
Id="WebApp"
Name="[WEBSITENAME]"
WebAppPool="AppPool"/>
<!-- if ENV = "DEV" -->
<iis:WebAddress
Id="DevHostHeader"
Header="dev.product.company.com"
Port="80"/>
<!-- if ENV = "QA" -->
<iis:WebAddress
Id="QaHostHeader"
Header="qa.product.company.com"
Port="80"/>
<iis:WebAddress
Id="QaHostHeader"
Header="product.qa1.company.com"
Port="80"/>
<!-- if ENV = "PROD" -->
<iis:WebAddress
Id="ProdHostHeader"
Header="prod.product.com"
Port="80"/>
</iis:WebSite>
</Component>
<Component/> is the most specific element that a condition can applied to. But in order to specify the condition there I have to duplicate all my web site auhtoring for each environment, correct?
Is there a way to author one version of the <WebAppPool/>, <WebSite/>, and <WebApplication/> and then have different versions and quantities (like QA in the above example) of <WebAddress/> inserted/chosen based on the condition of a propertie's value?
I really don't want to get into making multiple versions of the installer for a specific environment.
Thank you,
Zachary
You can approach the problem in a different way.
You can have a single WebAddress element, and the Header attribute will take the value of the property. Like this:
<iis:WebAddress Id="HostHeader" Header="[HOSTHEADER]" Port="80"/>
Now, based on the condition (production, DEV, QA) you set the property to the required value, for instance, qa.product.company.com for QA. Thus, you'll conditionally install the host header you need, and will keep a single WebAddress entry in the sources. Note, that Port attribute can accept the property values as well.
Well, I figured out how to do it without code duplication... pre-processor to the rescue!
Here's a simplified look at my "web services" directory:
ProductName.WebService.wxs
ProductName.DEV.WebAddress.wxi
ProductName.PROD.WebAddress.wx
ProductName.QA1.WebAddress.wxi
ProductName.WebService.wxs is as follows:
<Wix
xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<Fragment>
<iis:WebDirProperties .../>
<?foreach EnvID in DEV;PROD;QA1 ?>
<?define FullEnvID = "ProductName.$(var.EnvID)" ?>
<?if $(var.EnvID) = "DEV" ?>
<?define CompGUID = "{DFEAC94A-590E-4E92-9206-E574ABDDBB29}" ?>
<?elseif $(var.EnvID) = "PROD" ?>
<?define CompGUID = "{FEE4FBB1-9894-48F4-8DDC-9FC83F8AD778}" ?>
<?elseif $(var.EnvID) = "QA1" ?>
<?define CompGUID = "{EED17AF6-BF99-4B34-821D-6A8487292111}" ?>
<?endif ?>
<Component
Id="$(var.FullEnvID).WebSvc"
Directory="INSTALLDIR"
Guid="$(var.CompGUID)"
KeyPath="yes">
<Condition><![CDATA[ENV="$(var.EnvID)"]]></Condition>
<iis:WebAppPool
Id="$(var.FullEnvID).WebAppPool"
Name="[WEBSITENAME]"
ManagedPipelineMode="Integrated"
ManagedRuntimeVersion="v4.0"/>
<iis:WebSite
Id="$(var.FullEnvID).Website"
Description="[WEBSITENAME]"
Directory="INSTALLDIR">
<iis:WebApplication
Id="$(var.FullEnvID).WebApplication"
Name="[WEBSITENAME]"
WebAppPool="$(var.FullEnvID).WebAppPool"/>
<?include $(var.FullEnvID).WebAddress.wxi ?>
</iis:WebSite>
</Component>
<?undef CompGUID ?>
<?undef FullEnvID ?>
<?endforeach ?>
</Fragment>
</Wix>
<Condition><![CDATA[ENV="$(var.EnvID)"]]></Condition> determines which web site component is installed
<?include $(var.FullEnvID).WebAddress.wxi ?> slips in just the <iis:WebAddress/> sections as the loop iterates.
Here's what ProductName.DEV.WebAddress.wxi looks like:
<Include
xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<iis:WebAddress
Id="dev.product.company.com"
Header="dev.product.company.com"
Port="80"/>
<iis:WebAddress
Id="product.dev.company.com"
Header="product.dev.company.com"
Port="80"/>
</Include>
I am trying to create a custom UI for WiX and Burn. I have followed some of the guides I've found, and so far I have a project that has the following, which inherits from BootstrapperApplication.
namespace MyBA
{
public class TestBA : BootstrapperApplication
{
protected override void Run()
{
MessageBox.Show("My BA is running");
this.Engine.Quit(0);
}
}
}
And in the AssemblyInfo.cs:
[assembly: BootstrapperApplication(typeof(TestBA))]
Then in my Bootstrapper project I have the following.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
<Bundle Name="MyApplication"
Version="1.0.0"
Manufacturer="Acme Ltd"
UpgradeCode="F84A4058-FDF6-4218-BCB5-12C811DA3C99"
Condition="NOT ((VersionNT = 600 AND ServicePackLevel >=2) OR (VersionNT >= 601))"
IconSourceFile="$(var.MyApplicationInstallerRequiredFiles.ProjectDir)logo.ico"
SplashScreenSourceFile="$(var.MyApplicationInstallerRequiredFiles.ProjectDir)Splashscreen.bmp"
DisableRepair="no"
DisableRemove="no"
DisableModify="no">
<WixVariable Id="WixMbaPrereqPackageId"
Value="Netfx4Full" />
<WixVariable Id="WixMbaPrereqLicenseUrl"
Value="NetfxLicense.rtf" />
<WixVariable Id="WixStdbaLicenseRtf"
Value="$(var.MyApplicationInstallerRequiredFiles.ProjectDir)Licence.en-gb.rtf" />
<WixVariable Id="WixStdbaLogo"
Value="$(var.MyApplicationInstallerRequiredFiles.ProjectDir)logoInstallSmall.bmp" />
<BootstrapperApplicationRef Id='ManagedBootstrapperApplicationHost'>
<Payload Name='BootstrapperCore.config'
SourceFile='$(var.MyApplicationInstallerRequiredFiles.ProjectDir)Bootstrapper\MyBA.BootstrapperCore.config' />
<Payload SourceFile='$(var.MyApplicationInstallerRequiredFiles.ProjectDir)Bootstrapper\MyBA.dll' />
</BootstrapperApplicationRef>
<Chain>
<PackageGroupRef Id="MyApplicationPackage" />
</Chain>
</Bundle>
</Wix>
and I have added MyBA.BootstrapperCore.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="wix.bootstrapper"
type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.BootstrapperSectionGroup, BootstrapperCore">
<section name="host"
type="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.HostSection, BootstrapperCore" />
</sectionGroup>
</configSections>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v4.0" />
</startup>
<wix.bootstrapper>
<host assemblyName="MyBA">
<supportedFramework version="v4\Full" />
<supportedFramework version="v4\Client" />
</host>
</wix.bootstrapper>
</configuration>
However, whenever I run the Setup.exe for the bootstrapper, I get the splashscreen appear briefly, but nothing else. If I look in the %TEMP% at the logs there is the following
[0A00:0424][2011-11-02T15:52:08]: Burn v3.6.2221.0, path: C:\MyApplication\dev\source\Bootstrapper1\bin\Debug\Setup.exe, cmdline: ''
[0A00:0424][2011-11-02T15:52:08]: Setting string variable 'WixBundleName' to value 'MyApplication'
[0A00:0424][2011-11-02T15:52:08]: Setting string variable 'WixBundleLog' to value 'C:\Users\AppData\Local\Temp\MyApplication_20111102155208.log'
[0A00:0424][2011-11-02T15:52:08]: Condition 'NOT ((VersionNT = 600 AND ServicePackLevel >=2) OR (VersionNT >= 601))' evaluates to true.
[0A00:0424][2011-11-02T15:52:08]: Setting string variable 'WixBundleOriginalSource' to value 'C:\MyApplication\dev\source\Bootstrapper1\bin\Debug\Setup.exe'
[0A00:0424][2011-11-02T15:52:08]: Loading managed bootstrapper application.
[0A00:0424][2011-11-02T15:52:08]: Error 0x80131040: Failed to create the managed bootstrapper application.
[0A00:0424][2011-11-02T15:52:08]: Error 0x80131040: Failed to create UX.
[0A00:0424][2011-11-02T15:52:08]: Error 0x80131040: Failed to load UX.
[0A00:0424][2011-11-02T15:52:08]: Error 0x80131040: Failed while running
[0A00:0424][2011-11-02T15:52:08]: Error 0x80131040: Failed to run per-user mode.
Why is this happening and why are the above errors occurring?
If you look at the source code for the WixBA, they declare a global Threading.Dispatcher, and then in the overridden Run() method, there is the following line:
Threading.Dispatcher.Run();
I had similar issues, and similarly adding the Threading.Dispatcher to my bootstrapper application fixed them.
Also, if your Bootstrapper Application depends on any other dlls, you need to include them as a <Payload/> under your <BootstrapperApplicationRef/>.