My requirement is to create a directory in programdata/test/example. How can I do that in wix?
Define the folder like this:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="CommonAppDataFolder">
<Directory Id="TestFolder" Name="test">
<Directory Id="ExampleFolder" Name="example" />
</Directory>
</Directory>
</Directory>
The important part here is the CommonAppDataFolder Id, which is known by Windows installer. You can find the full list of known system folders in the Windows Installer Property Reference.
If you install any files to that folder, it will be created implicitly. If not, you can force it to be created by installing a component like this:
<Component Id="CreateTestFolder" Directory="ExampleFolder" Guid="PUT-RANDOM-GUID-HERE">
<CreateFolder />
</Component>
Under <Product> you can enter:
<DirectoryRef Id="TARGETDIR">
<Directory Id="CommonAppDataFolder">
<Directory Id="CommonAppXXXX" Name="test">
<Directory Id="CommonAppYYYY" Name="example">
<Component Id="CreateProgramDataZZZ" Guid="ABC-ETC">
<CreateFolder />
</Component>
</Directory>
</Directory>
</Directory>
</DirectoryRef>
And reference the component CreateProgramDataZZZ in your feature.
It can also be helpful to set permissions on the directory like this:
<CreateFolder>
<util:PermissionEx User="Users" GenericAll="yes" />
</CreateFolder>
(in place of <CreateFolder />)
this will create folder for you...
<Directory Id="DIR_ID" Name="DIR_NAME">
<Component Guid="GUID" Id="id" KeyPath="no" NeverOverwrite="no" Permanent="no" Location="local">
<CreateFolder>
<util:PermissionEx CreateChild="yes" CreateFile="yes" Delete="yes" Read="yes" ReadAttributes="yes" ReadExtendedAttributes="yes" ReadPermission="yes" Traverse="yes" GenericRead="yes" GenericWrite="yes" User="Everyone" />
</CreateFolder>
</Component>
</Directory>
Related
this is the markup i used to create the directory structure and create sub directories. it does work just fine. it creates the software directory of the c:\ root and creates the sub directories under that. But then i add a new component group called "shortcuts". I want to create a short cut on the start menu and a desktop icon.i am not sure of what to call the id where the ?????? are in the start menu directory. i also get the following error when i build the project.
Error 1 The Component/#Directory attribute was not found; it is required.
it occurs twice. one at this line Component Id="cmpStartMenuShortcut" and one at this line Component Id="cmpDesktopShortcut"
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="WINDOWSVOLUME">
<Directory Id="SoftwareDirectory" Name="UnionAdministrator">
<Directory Id="RuntimeFolder" Name="Runtime" />
<Directory Id="ReportsFolder" Name="Reports" />
<Directory Id="TasksFolder" Name="Tasks" />
<Directory Id="DebugLogsFolder" Name="DebugLogs" />
</Directory>
</Directory>
<Directory Id ="FontsFolder" />
<Directory Id ="???????????r">
<Directory Id="AppStartMenuFolder" Name="Runtime" />
</Directory>
<Directory Id="DesktopFolder" />
</Directory>
<SetDirectory Id="WINDOWSVOLUME" Value="[WindowsVolume]" />
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents">
<Component Id="cmpCreateRuntimeFolder"
Guid="{27D409D8-8D86-4CB0-8165-E30A6E3998EC}"
Directory="RuntimeFolder">
<CreateFolder />
</Component>
<Component Id="cmpCreateReportsFolder"
Guid="{9621003B-0BDC-44D8-B981-C5B9CA76C733}"
Directory="ReportsFolder">
<CreateFolder />
</Component>
<Component Id="cmpCreateTasksFolder"
Guid="{785A0024-16B2-499D-9B67-6BCBB8094C55}"
Directory="TasksFolder">
<CreateFolder />
</Component>
<Component Id="cmpCreateDebugLogsFolder"
Guid="{9C91955B-967A-411D-ACD9-6C6AA15F84E8}"
Directory="DebugLogsFolder">
<CreateFolder />
</Component>
</ComponentGroup>
</Fragment>
<Fragment>
<ComponentGroup Id="Shortcuts">
<Component Id="cmpStartMenuShortcut"
Guid="{2A561F4E-118A-4927-9C29-7FF441B77097}">
<Shortcut Id="StartMenuShortcut"
Name="Union Adminstrator"
Description="Runs UnionAdminstrator"
Directory="AppStartMenuFolder"
Target="[RuntimeFolder]UnionAdministrator.exe" />
</Component>
<Component Id="cmpDesktopShortcut"
Guid="{6A686136-06D9-469B-93BA-076D5F32D46B}">
<Shortcut Id="DesktopShortcut"
Name="Union Adminstrator"
Description="Runs UnionAdminstrator"
Directory="DesktopFolder"
Target="[#FILE_UAEXE] " />
</Component>
</ComponentGroup>
</Fragment>
Give directory for shortcuts.and assign it like you have done for other components.
Also since you cant give shortcut as keypath, you could keep registry in shortcut component as keypath.
I'm a beginner in WIX. I want to create multiple folders inside the main folder, but ending with just one folder. Can someone help me on how to create multiple folders?
<!-- Step 1: Define the directory structure -->
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="TEST">
<Directory Id="HTML" Name="HTML" />
</Directory>
</Directory>
</Directory>
<!-- Step 2: Add files to your installer package -->
<DirectoryRef Id="APPLICATIONROOTDIRECTORY">
<Component Id="NewSHU_TM.exe" Guid="3977B09E-B696-471A-9C29-419301EDF6A0">
<File Id="NewSHU_TM.exe" Source="C:\Program Files\Debug\NewSHU_TM.exe" KeyPath="yes" Checksum="yes"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="HTML">
<Component Id="exec.html" Guid="61D58D90-F9A3-4649-9113-6AD7B1249DE8">
<File Id="exec.html" Source="C:\Program Files\Debug\HTML\exec.html" KeyPath="yes" Checksum="yes"/>
<File Id="exec_001.html" Source="C:\Program Files\Debug\HTML\exec_001.html" KeyPath="no" Checksum="yes"/>
</Component>
</DirectoryRef>
<!-- Step 3: Tell WiX to install the files -->
<Feature Id="MainApplication" Title="Main Application" Level="1">
<ComponentRef Id="NewSHU_TM.exe" />
<ComponentRef Id="exec.html"/>
<!--<ComponentRef Id="documentation.html" />-->
</Feature>
</Product>
You need to nest the directories you want to install to within TARGETDIR:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Component Id="ApplicationFiles" Guid="12345678-1234-1234-1234-222222222222">
<File Id="ApplicationFile1" Source="example.exe"/>
</Component>
</Directory>
</Directory>
</Directory>
See the source for this sample here:
http://www.codeproject.com/Tips/105638/A-quick-introduction-Create-an-MSI-installer-with
You need to close each "Directory" element. Please notice the endding "/>" in the "TEST" and "HTML" folder below.
The following will create (given you are adding files to these directories) the two folders at the same level under the "Example" folder:
c:\Program Files (x86)\Example\TEST and
c:\Program Files (x86)\Example\HTML
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="Example">
<Directory Id="ChildFolder1" Name="TEST" />
<Directory Id="ChildFolder2" Name="HTML" />
</Directory>
</Directory>
I have built a WiX installer for an application and in it I need to copy some files to a specific folder on the "C:" drive. I originally coded my directories like this:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyCompanyInstall" Name="MyCompany">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" />
</Directory>
</Directory>
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="[WindowsVolume]\MyCompany">
<Directory Id="MYCOMPANYMYSPECIALFOLDERDATAFOLDER" Name="MySpecialFolder">
<Directory Id="MYCOMPANYMYSPECIALFOLDERTRENDINGFOLDER" Name="Trending"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="MyCompanyProgramMenu" Name="MyCompany">
<Directory Id="ProgramMenuDir" Name="$(var.ProductName)"/>
</Directory>
</Directory>
<Directory Id="DesktopFolder"/>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="MYCOMPANYROOT">
<Component Id="CreateDirectories" Guid="60D9E460-89C8-42D2-8581-D858785A1817">
<CreateFolder Directory="MYCOMPANYROOT"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTDATAFOLDER"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTTRENDINGFOLDER"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<DirectoryRef Id="MYCOMPANYMYPRODUCTDATAFOLDER">
<Component Id="FirstFile.xml" Guid="E9879B51-1C74-47BF-A475-3B77D66297E2">
<File Id="FirstFile.xml" Source="$(var.TargetDir)FirstFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="SecondFile.xml" Guid="69A86F79-4596-4714-9FE7-628882ADA303">
<File Id="SecondFile.xml" Source="$(var.TargetDir)SecondFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="MyCompanyMyProductHelp.pdf" Guid="D2D3CDF1-61FA-4021-8F56-F23770580AA0">
<File Id="MyCompanyMyProductHelp.pdf" Source="$(var.TargetDir)Documents\MyCompany My Product Help.pdf" KeyPath="yes" Checksum="yes"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<Icon Id="$(var.ProductName)Icon.EXE" SourceFile="$(var.TargetPath)"/>
</Fragment>
But on one computer in the office I kept getting the case that the files meant for "C:\MyCompany\MySpecialFolder\" were not copied. I then tried to hard code the "C:" drive like so:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyCompanyInstall" Name="MyCompany">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" />
</Directory>
</Directory>
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="C:\MyCompany">
<Directory Id="MYCOMPANYMYSPECIALFOLDERDATAFOLDER" Name="MySpecialFolder">
<Directory Id="MYCOMPANYMYSPECIALFOLDERTRENDINGFOLDER" Name="Trending"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="MyCompanyProgramMenu" Name="MyCompany">
<Directory Id="ProgramMenuDir" Name="$(var.ProductName)"/>
</Directory>
</Directory>
<Directory Id="DesktopFolder"/>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="MYCOMPANYROOT">
<Component Id="CreateDirectories" Guid="60D9E460-89C8-42D2-8581-D858785A1817">
<CreateFolder Directory="MYCOMPANYROOT"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTDATAFOLDER"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTTRENDINGFOLDER"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<DirectoryRef Id="MYCOMPANYMYPRODUCTDATAFOLDER">
<Component Id="FirstFile.xml" Guid="E9879B51-1C74-47BF-A475-3B77D66297E2">
<File Id="FirstFile.xml" Source="$(var.TargetDir)FirstFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="SecondFile.xml" Guid="69A86F79-4596-4714-9FE7-628882ADA303">
<File Id="SecondFile.xml" Source="$(var.TargetDir)SecondFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="MyCompanyMyProductHelp.pdf" Guid="D2D3CDF1-61FA-4021-8F56-F23770580AA0">
<File Id="MyCompanyMyProductHelp.pdf" Source="$(var.TargetDir)Documents\MyCompany My Product Help.pdf" KeyPath="yes" Checksum="yes"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<Icon Id="$(var.ProductName)Icon.EXE" SourceFile="$(var.TargetPath)"/>
</Fragment>
But I got the same results.
Does anyone know why this won't work on only one machine?
Well I stumbled upon a fix. I don't understand why this fixes it, but it now works.
The key was to add the line:
<SetDirectory Id="MYCOMPANYROOT" Value="[WindowsVolume]MyCompany"/>
I would have thought that the "FileSource" attribute in the "Directory" tag would have done the trick, but alas it didn't.
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="[WindowsVolume]MyCompany">
I don't really understand why I needed this. If someone could explain, I would appreciate it.
Code follows:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="MyCompanyInstall" Name="MyCompany">
<Directory Id="INSTALLFOLDER" Name="$(var.ProductName)" />
</Directory>
</Directory>
<Directory Id="MYCOMPANYROOT" Name="MyCompany" FileSource="[WindowsVolume]MyCompany">
<Directory Id="MYCOMPANYMYSPECIALFOLDERDATAFOLDER" Name="MySpecialFolder">
<Directory Id="MYCOMPANYMYSPECIALFOLDERTRENDINGFOLDER" Name="Trending"/>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="MyCompanyProgramMenu" Name="MyCompany">
<Directory Id="ProgramMenuDir" Name="$(var.ProductName)"/>
</Directory>
</Directory>
<Directory Id="DesktopFolder"/>
</Directory>
</Fragment>
<Fragment>
<!-- New line -->
<SetDirectory Id="MYCOMPANYROOT" Value="[WindowsVolume]MyCompany"/>
<!-- -->
<DirectoryRef Id="MYCOMPANYROOT">
<Component Id="CreateDirectories" Guid="60D9E460-89C8-42D2-8581-D858785A1817">
<CreateFolder Directory="MYCOMPANYROOT"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTDATAFOLDER"/>
<CreateFolder Directory="MYCOMPANYMYPRODUCTTRENDINGFOLDER"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<DirectoryRef Id="MYCOMPANYMYPRODUCTDATAFOLDER">
<Component Id="FirstFile.xml" Guid="E9879B51-1C74-47BF-A475-3B77D66297E2">
<File Id="FirstFile.xml" Source="$(var.TargetDir)FirstFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="SecondFile.xml" Guid="69A86F79-4596-4714-9FE7-628882ADA303">
<File Id="SecondFile.xml" Source="$(var.TargetDir)SecondFile.xml" KeyPath="yes" Checksum="yes"/>
</Component>
<Component Id="MyCompanyMyProductHelp.pdf" Guid="D2D3CDF1-61FA-4021-8F56-F23770580AA0">
<File Id="MyCompanyMyProductHelp.pdf" Source="$(var.TargetDir)Documents\MyCompany My Product Help.pdf" KeyPath="yes" Checksum="yes"/>
</Component>
</DirectoryRef>
<!-- trimmed -->
<Icon Id="$(var.ProductName)Icon.EXE" SourceFile="$(var.TargetPath)"/>
</Fragment>
Have a read up on TARGETDIR, you will see that this links to ROOTDRIVE, which states:
If ROOTDRIVE is not set at a command line or authored into the
Property table, the installer sets this property. During an
administrative installation the installer sets ROOTDRIVE to the first
connected network drive it finds that can be written to. If it is not
an administrative installation, or if the installer can find no
network drives, the installer sets ROOTDRIVE to the local drive that
can be written to having the most free space.
So I suspect that on the single machine which you are having issues with, that it has another local drive with more space than c:
I had a similar problem.
On one of our machines WIX installed on E drive (flash disk) instead of C dive.
I have come across this answer which solve my problem: https://stackoverflow.com/a/8591139/1891969
Just replace the TARGETDIR value with "C:\".
<InstallExecuteSequence>
<Custom Action="FormatTargetDirectory" After="CostFinalize">NOT Installed</Custom>
</InstallExecuteSequence>
<CustomAction Directory="TARGETDIR" Value="[DRIVE_NAMES]" Id="FormatTargetDirectory"/>
How do I create a shortcut on the desktop from a wix setup project?
The shortcut is a non-advertised one.
Remember to put the component in your feature tag.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="ApplicationShortcutDesktop" Guid="*">
<Shortcut Id="ApplicationDesktopShortcut"
Name="Text under your icon"
Description="Comment field in your shortcut"
Target="[MYAPPDIRPROPERTY]MyApp.exe"
WorkingDirectory="MYAPPDIRPROPERTY"/>
<RemoveFolder Id="DesktopFolder" On="uninstall"/>
<RegistryValue
Root="HKCU"
Key="Software\MyCompany\MyApplicationName"
Name="installed"
Type="integer"
Value="1"
KeyPath="yes"/>
</Component>
</Directory>
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="MyCompany" Name="MyCompany">
<Directory Id="MYAPPDIRPROPERTY" Name="MyAppName">
<!-- main installation files -->
</Directory>
</Directory>
</Directory>
</Directory>
I think my way is easier, no need for you to create a registry key:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" SourceName="Desktop" />
<Directory Id="MergeRedirectFolder">
<Component Id="MyExeComponent" Guid="{PUT-GUID-HERE}">
<File Id="MyExeFile" Source="$(var.ExeSourcePath)" KeyPath="yes">
<Shortcut
Id="DesktopShortcut"
Directory="DesktopFolder"
Name="$(var.ShortcutName)"
WorkingDirectory="MergeRedirectFolder" />
</File>
</Component>
</Directory>
</Directory>
Thanks for example. In WIX 3.8 it still raises:
"Error 3 ICE43: Component ... has non-advertised shortcuts. It should use a registry key under HKCU as its KeyPath, not a file."
So I did this such way in a file with features:
<Component Id="cmp79F6D61F01DD1060F418A05609A6DA70"
Directory="dirBin" Guid="*">
<File Id="fil34B100315EFE9D878B5C2227CD1454E1" KeyPath="yes"
Source="$(var.SourceDir)\FARMS.exe" >
<Shortcut Id="DesktopShortcut"
Directory="DesktopFolder"
Name="FARMS $(var.FarmsVersion)"
Description="Local Land Services desktop application"
WorkingDirectory="INSTALLFOLDER"
Icon="FARMS.exe"
IconIndex="0"
Advertise="yes" >
<Icon Id="FARMS.exe" SourceFile="$(var.SourceDir)\FARMS.exe" />
</Shortcut>
</File>
</Component>
And mentioned desktop folder in a file with product definition:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop" />
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="FARMS" >
</Directory>
</Directory>
</Directory>
</Fragment>
It seems lot easier in this documentation.
First, you have to point your DesktopFolder,
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="DesktopFolder" Name="Desktop"/>
Then you should create Shortcut component for file that you want to create shortcut of.
<Component Id="PutYourComponentIdHere" Directory="FileDirectory" Guid="*">
<File Id="NotYourComponentId" KeyPath="yes" Source="..\YourFileSource\YourExecutable.exe">
<Shortcut Id="desktopServer" Directory="DesktopFolder" Name="YourShourtcutName" WorkingDirectory='WhereShouldYourShortcutPoint' Advertise="yes"/>
</File>
</Component>
It worked for me. I need to put icon but thats easy part. Hope it works.
After too much effort, I used this way:
<Product ...>
<Feature Id="ProductFeature" Title="SetupProject" Level="1">
...
...
<ComponentRef Id="cmpDesktopShortcut" />
</Feature>
<Component Id="cmpDesktopShortcut" Guid="PUT-GUID-HERE" Directory="DesktopFolder" >
<Shortcut Id="MyDesktopShortcut"
Name="Setup Project"
Description="Opens the program."
Directory="DesktopFolder"
Target="[INSTALLFOLDER]App.exe"
WorkingDirectory="INSTALLFOLDER"/>
<RegistryValue Root="HKCU" Key="Software\My Company\Sample Application" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</Product>
I believe that using a "Current User" (HKCU) registry key as Key Path causes problems on a multi-user machine tool. Because the registry key is only created for the current user and when a different user logs in, then the auto-repair of the installation kicks in.
I'm having trouble setting the working directory of a shortcut created as part of a WiX script. Here are the basics:
<!-- create a start menu shortcut. -->
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="My Name">
<Component Id="ApplicationShortcut" Guid="822A26AF-5231-4EDA-A18D-5DF15020BD94">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="My Name"
Description="My Description"
Target="[INSTALLLOCATION]My.exe"
WorkingDirectory="INSTALLLOCATION" />
<RemoveFolder Id="ApplicationProgramsFolder" On="uninstall"/>
</Component>
</Directory>
</Directory>
<!-- Install the app. -->
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="My Name">
<Component Id="ProductComponent" Guid="4740357A-69D3-4626-A0F7-D0667C93A2CE">
<File Id="My.exe" Name="My.exe" Source="My.exe" />
</Component>
</Directory>
</Directory>
This jives with examples I've seen, and the shortcut gets created, and it points to the right exe, but the shortcut has no working directory specified, and so the app doesn't find its local resources.
You don't need to say [INSTALLLOCATION] because the ShortCut table defines the WkDir column describes "The name of the property that has the path of the working directory for the shortcut."
I would reccomend trying this:
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationProgramsFolder" Name="My Name">
</Directory>
</Directory>
<!-- Install the app. -->
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLLOCATION" Name="My Name">
<Component Id="ProductComponent" Guid="4740357A-69D3-4626-A0F7-D0667C93A2CE">
<File Id="My.exe" Name="My.exe" Source="My.exe" />
<Shortcut Id="ApplicationStartMenuShortcut"
Advertise="yes"
Name="My Name"
Description="My Description"
Directory="ApplicationProgramsFolder"
WorkingDirectory="INSTALLLOCATION">
<Icon Id="My.exe" SourceFile="My.exe" />
<Shortcut>
</Component>
</Directory>
</Directory>
I think you need square brackets around your INSTALLLOCATION in the working directory attribute.