I'm attempting to use a custom action to run a program with a command-line option during installation (after files copied). The action requires admin permission (it sets up and installs a windows service). For some reason, the custom action keeps failing.
My wix code:
<?xml version='1.0' encoding='Windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product
Name='WHS 2011 Media Collector'
Id='28656223-C2E0-4E74-8503-B9D668056C4E'
UpgradeCode='84F31832-4E09-4149-A3F7-56A8DF63086F'
Language='1033'
Codepage='1252'
Version='3.0.0'
Manufacturer='Nick Radtke'>
<Package
Id='*'
Keywords='Installer'
Platform="x64"
Description="WHS 2011 Media Collector" Comments='Deployment Package for WHS 2011 Media Collector'
Manufacturer='Nick Radtke'
InstallerVersion='300'
Languages='1033'
Compressed='yes'
SummaryCodepage='1252'
InstallPrivileges='elevated'
InstallScope='perMachine'/>
<Media
Id='1'
Cabinet='WSSSampleAddins.cab'
EmbedCab='yes'
DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="Addins Installation [1]" />
<Property Id="LaunchApplication" Value=""MediaCollectorServerService.exe" -install"/>
<Property Id="MSIUSEREALADMINDETECTION" Value="1" />
<InstallExecuteSequence>
<Custom Action='LaunchApplication' Before='InstallFinalize'>NOT Installed</Custom>
</InstallExecuteSequence>
<CustomAction Id="LaunchApplication"
BinaryKey="WixCA"
Impersonate="no"
DllEntry="CAQuietExec64"
Execute="deferred"
Return="check"
/>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFiles64Folder' Name='PFiles'>
<Directory Id="ParentAddinBinaryDir" Name="Nick Radtke">
<Directory Id="AddinBinaryDir" Name="WHS 2011 Media Collector">
<Component
Id='WHS2011MCBinaryComponent'
Guid='D21DA776-83F1-4F22-985B-FDB3C8ABD481'
Win64='yes'>
<RemoveFolder Id='AddinBinaryDir' On='uninstall' />
<File
Id='WHS2011MediaCollector.ListViewSubTab'
Name='WHS2011MediaCollector.ListViewSubTab.dll'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\WHS2011MediaCollector.ListViewSubTab.dll'
ProcessorArchitecture='x64'
KeyPath='yes'>
</File>
<File
Id='WHS2011MediaCollector.TopLevelTab'
Name='WHS2011MediaCollector.TopLevelTab.dll'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\WHS2011MediaCollector.TopLevelTab.dll'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
<File
Id='WHS2011MediaCollector.PicturesSubTab'
Name='WHS2011MediaCollector.PicturesSubTab.dll'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\WHS2011MediaCollector.PicturesSubTab.dll'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
<File
Id='WHS2011MediaCollector.VideosSubTab'
Name='WHS2011MediaCollector.VideosSubTab.dll'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\WHS2011MediaCollector.VideosSubTab.dll'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
<File
Id='WHS2011MediaCollector.SettingsSubTab'
Name='WHS2011MediaCollector.SettingsSubTab.dll'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\WHS2011MediaCollector.SettingsSubTab.dll'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
<File
Id='NetLibrary'
Name='NetLibrary.dll'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\NetLibrary.dll'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
<File
Id='Icon.png'
Name='Icon.png'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\Icon.png'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
<File
Id='taglib_sharp'
Name='taglib-sharp.dll'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\taglib-sharp.dll'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
<File
Id='MediaCollectorServerService.exe'
Name='MediaCollectorServerService.exe'
DiskId='1'
Source='..\..\MediaCollectorServerService\x64\Release\MediaCollectorServerService.exe'
ProcessorArchitecture='x64'
KeyPath='no'>
</File>
</Component>
</Directory>
</Directory>
<Directory Id="WindowsServerDir" Name="Windows Server">
<Directory Id="WindowsServerBinDir" Name="Bin">
<Directory Id="WindowsServerAddinsDir" Name="Addins">
<Directory Id="WindowsServerPrimaryDir" Name="Primary">
<Component
Id='WHS2011MCXMLComponent'
Guid='D21DA776-83F1-4F22-985B-FDB3C8ABD491'
Win64='yes'>
<File Id='WHS2011MCTopLevelTabXML'
Name='WHS2011MediaCollector.addin'
DiskId='1'
Source='..\..\MediaCollectorAddIn\MediaCollector\TopLevelTab\bin\Release\WHS2011MediaCollector.addin'
ProcessorArchitecture='x64'
KeyPath='yes'>
</File>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id='WHS2011MCBinaryComponent' />
<ComponentRef Id='WHS2011MCXMLComponent' />
</Feature>
</Product>
</Wix>
This is the error I'm getting in the msi log:
MSI (s) (40:30) [22:58:07:647]: Created Custom Action Server with PID 11672 (0x2D98).
MSI (s) (40:40) [22:58:07:663]: Running as a service.
MSI (s) (40:40) [22:58:07:663]: Hello, I'm your 32bit Elevated custom action server.
CAQuietExec64: Error 0x80070002: Command failed to execute.
CAQuietExec64: Error 0x80070002: CAQuietExec64 Failed
CustomAction LaunchApplication returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 22:58:07: InstallFinalize. Return value 3.
MSI (s) (40:D0) [22:58:07:694]: Note: 1: 2265 2: 3: -2147287035
If I run the command line as a normal user, it fails, but if I run it as an admin user (or the system user), it works. I'm fairly certain the problem is the permissions on the action. I've set it to deferred and Impersonate='no', but it's still not working. Anyone have any tips?
Edit: So, I've found that apparently shortcuts in launchapplication aren't working for the path of the executable. Does anyone know the syntax that allows for this?
Ended up figuring it out myself.
Changed the
<Property Id="LaunchApplication" Value=""MediaCollectorServerService.exe" -install"/>
line to
<SetProperty Id="LaunchApplication" Before="InstallInitialize" Sequence="execute" Value=""[#MediaCollectorServerService.exe]%quot; -install"><![CDATA[NOT Installed AND LaunchApplication=""]]</SetProperty>
Hoping this proves useful for others in the future.
Related
I am using heat.exe to generate a .wxs file to include files in my main installer. I have two questions:
Which switches would I use to register a DLL?
Once I have generated the output file how do I go about adding it to my "Main.wxs" file? (Please be pretty explicit, new to this)
I have looked around a lot for an answer to the second question and I always come up with something vague or for VS, I am working from the command line. Thanks!
This is what I have tried thus far: I get the error: (LGHT0103: The system cannot find the file "file") I get this error for all of my files.
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="cmp1D2A500FA963CF9DB333FD18154B94BC" Guid="{8DE755D7-F1F9-4EC3-BCD5-B72360B8752A}">
<File Id="filCBD973AD942425DC5F533B29866FEF5A" KeyPath="yes" Source="SourceDir\DLLs\FP7000-Camera.dll" />
</Component>
<Component Id="cmp4CC93670B061A60B94C1867DCFAAAED0" Guid="{717E0819-2842-4C0D-BFAB-30E4C8C66F7E}">
<File Id="fil7CEC0F75EDE8EEF9C7F6D563E8D04EF9" KeyPath="yes" Source="SourceDir\DLLs\libmfxsw64.dll" />
</Component>
<Component Id="cmpE80ACF08DF44E67E7583F35557C8EB02" Guid="{4CAA0627-45DB-4E34-9B4C-C54B5E21346C}">
<File Id="fil1E619A89A3D0D2FDE446E60B3D3EB2AF" KeyPath="yes" Source="SourceDir\DLLs\pthreadVC2.dll" />
</Component>
</ComponentGroup>
</Fragment>
You can cut the component nodes and paste them into the correct installation directory in your main wxs file. As an example you can check out this simple mock-up:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="put-guid-here"
Name="Example Product Name" Version="0.0.1"
Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes"
Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="FP7000-Camera.dll" Guid="*">
<File Id="FP7000-Camera.dll" Source="replace with path to FP7000-Camera.dll"/>
</Component>
further components can be added here.
</Directory>
</Directory>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="FP7000-Camera.dll"/>
</Feature>
</Product>
</Wix>
You should extract the COM data for your COM files. Here is a sample Heat.exe command. (Note: if your dll fails to load due to missing dependencies you might need to install your sdk setup before running the extraction):
heat file MyComFile.ocx -out MyComFile.wxs
the resulting, extracted COM data in MyComFile.wxs will look something like this:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="dirE645D1B018BB48C41BDBE188A129817F" Name="wix310-binaries" />
</DirectoryRef>
</Fragment>
<Fragment>
<DirectoryRef Id="dirE645D1B018BB48C41BDBE188A129817F">
cut from here
<Component Id="cmpD8BB195A00599F06D2FF16982DBAA523" Guid="PUT-GUID-HERE">
<File Id="filBDC3CFD8FF09857ADE9793AF172F66E6" KeyPath="yes" Source="SourceDir\wix310-binaries\ITDetector.ocx">
<TypeLib Id="{D6995525-B33A-4980-A106-9DF58570CC66}" Description="ITDetector 1.0 Type Library" HelpDirectory="dirE645D1B018BB48C41BDBE188A129817F" Language="0" MajorVersion="1" MinorVersion="0">
<Class Id="{D719897A-B07A-4C0C-AEA9-9B663A28DFCB}" Context="InprocServer32" Description="iTunesDetector Class" ThreadingModel="apartment" Programmable="yes" SafeForScripting="yes" SafeForInitializing="yes">
<ProgId Id="ITDetector.iTunesDetector.1" Description="iTunesDetector Class">
<ProgId Id="ITDetector.iTunesDetector" Description="iTunesDetector Class" />
</ProgId>
</Class>
<Interface Id="{45D2C838-0137-4E6A-AA3B-D39B4A1A1A28}" Name="IiTunesDetector" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
</TypeLib>
</File>
</Component>
to here
</DirectoryRef>
</Fragment>
</Wix>
Paste the component into your main wxs file in the appropriate Directory location. For example in INSTALLDIR as illustrated in the first WXS file above.
Finally a merged sample showing the main wxs file populated with the extracted component nodes from your heat.exe tool:
<?xml version="1.0"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="put-guid-here"
Name="Example Product Name" Version="0.0.1"
Manufacturer="Example Company Name" Language="1033">
<Package InstallerVersion="200" Compressed="yes"
Comments="Windows Installer Package"/>
<Media Id="1" Cabinet="product.cab" EmbedCab="yes"/>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="FP7000-Camera.dll" Guid="*">
<File Id="FP7000-Camera.dll" Source="replace with path to FP7000-Camera.dll"/>
</Component>
<Component Id="cmpD8BB195A00599F06D2FF16982DBAA523" Guid="*">
<File Id="filBDC3CFD8FF09857ADE9793AF172F66E6" KeyPath="yes" Source="SourceDir\wix310-binaries\ITDetector.ocx">
<TypeLib Id="{D6995525-B33A-4980-A106-9DF58570CC66}" Description="ITDetector 1.0 Type Library" HelpDirectory="dirE645D1B018BB48C41BDBE188A129817F" Language="0" MajorVersion="1" MinorVersion="0">
<Class Id="{D719897A-B07A-4C0C-AEA9-9B663A28DFCB}" Context="InprocServer32" Description="iTunesDetector Class" ThreadingModel="apartment" Programmable="yes" SafeForScripting="yes" SafeForInitializing="yes">
<ProgId Id="ITDetector.iTunesDetector.1" Description="iTunesDetector Class">
<ProgId Id="ITDetector.iTunesDetector" Description="iTunesDetector Class" />
</ProgId>
</Class>
<Interface Id="{45D2C838-0137-4E6A-AA3B-D39B4A1A1A28}" Name="IiTunesDetector" ProxyStubClassId32="{00020424-0000-0000-C000-000000000046}" />
</TypeLib>
</File>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="DefaultFeature" Level="1">
<ComponentRef Id="FP7000-Camera.dll"/>
<ComponentRef Id="cmpD8BB195A00599F06D2FF16982DBAA523"/>
</Feature>
</Product>
</Wix>
If the above is unclear, please try to read this answer: How to run heat.exe and register a dll in wix
I was following the below code which is product.wxs files.But I am facing an error as below:
Error 5 Unresolved reference to symbol 'WixComponentGroup:MyWebWebComponents' in section 'Product:{}'
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<Product Id="702881b5-9a64-4ab8-ab47-f3babcd950a2"
Name="WixApplication" Language="1033"
Version="1.0.0.0"
Manufacturer="HexWireless"
UpgradeCode="42b7872b-78c8-4a0b-abcd-28a30c9804ab">
<Package InstallerVersion="200" Compressed="yes" Platform="x64" InstallScope="perMachine"/>
<!--<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />-->
<!--Find the Path to the sqlcmd.exe by performing a registry search. This is hardcoded for SQL 2012.
Change 110 to 100 for 2008. Might need to change the script too.-->
<Property Id="SQLBINDIR">
<RegistrySearch Id="SqlBinDir"
Root="HKLM" Key="SOFTWARE\Microsoft\Microsoft SQL Server\110\Tools\ClientSetup"
Name="Path"
Type="raw"
Win64="yes"/>
</Property>
<Condition Message="Microsoft SQL Server 2012 needs to be installed before this installer can run">
<![CDATA[SQLBINDIR]]>
</Condition>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLLOCATION" Name="Database">
<Component Id="Database" Guid="a8dc2Fcd-087d-e393-b059-c67877e51b8a">
<File Id="DatabaseScript" Source="SQLScripts\HexWireless.sql"/>
<RemoveFile Id ="RemoveInstall.log" Name="Install.log" On="uninstall" />
</Component>
</Directory>
<Directory Id="INSTALLDIR" Name="PFiles">
<Directory Id="WixService" Name="Service">
<Component Id="WixWindowsServiceComponent" DiskId="1" Guid="6f51c0f3-776c-4aec-a200-1f199352c6c3" Win64="yes">
<File Id="WixService.exe" Name="WixService.exe" Source="$(var.WixService.TargetDir)\WixService.exe"/>
<ServiceInstall Id="InstallWixService" DisplayName="WixService" Name="WixService.exe" Description="WixService" Account="NT Authority\Network Service" ErrorControl="normal" Start="demand" Type="ownProcess" Vital="yes" />
<ServiceControl Id="ControlWixService" Name="WixService.exe" Stop="uninstall" Remove="uninstall" />
</Component>
</Directory>
</Directory>
<Directory Id="INSTALLFOLDER" Name="Publish">
</Directory>
</Directory>
<Feature Id="ProductFeature" Title="WebApplication" Level="1">
<Feature Id="Database" Title="Database" Description="DatabaseScript" Level="1" Display="expand"
AllowAdvertise="no" ConfigurableDirectory="INSTALLLOCATION" Absent="allow">
<Feature Id="WixWindowsServiceComponent" Title="Service" Description="WixService" Level="1" Display="expand"
AllowAdvertise="no" ConfigurableDirectory="INSTALLDIR" Absent="allow">
<ComponentGroupRef Id="WixWebsiteIssConfiguration" />
<ComponentRef Id="Database"/>
<ComponentRef Id="WixWindowsServiceComponent"/>
<ComponentGroupRef Id="MyWebWebComponents"/>
</Feature>
</Feature>
</Feature>
<Property Id="INSTALLDIR" Value="D:" />
<Media Id="1" Cabinet="WixWindowsServiceComponent.cab" EmbedCab="yes" />
<InstallExecuteSequence>
<!--If the database feature is selected these actions will run to install the DB-->
<Custom Action="Database.cmd" After="InstallFiles" >
<![CDATA[NOT Installed]]>
</Custom>
<!--Ensure this runs after the custom action to set up the properties for its cmd line-->
<Custom Action="Database" After="Database.cmd">
<![CDATA[NOT Installed]]>
</Custom>
</InstallExecuteSequence>
<UI>
<UIRef Id="GUI"/>
<UIRef Id="WixUI_ErrorProgressText" />
</UI>
<!--This is the sequence script. Best way to understand this is by running sqlcmd -?
Use "property" Custom action to get variable substitution working-->
<CustomAction Id="Database.cmd" Property="Database"
Value=""[SQLBINDIR]sqlcmd.exe" -E -S "[SQLSERVER]" -i "[#DatabaseScript]" -o "[INSTALLLOCATION]HexWireless.log""/>
<!-- Note that the cmd line and args will come from a property with the same name as the custom action, this has been set by the custom action above -->
<CustomAction Id="Database" BinaryKey="WixCA" DllEntry="CAQuietExec" Return="check" Execute="deferred" Impersonate="yes" />
</Product>
</Wix>
Thanks In Advance.
I am not sure if your issue is sorted or not, I just faced the same issue even though i have created a few of these msi files with Wix.
In my case, it wasn't finding the "HeatedComponents" that I am generating automatically within the project. I had to load this file into the project, (these files or folders may be inside your project folder but in most cases VS does not load them automatically).
You have to Right Click on the project -> Add -> Existing Item; and select the file/item that is required.
I need to create a setup project using WiX to deploy two Visual Studio Extensions(vsix). I create a project follow the steps that you can see in this blog: Creating WiX setup for VSIX. I can compile the project and generate the .msi file, but when I am going to install the extensions, it gave me a runtime error, the error code is 2343.
The XML of the WiX project is this:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:VSExtension="http://schemas.microsoft.com/wix/VSExtension" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<Product Id="{77F7DB1E-6E8A-44DB-88FE-9E496B140A2C}" Name="Bpmn Studio" Language="1033" Version="1.0.0.0" Manufacturer="Cadic" UpgradeCode="8c57d4aa-2b56-4561-94dd-cf02b34a4747">
<Package InstallerVersion="301" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" VolumeLabel="Bpmn Studio"/>
<PropertyRef Id="VS2013DEVENV"/>
<Condition Message="Visual Studio 2013 needs to be intalled for this installation to continue.">
<![CDATA[Installed OR VS2013DEVENV]]>
</Condition>
<!--Directory structure-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLLOCATION" />
<UIRef Id="WixUI_InstallDir" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Casasoft" >
</Directory>
</Directory>
</Directory>
<Property Id="VSINSTALLDIR">
<RegistrySearch Id="VSInstallRegistry" Root="HKLM" Key="SOFTWARE\Microsoft\VisualStudio\12.0" Name="InstallDir" Type="directory" />
</Property>
<CustomAction Id="SetVSIXInstaller" Return="check" Execute="immediate" Property="VSIXInstaller" Value="C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\VSIXInstaller.exe" />
<CustomAction Id="DeployVSIX" Property="VSIXInstaller" Execute="deferred" Impersonate="no" ExeCommand="/quiet" Return="asyncWait"/>
<InstallExecuteSequence>
<Custom Action="DeployVSIX" After="MsiPublishAssemblies" />
</InstallExecuteSequence>
<Feature Id="BpmnStudio" Title="Bpmn Studio" Level="1">
<ComponentRef Id="BpmnStudioExtensionVSPackage" />
</Feature>
<Feature Id="ProjectTypeFeature" Title="Bpmn Studio Project Type" Level="1">
<ComponentRef Id="VSProjectTypePackage" />
</Feature>
</Product>
<Fragment>
<ComponentGroup Id="VSProjectTypeProductComponents" Directory="INSTALLFOLDER">
<Component Id="VSProjectTypePackage" Guid="BD8BA9C9-3728-4847-8428-EBECE32F79DA">
<VSExtension:VsixPackage File="VsBpmnStudioProjectTypeInstaller" PackageId="86e54529-745f-4b71-85f2-d2eb602bb777" Target="professional" TargetVersion="12.0" Vital="yes" Permanent="yes" />
<File Id="VsBpmnStudioProjectTypeInstaller" Name="BpmnStudioProject.vsix" Source="D:\Work\DSL\2013\Bpmn Studio\Common\Setup\BpmnStudioProject\bin\Debug\BpmnStudioProject.vsix" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="BpmnStudioExtension" Directory="INSTALLFOLDER">
<Component Id="BpmnStudioExtensionVSPackage" Guid="BD8BA9C9-3728-4847-8429-EBECE32F79DA">
<VSExtension:VsixPackage File="VsPackageInstaller" PackageId="86e54529-745f-4b71-85f2-d2eb602bb767" Target="professional" TargetVersion="12.0" Vital="yes" Permanent="yes" />
<File Id="VsPackageInstaller" Name="CasaSoft.BpmnStudio.DslPackage.vsix" Source="D:\Work\DSL\2013\Bpmn Studio\DslPackage\bin\Debug\CasaSoft.BpmnStudio.DslPackage.vsix" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Hi Jason: I found the empty path,Is when I set the path where I want to install the extensions in the UI Interface. The Value INSTALLALLOCATION doesn't exist. I change this value for INSTALLFOLDER and now works as I want
I am currently working on a tool for system administrators that can be used to update all clients of a Windows AD. It needs to work with Group Policy and SMS for the purpose of doing mass-updating. Therefore I need the tool to result in a MSI file.
Is it possible to create a MSI file that does not install anything but instead only does a custom action (ie. run a script or exe-file).
Best Regards Jakob Simon-Gaarde
Yes, it is possible. Shameful, but, possible.
You can make a square peg fit in a round hole but you lose all of the intended benefits.
FWIW, SMS is now called SCCM and it can call EXE commands.
Found a hackish way to solve my problem:
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product
Name='MVLicense Updater' Id='f8fc0a30-c138-1fe2-838b-0845200c9a66'
UpgradeCode='00ca86a0-c889-12e2-8f8b-0800200c9a66'
Language='1033' Version='1.0.0.0' Manufacturer='My Company'>
<Package Id='*' InstallerVersion='200' Compressed='yes' />
<Media Id='1' Cabinet='my.cab' EmbedCab='yes' />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder'>
<Directory Id='INSTALLDIR' Name='My-Updater'>
<Component Id='Readme' Guid='68fef080-c87b-34e2-8889-0824200c9a66'>
<File Id='ReadmeTXT' Name='readme.txt' Source='readme.txt' Vital='no' />
<RemoveFolder Id="INSTALLDIR" On="uninstall" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id='Complete' Level="1">
<ComponentRef Id='Readme' />
</Feature>
<CustomAction Id="ForceError" Error="1602"/>
<CustomAction Id="RunMyUpdater" BinaryKey="MyUpdaterExe" ExeCommand="dummy" Return="check"/>
<InstallExecuteSequence>
<Custom Action='RunMyUpdater' After='InstallInitialize'></Custom>
<Custom Action="ForceError" After="RunMvlupdate"></Custom>
</InstallExecuteSequence>
<AdminExecuteSequence>
<Custom Action='RunMyUpdater' After='InstallInitialize'></Custom>
<Custom Action="ForceError" After="RunMyUpdate"></Custom>
</AdminExecuteSequence>
<Binary Id="MyUpdaterExe" SourceFile="dist\myupdater.exe" />
<UI>
<Error Id="1602">We have a problem</Error>
</UI>
</Product>
</Wix>
This does the job of running my executable that does some configuration stuff based on calling an internet service and then rolls back the installation because I force an error to occure.
I have two questions about the directories with using fragments in Windows Installer XML.
I got this fragment file from the heat.exe:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
<DirectoryRef Id="TARGETDIR">
<Directory Id="dir08A07F5561FBEB6B9772467C730F6445" Name="Test" />
</DirectoryRef>
</Fragment>
<Fragment>
<ComponentGroup Id="InstallationFiles">
<Component Id="cmp071F7F8F6B6027C8D2841272FE526A2B" Directory="dir08A07F5561FBEB6B9772467C730F6445" Guid="{CCCB70AC-29F5-4DAA-B03E-1A2266649AB6}">
<File Id="fil63087E96FFB31F9E39B642CE8914F48B" KeyPath="yes" Source="SourceDir\dmedv.jpg" />
</Component>
<Component Id="cmpAE6CBEDA75641CF25BA9996AEB74A0DE" Directory="dir08A07F5561FBEB6B9772467C730F6445" Guid="{F5DABCAB-95D1-4197-A49F-E5F052A8E7EF}">
<File Id="filD27F2F6B26F5C14563865FE6C2AD5D50" KeyPath="yes" Source="SourceDir\Files.txt" />
</Component>
<Component Id="cmp25C5EADB5C0A9E779D20EC7B77BD42B0" Directory="dir08A07F5561FBEB6B9772467C730F6445" Guid="{E301B04A-6EA5-496B-A58A-8898110BE57C}">
<File Id="fil7C91C48D9AA0F2FE0EB37A21F108037F" KeyPath="yes" Source="SourceDir\readme.txt" />
</Component>
<Component Id="cmpD387AB4B40EDF14BF271ADDA7B71D2B7" Directory="dir08A07F5561FBEB6B9772467C730F6445" Guid="{6AF61DF4-32D0-4E7C-95B8-1DB9E7409029}">
<File Id="fil966691BA382AFC9343430FE162643432" KeyPath="yes" Source="SourceDir\readme1.txt" />
</Component>
<Component Id="cmpB86212407C1BEA12838C8C7B20495E9F" Directory="dir08A07F5561FBEB6B9772467C730F6445" Guid="{921E971E-E224-464C-9FBC-FBC5F78B3E5B}">
<File Id="fil61CD8EF43EA29DF58454E9A19F8C1EF9" KeyPath="yes" Source="SourceDir\readme2.txt" />
</Component>
<Component Id="cmpE4143B48FF854AE84F6054D4636FDE81" Directory="dir0ADF7E89B935DD39670130B4DC1D670E" Guid="{6F248718-93DD-4850-A18E-BD7079F738D5}">
<File Id="fil03847B355B6AADE5E4E04D143C92BC67" KeyPath="yes" Source="SourceDir\Test2\dmedv2.jpg" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<DirectoryRef Id="dir08A07F5561FBEB6B9772467C730F6445" />
</Fragment>
<Fragment>
<DirectoryRef Id="dir0ADF7E89B935DD39670130B4DC1D670E" />
</Fragment>
<Fragment>
<DirectoryRef Id="dir08A07F5561FBEB6B9772467C730F6445">
<Directory Id="dir0ADF7E89B935DD39670130B4DC1D670E" Name="Test2" />
</DirectoryRef>
</Fragment>
</Wix>
and I have this wix installer file:
<?xml version='1.0' encoding='windows-1252'?>
<?define ProductVersion="1.0.0.0"?>
<?define ProductName="DMServices Installer"?>
<?define Manufacturer="DM EDV- und Bürosysteme GmbH"?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi' xmlns:iis='http://schemas.microsoft.com/wix/IIsExtension'>
<Product Name="$(var.ProductName)" Id='BB7FBBE4-0A25-4cc7-A39C-AC916B665220' UpgradeCode='8A5311DE-A125-418f-B0E1-5A30B9C667BD'
Language='1033' Codepage='1252' Version="$(var.ProductVersion)" Manufacturer="$(var.Manufacturer)">
<Package Id='*' Keywords='Installer'
Description="DMService Installer Setup"
Manufacturer='DM EDV- und Bürosysteme GmbH'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="the man" />
<PropertyRef Id="NETFRAMEWORK35"/>
<Condition Message='This setup requires the .NET Framework 3.5.'>
<![CDATA[Installed OR (NETFRAMEWORK35)]]>
</Condition>
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder'>
<Directory Id='DM' Name='DM EDV'>
<Directory Id='INSTALLDIR' Name='DMServices'>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id='InstallationFiles' Title='InstallationFiles' Level='1'>
<ComponentGroupRef Id='InstallationFiles' />
</Feature>
</Product>
</Wix>
So far.
Now when i generate this files to wixobj, the compiler shows errors because the files can't be found. The files are in a directory called "Test". And in the file it's named SourceDir.
For a lil workaround i can copy the test directory and call it SourceDir ;-). So my Setup will be created.
How can I do it without a second directory?
EDIT: Problem is done.
Now i install my package. But whatever i do, the files will be installed to C:\Test.
But I want it to be installed in my Program Files Directory.
In many examples i can do it, like in the file, but i have to know the guids.
But we do wix for getting all files from one directory, without to put our hands on.
So how to install the files into the program files directory?
Take a closer look at -dr switch of heat.exe. You can put the necessary directory reference there. So, define your directory structure in the main file as you do now, and provide correct directory ID to heat.exe.
UPDATE:
Ok, the following works for me. The main directory structure:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="INSTALLLOCATION" Name="My folder">
<Directory Id="WebsiteFolder" Name="Website">
...
</Directory>
</Directory>
</Directory>
The Feature references the ComponentGroup:
<Feature Id="ProductFeature" Title="!(loc.ProductFeature.Title)" Level="100">
...
<ComponentGroupRef Id="WebsiteFolderComponentGroup"/>
...
</Feature>
The heat.exe generates the following fragment:
<Fragment>
<DirectoryRef Id="WebsiteFolder">
<Component Id="cmp1" Guid="GUID-GOES-HERE">
<File Id="fil1" KeyPath="yes" Source="$(var.WebsiteFolderSource)\Default.aspx" />
</Component>
<Component Id="cmp2" Guid="GUID-GOES-HERE">
<File Id="fil2" KeyPath="yes" Source="$(var.WebsiteFolderSource)\default.css" />
</Component>
<Directory Id="dir1" Name="App_Browsers">
<Component Id="cmp3" Guid="GUID-GOES-HERE">
<File Id="fil3" KeyPath="yes" Source="$(var.WebsiteFolderSource)\App_Browsers\Form.browser" />
</Component>
</Directory>
<Directory Id="App_Config" Name="App_Config">
<Component Id="cmp4" Guid="GUID-GOES-HERE">
<File Id="fil4" KeyPath="yes" Source="$(var.WebsiteFolderSource)\App_Config\ConnectionStrings.config" />
</Component>
</Directory>
<Directory Id="bin" Name="bin">
<Component Id="cmp5" Guid="GUID-GOES-HERE">
<File Id="fil5" KeyPath="yes" Source="$(var.WebsiteFolderSource)\bin\MySystem.Web.UI.dll" />
</Component>
<Component Id="cmp6" Guid="GUID-GOES-HERE">
<File Id="fil6" KeyPath="yes" Source="$(var.WebsiteFolderSource)\bin\Another.dll" />
</Component>
...
</Directory>
...
</Directory>
...
<ComponentGroup Id="WebsiteFolderComponentGroup">
<ComponentRef Id="cmp1" />
<ComponentRef Id="cmp2" />
<ComponentRef Id="cmp3" />
<ComponentRef Id="cmp4" />
...
</ComponentGroup>
And finally, the heat command which generates necessary output looks like this (Nant sample):
<exec program="heat.exe" verbose="true" basedir="${paths.source}">
<arg line='dir "${paths.dist.website}"'/><!-- Notice the quotes inside the attributes -->
<arg line='-srd'/>
<arg line='-dr WebsiteFolder'/>
<arg line='-cg WebsiteFolderComponentGroup'/>
<arg line='-out "${paths.harvest}\website.wxs"'/>
<arg line='-ke -sfrag -scom -sreg -gg'/>
<arg line='-var var.WebsiteFolderSource'/>
</exec>
These snippets contain enough information to understand how it all works. Play with heat.exe switches to find out the combination you need. Good luck!
In case people like me still looking for clarification: The <DirectoryRef Id="WebsiteFolder"> in the heat fragment is important, it is the reference to where the fragment files should be installed. If you have multiple fragments and want to place it in different locations, the DirectoryRef is the key.