WIX UI Overwrite Folder Path Custom Action - c#

Let's say I have this directory structure.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="test" Name="test">
<Component Id="file" Guid="*">
<File Id="file" Source="file.dll"></File>
</Component>
</Directory>
</Directory>
This will install file.dll into C:\test. What I want to do is during the install overwrite where that file directory with C:\newpath\ and install the file there instead. I have tried this with a Custom Action with no luck. I do see the debug line written so I know it's being called, it's just the file is still installed in C:\test
<InstallExecuteSequence>
<Custom Action="OverwriteDir" After="CostFinalize" />
</InstallExecuteSequence>
[CustomAction]
public static ActionResult OverwriteDir(Session session)
{
System.Diagnostics.Debug.WriteLine(session["tester"]);
session["tester"] = "C:\\newpath";
return ActionResult.Success;
}
What can I do differently?

First you need to make sure that the folder which contains your file inside the MSI uses a public installer property (no lowercase letters in its name) as its ID. The best solution is TARGETDIR because its already configured.
After that, you can use one of these custom action to change the property value during install:
a custom action which changes the directory property value scheduled before CostFinalize
a type 35 custom action which changes the directory path (should be scheduled after CostFinalize)

Related

How to execute Custom action in Wix after Uninstall completed

I have enabled logging using below code :
<Property Id="MsiLogging" Value="voicewarmupx!"/>
and I want to copy log file from temp folder to custom Log location.
I have written a custom action as below
<CustomAction Id="CopyLogFile" Execute="immediate"
ExeCommand="cmd /c copy [MsiLogFileLocation] [LogsFolder]"
Directory="TARGETDIR"
Impersonate="no"
Return="asyncNoWait" />
<InstallExecuteSequence>
Custom Action="CopyLogFile" OnExit="success"></Custom>
After successful installation above code works fine but when I do Uninstall the code is not working.
Any one please help me to move file from Temp folder to specific folder after uninstall.?
The specify the condition for the Custom Action to be invoked on an uninstall: (REMOVE="ALL") AND NOT UPGRADINGPRODUCTCODE.
This should work:
<CustomAction Id="CopyLogFile" Execute="immediate"
ExeCommand="cmd /c copy [MsiLogFileLocation] [LogsFolder]"
Directory="TARGETDIR"
Impersonate="no"
Return="asyncNoWait" />
<InstallExecuteSequence>
<Custom Action="CopyLogFile" OnExit="success">(REMOVE="ALL") AND NOT UPGRADINGPRODUCTCODE</Custom>
...
See the full property references you can use in the Microsoft Docs.

Creating shortcut to folder in WIX that uses environmental variable

I'm trying to do two things in WIX:
Create new environmental variable that points to specific directory, e.g. %test% which leads to a variable [DOCUMENTSPATH]
Create a shortcut to that folder on the desktop. Shortcut must be using the same variable [DOCUMENTSPATH]
Using the <RegistryKey> and <RegistryValue> I can create the environmental variable that leads to variable.
<Component Id="EnvironmentAlias" Guid="827d993f-32c0-4088-a72a-43888a5f496a">
<RegistryKey Root="HKLM" Key="SYSTEM\CurrentControlSet\Control\Session Manager\Environment">
<RegistryValue Type="string" Name="%NEW_PATH%" Value="[DOCUMENTSPATH]" Action="write"></RegistryValue>
</RegistryKey>
</Component>
This creates the shortcut
<Component Id="SampleDir" Guid="E9EAE95A-8234-406D-950D-397956287709" Directory="DesktopFolder">
<Shortcut Id="SampleDirSC"
Name="somename"
Target="[DOCUMENTSPATH]"
Advertise="yes"
Show="normal" />
</Component>
(Also tried with advertise=no)
The link and variable are created but the link type is file instead of folder - so both the behavior of it and looks are wrong. It looks like generic shortcut and does not open the folder on click - I need to right-click -> go to location to go to the [DOCUMENTSPATH] folder. This is because the [DOCUMENTSPATH] I'm using contains different environmental variable, e.g. %localappdata%.
Any ideas how to enforce target type of the shortcut in wix OR how to expand the environmental variables in wix?
Edit: additional explanation.
I am trying to make wix expand environmental variable (the one that starts with %, like %appdata%) when creating the shortcut because windows doesn't handle well dynamic variables in shortcuts.
Change your tag to this
<Component Id="SampleDir" Guid="E9EAE95A-8234-406D-950D-397956287709" Directory="DesktopFolder">
<Shortcut Id="SampleDirSC"
Name="somename"
Target="[DOCUMENTSPATH]"
WorkingDirectory="DOCUMENTSPATH"
Show="normal" />
</Component>
This is a part sample of my test code
<DirectoryRef Id="DesktopFolder">
<Component Id="ApplicationShortCutC" Guid="{CB93D6D1-AB98-4b45-98FF-4017EE5A0A09}">
<Shortcut Id="AppShortCutC" Name="!(wix.Product)"
Description="!(wix.ProductDesc)"
Target="[INSTALLDIR]"
WorkingDirectory="INSTALLDIR" />
<RegistryKey Root="HKCU" Key="!(wix.Manufacturer)\!(wix.Product)" Action="createAndRemoveOnUninstall">
<RegistryValue Name="ShortCutC" Type="integer" Value="1" KeyPath="yes" />
</RegistryKey>
<RemoveFolder Id="ShortCutFolder" Directory="ApplicationProgramsFolder" On="uninstall"/>
</Component>
</DirectoryRef
Shortcut element here, says that advertise=yes ignores the target.
Sample code

