I'm trying to create a simple installer for a .net application in WiX. I installed Votive and am using the basic template wxs file it creates. When I compile it I get warning LGHT1076: ICE71: The Media table has no entries.
Also when I run the installer it starts and disappears during installation and there is no entry in the Add/Remove Programs app.
Here's the XML:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="26d654fe-af0f-4b48-8993-8e249597a130"
Name="Minefold"
Language="1033"
Version="0.0.0.1"
Manufacturer="Minefold"
UpgradeCode="6aad5a10-cbbe-472b-87fc-0813fb450836">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Minefold" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Source="C:\code\Minefold\Minefold\bin\Debug\Minefold.exe" Id="Minefold.exe" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<Feature Id="Application" Title="Minefold" Level="1">
<ComponentRef Id="ProductComponent" />
</Feature>
</Fragment>
</Wix>
Add a Feature with a ComponentGroupRef to your Product. As written, nothing connects the Product with the content in the Fragments.
Related
When using WixQuietExec the command line file I am trying to launch does not appear to run during installation.
My reason for doing this is that the installer I am building necessitates running a number of .exe/.bat files in a particular sequence to build correctly.
.wxs file
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="immediateExecution" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="8b6b82f7-ecbb-426d-bd9a-6fb7548ac349">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="immediateExecution" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="immediateExecution" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
</ComponentGroup>
<Property Id="WixQuietExecCmdLine" Value="blankfile.cmd"/>
<CustomAction Id="QtExecExample" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="immediate" Return="check"/>
<InstallExecuteSequence>
<Custom Action="QtExecExample" Sequence="1"/>
</InstallExecuteSequence>
</Fragment>
</Wix>
blankfile.cmd
cd C:\Users\ljn\Desktop
copy NUL EMptyFile.txt
This is obviously a test case to check the functionality can be achieved in WiX. From the documentation it seems this should be easily achievable, yet the example here is not producing the desired result. Is there something wrong with the .wxs file? Please bear in mind that the utils reference has been added correctly in VS.
Following is my code. I need to install the .inf and .cer files after execution of the MSI file. I have tried referring to various wix resources but couldn't find anything. I am testing the installer on a virtual machine but it doesn't seem to work. I am new to wix and need help regarding this by going through the code and pointing out my mistakes.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="Cal" Language="1033" Version="1.0.0.0" Manufacturer="Cal" UpgradeCode="my-code">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes" />
<Feature Id="ProductFeature" Title="Cal" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
<!--<CustomActionRef Id="InstallAction1" />-->
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Cal" />
<Directory Id="SilInst" Name="BackInst">
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="P2">
<File Source="C1.sys" />
</Component>
<Component Id="P6">
<File Source="C1.inf" />
</Component>
<Component Id="P7">
<File Source="C1.cer" />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<CustomAction Id='InstallAction1' Directory='INSTALLFOLDER' ExeCommand='RUNDLL32.EXE SETUPAPI.DLL,InstallHinfSection DefaultInstall 132 C1.inf' Execute='deferred'
Return='check'/>
<CustomAction Id='InstallAction2' Directory='INSTALLFOLDER' ExeCommand='certutil -addstore C1.cer -s -r localMachine trustedpublisher' Execute='deferred'
Return='check'/>
<InstallExecuteSequence>
<Custom Action="InstallAction2" After='InstallFiles'/>
<Custom Action="InstallAction1" After='InstallAction2'/>
</InstallExecuteSequence>
</Fragment>
</Wix>
To troubleshoot, create an installation log, then search for the custom action id.
Installing driver and certificate on machine typically requires elevated permissions. Therefore use Impersonate="no" for your custom actions. See How to run a Custom Action inside an MSI created in WiX with elevated privileges?
I have a component with an IniFile element in my WiX script. I need to set the read and write permissions for the Local Service to the resulting ini-file as the application runs under this account and must be able to read and write from/into the ini-file. The Permission(Ex) elements can't have IniFile as a parent so I don't see the native way in WiX to set permissions to an IniFile element, could anyone suggest a solution? The file is installed into a subfolder of CommonAppData.
The option to include a ready ini-file in the distribution and install it simply as a File is bad for me as the contents of the file depends on the individual installation (paths, computer name etc).
What version of Wix are you using? I am using Wix v3.9 and could get it to work. Well, I don't understand why the PermissionEx element would be concerned about the "Name" attribute of the File tab, especially when PermissionEx is itself nested/a child of the File tag.
Here is my sample project.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="INIFile" Language="1033" Version="1.0.0.0" Manufacturer="Test" UpgradeCode="4549f852-c012-4180-ab66-5d972f3faf53">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="INIFile" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="INIFile" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="ProductComponent">
<File Id="TestFile" KeyPath="yes" Source="E:\Learning\Test Projects\Files\test.txt" Name="test.txt">
<PermissionEx Id="Blah" Sddl="O-AB-C" />
</File>
<IniFile Id="TestIni" Action="addLine" Directory="INSTALLFOLDER" Key="Test" Name="Test" Section="Test" Value="Test"/>
</Component>
</ComponentGroup>
</Fragment>
</Wix>
There is a similar question
Edit context menu (selectiontree) in customize dialog?
but the link in the accepted answer states:
"You cannot remove Entire feature will be installed on local hard drive from the options. It is displayed only when there are subfeatures and enables installation of the subfeatures as well as the feature itself as opposed from Will be installed on local hard drive which installs only the selected features and does not affect subfeatures."
However, I have no subfeatures. How to remove the Entire feature... option?
Here's the code below:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="WixTestFeatureTree" Language="1033" Version="1.0.0.0" Manufacturer="TestManufacturer" UpgradeCode="bb04a635-6251-4fd5-8d2f-182d3441dc0a">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<UIRef Id="WixUI_FeatureTree" />
<UIRef Id="WixUI_ErrorProgressText" />
<Feature Id="ExeFeature" Title="The EXE file" Level="1">
<Component Id="TheApp" Guid="*" Directory="INSTALLFOLDER">
<File Id="TestExe" Source="Test.exe" Vital="yes"></File>
</Component>
</Feature>
<Feature Id="PdfFeature" Title="The PDF file" Level="1">
<Component Id="ThePDF" Guid="*" Directory="INSTALLFOLDER">
<File Id="TestPDF" Source="Test.pdf" Vital="yes"></File>
</Component>
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixTestFeatureTree" />
</Directory>
</Directory>
</Fragment>
</Wix>
It looks Windows Installer always displays Entire feature will be installed on local hard drive item even if there are no subfeatures. At least this item was present in all the cases that I tested where there were no visible subfeatures. It could also depend on the version of Windows Installer, I tested in Windows 7 with all the latest updates.
I've always thought Windows Installer doesn't display Entire feature will be installed on local hard drive item for a feature which has no subfeatures. Latest tests proved I was wrong.
You need to add the UI type in order to have a different UI in the installer.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="WixTestFeatureTree" Language="1033" Version="1.0.0.0" Manufacturer="TestManufacturer" UpgradeCode="bb04a635-6251-4fd5-8d2f-182d3441dc0a">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<UI Id="MyWixUI_FeatureTree">
<UIRef Id="WixUI_FeatureTree" />
</UI>
<UIRef Id="WixUI_ErrorProgressText" />
<Feature Id="ExeFeature" Title="The EXE file" Level="1">
<Component Id="TheApp" Guid="*" Directory="INSTALLFOLDER">
<File Id="TestExe" Source="Test.exe" Vital="yes"></File>
</Component>
</Feature>
<Feature Id="PdfFeature" Title="The PDF file" Level="1">
<Component Id="ThePDF" Guid="*" Directory="INSTALLFOLDER">
<File Id="TestPDF" Source="Test.pdf" Vital="yes"></File>
</Component>
</Feature>
<UIRef Id="WixUI_Mondo"></UIRef>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="WixTestFeatureTree" />
</Directory>
</Directory>
</Fragment>
</Wix>
add <UIRef Id="WixUI_Mondo"></UIRef> , also add reference to WixUIExtension.dll
each feature has **Level**attribute, level=1 meaning the feature will be installed, if you change the level for 1000 for example the user can pick in the custom dialog weather he wants to install this feature or not
This is an example of what I'm trying to do:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="MySoftware" UpgradeCode="d2192e52-f4f6-461c-9d8e-eb66067df09a">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate />
<Feature Id="ProductFeature" Title="SetupProject1" Level="1">
<ComponentGroupRef Id="ProductComponents" />
</Feature>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="[Manufacturer] SetupProject1" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<!-- TODO: Remove the comments around this Component element and the ComponentRef below in order to add resources to this installer. -->
<!-- <Component Id="ProductComponent"> -->
<!-- TODO: Insert files, registry keys, and other resources here. -->
<!-- </Component> -->
<Component Id="CMP_NEW">
<File Id="FILE_NEW" Source="New Text Document.txt" KeyPath="yes" />
</Component>
</ComponentGroup>
</Fragment>
The folder that created in ProgramFiles is [Manufacturer] SetupProject1 and not MySoftware SetupProject1. Do I do it right? If not, how can I do it please?
Create a variable $(var.Manufacturer) and use it like so:
Define like this: <?define Manufacturer = "MySoftware"?>
<Product Id="*" Name="SetupProject1" Language="1033" Version="1.0.0.0" Manufacturer="$(var.Manufacturer)" UpgradeCode="d2192e52-f4f6-461c-9d8e-eb66067df09a">
<Directory Id="INSTALLFOLDER" Name="$(var.Manufacturer) SetupProject1" />
That will work..:)
The problem I have is that you can't set the preprocessor variable to a value defined during the installation, say in the UI. I'm trying to set the directory name to a property that is given by the User.
So far the key way I've seen to get around this is to use a custom action to change the Directory datatable to the value of the property you would otherwise reference. Just make sure you time the custom action so that it doesn't happen before the directory is normally set, otherwise it might be overwritten.
I'm still looking for something a little prettier however.