WiX installer includes dll into msi

I'm trying to create an installer using WiX. To includes DLLs into .msi package I tryied two different ways. One of these is:
<DirectoryRef Id="SETTINGSDIR">
<Component Id="CMP_CopySettings" Guid="AC7D1AA1-798B-48F5-AF8D-188B1050D47C" KeyPath="yes">
<CreateFolder />
<File Id="DBA.bat" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\A_DB clear.bat" Checksum="yes"/>
<File Id="AConfiguration.xml" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\AConfiguration.xml" Checksum="yes"/>
<File Id="ADB.CE.DEFAULT.sdf" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\ADB.CE.DEFAULT.sdf" Checksum="yes"/>
<File Id="ADB.CE.sdf" Source="$(var.SolutionDir)\scr\A\A.WindowsService\bin\$(var.Configuration)\Settings\A.CE.sdf" Checksum="yes"/>
<RemoveFile Id="RemoveFileSettings" Name="*" On="uninstall"/>
</Component>
</DirectoryRef>
But as you can easily understand, it's very hard write an xml node for each DLL (6 projects with 200+ DLLs for each one).
The second one is faster, but WiX just creates a link to the folder instead of copy DLLs into msi package
<DirectoryRef Id="SETTINGSDIR">
<Component Id="CMP_CopySettings" Guid="AC7D1AA1-798B-48F5-AF8D-188B1050D47C" KeyPath="yes">
<CreateFolder />
<CopyFile Id="SettingsID" SourceProperty="SETTINGSSOURCEDIRECTORY" DestinationDirectory="SETTINGSDIR" SourceName="*" />
<RemoveFile Id="RemoveFileSettings" Name="*" On="uninstall"/>
</Component>
</DirectoryRef>
Is there a quick solution that can I add at my second way or I have to use heat.exe tool? In this case, can you explain me how to use it? The official documentation is very poor
Thanks
What you want is an harvest tool to do this for you. Luckily it already exists: Heat
In your specific case you might want to use the command heat dir ".\My Files" -gg -g1 -directoryid "YourDirectoryId" -sfrag -template:fragment -out directory.wxs but check what is exactly your need, which harvesting you want to skip etc...
Note the -t <xsl> switch which gives you the total control on how you want to tune the final output.

Wix - How to get a relative path

I need to reference some dlls files in my wix project, and i need to user relative path. If i use absolute path like this
C:\Users\MyUser\Documents\any\other\folder
it works perfectly, but i need a relative path like this:
../bin/dll
but it is unable to find the folder.
This is the "ComponentGroup" section where i need to get the dll folder
<ComponentGroup Id="DllsComponent" Directory="INSTALLFOLDER" Source="../bin/dll">
<Component Id="EntityFramework.dll">
<File Name="EntityFramework.dll" />
</Component>
<Component Id="EntityFramework.SqlServer.dll">
<File Name="EntityFramework.SqlServer.dll" />
</Component>
<Component Id="EntityFramework.SqlServerd.xml">
<File Name="EntityFramework.SqlServer.xml" />
</Component>
<Component Id="EntityFramework.xml">
<File Name="EntityFramework.xml" />
</Component>
<Component Id="ParodosService.exe.config">
<File Name="ParodosService.exe.config" />
</Component>
</ComponentGroup>
and the wix project structure is this:
ParodosService.Setup
|_bin
|_dll
|_EntityFramework.dll
|_EntityFramework.SqlServer.dll
|_other files...
|_Debug
|_Release
Thanks in advance...
You can use predefined directory properties from the list
System Folder Properties
Set the closest in the directory table and than use it in the source attribute.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder">
</Directory>
</Directory>
Source attribute:
Source="$(var.DesktopFolder)../bin/dll

Unresolved reference to symbol in Wix

I am trying to create a installer for MVC4 application using Wix. I found an example that shows how to create an installer for a MVC4 Application at this link
But when I try to build the Wix Setup Project, it gives me errors like below
Error 16 Unresolved reference to symbol 'WixComponentGroup:MyWebWebComponents'
in section 'Product:{D16E42B5-3C6F-4EE5-B2F4-727BF8B74A92}'.
C:\Users\Baris\Desktop\New folder\WIXInstallerDemo-master\DemoWebsite.Setup\Product.wxs 15
1 DemoWebsite.Setup
Error 17 Unresolved reference to symbol 'WixComponentGroup:DemoWebsiteIssConfiguration'
in section 'Product:{D16E42B5-3C6F-4EE5-B2F4-727BF8B74A92}'.
C:\Users\Baris\Desktop\New folder\WIXInstallerDemo-master\DemoWebsite.Setup\Product.wxs 16
1 DemoWebsite.Setup`
I tried adding WixUIExtension as a reference but it doesn't work.
This is the Product.wxs. And feature node's children nodes causes this error
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="{D16E42B5-3C6F-4EE5-B2F4-727BF8B74A92}" Name="Demo website setup" Language="1033" Version="1.0.0.0" Manufacturer="Me" UpgradeCode="9279b740-8419-45c4-9538-6a45f8e949c7">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1" Cabinet="DemoWebsite.cab" EmbedCab="yes" />
<Property Id="DB_USER" Value="sa"/>
<Property Id="DB_PASSWORD" Value="sa"/>
<Property Id="DB_SERVER" Value="LOCAL"/>
<Property Id="DB_DATABASE" Value="DemoWebsite"/>
<Feature Id="ProductFeature" Title="DemoWebsite.Setup" Level="1">
<ComponentGroupRef Id="MyWebWebComponents" />
<ComponentGroupRef Id="DemoWebsiteIssConfiguration" />
</Feature>
<!-- Specify UI -->
<UIRef Id="MyUI" />
<Property Id="WIXUI_INSTALLDIR" Value="INETPUB" />
</Product>
<Fragment>
<!-- Will default to C:\ if that is the main disk-->
<Directory Id="TARGETDIR" Name="SourceDir">
<!-- Will reference to C:\inetpub-->
<Directory Id="INETPUB" Name="Inetpub">
<!-- Will reference to c:\Inetpub\Demowebsite-->
<Directory Id="INSTALLFOLDER" Name="DemoWebsite">
</Directory>
</Directory>
</Directory>
</Fragment>
</Wix>
What am I doing wrong? I know its very specific for SO but I cannot find any solution on the web.
I am using VS 2012- Wix 4.0
The error message says it all: it expects a ComponentGroup-tag containing your components (containing e.g. files or registry keys). If you take a look at the example project that you linked in your question, the <ComponentGroupRef Id="DemoWebsiteIssConfiguration" />-element references a ComponentGroup with the name DemoWebsiteIssConfiguration. You can find this in the file DemoWebsite.Setup\IISConfiguration.wxs:
<ComponentGroup Id="DemoWebsiteIssConfiguration">
<ComponentRef Id="InstallWebsite" />
<ComponentRef Id="DemoWebsiteAppPool" />
</ComponentGroup>
It is a ComponentGroup which contains two components or, in this case, references to two components. These components are defined above the ComponentGroup-element in the same file.
Regarding the other ComponentGroupRef with the id MyWebComponents: The referenced ComponentGroup is created dynamically during the build. You can take a look at the file DemoWebsite.Setup\setup.build. This file is a MSBuild-file used to build the setup. It contains a target named Harvest that invokes heat, another tool in the WiX Toolset package. heat will parse e.g. a directory and gather all the files contained within and put them in a ComponentGroup that you can reference in your source file. I.e. you define a reference to a ComponentGroup and then you can create the content of this dynamically. This way you don't have to bother if a file is added to or removed from the project, as heat will gather them dynamically.
<Target Name="Harvest">
<!-- Harvest all content of published result -->
<Exec
Command='$(WixPath)heat dir $(Publish) -dr INSTALLFOLDER -ke -srd -cg MyWebWebComponents -var var.publishDir -gg -out $(WebSiteContentCode)'
ContinueOnError="false"
WorkingDirectory="." />
</Target>
The name of the dynamically created ComponentGroup is defined with the parameter -cg. you can invoke heat with the parameter -? for a short description of the possible parameters.

Categories

Resources