In WiX I have
<Directory Id="CommonAppDataFolder">
<Directory Id="CommonAppDataManufacturerFolder" Name="$(var.MANUFACTURER)">
<Directory Id="AppDataFolder" Name="$(var.PRODUCTNAME)">
<Directory Id="DatasFolder" Name="Datas"/>
</Directory>
</Directory>
</Directory>
and
<ComponentGroup Id="DatasComponents" Directory="DatasFolder">
<Component Id="Database.sdf" Guid="4c33c78e-7113-4a8c-b9fd-6ba4f6490935">
<File Id="Database.sdf" Source="Database.sdf" />
<RemoveFolder Id='DatasFolder' On='uninstall' />
<RegistryValue Root='HKCU'
Key='Software\[Manufacturer]\[ProductName]'
Type='string'
Value=''
KeyPath='yes' />
</Component>
</ComponentGroup>
But the file is being copied to C:\Users\username\AppData\Roaming\Datas\ instead of %ProgramData%\Manufacturer\ProductName\Datas\
The problem is that AppDataFolder is a reserved keyword that takes you to the Roaming data folder, I simply changed this id to a non-reserved keyword and my code worked
<Directory Id="CommonAppDataFolder">
<Directory Id="CommonAppDataManufacturerFolder" Name="$(var.MANUFACTURER)">
<Directory Id="MyAppDataFolder" Name="$(var.PRODUCTNAME)">
<Directory Id="DatasFolder" Name="Datas"/>
</Directory>
</Directory>
</Directory>
Related
For my application, most of the files need to be installed to a directory in ProgramFiles, and one other file needs to be installed in a directory in AppData/Local.
Here is an example of what I have so far:
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="Folder1" />
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="AppID" Directory="INSTALLFOLDER">
<Component Id="AppID">
<File Source="$(var.myApp.TargetPath)" />
</Component>
<Component Id="OtherFile" Guid="INSERT-GUID_HERE">
<File Id='OtherFile' Name='OtherFile' Source="otherfile" KeyPath='yes' />
</Component>
<Component Id="CopyId">
<CopyFile Id="CopyId" FileId="OtherFile"
DestinationDirectory="LocalAppDataFolder" />
</Component>
</Fragment>
I've tried to copy the other file to AppData/Local but this won't compile and gives the error:
Unresolved reference to symbol 'Directory:LocalAppDataFolder' in section 'Fragment:'
Ideally, I want the other file to be in directory in AppData/Local, and not in ProgramFiles at all.
Application Launch: Consider doing file-copying on application launch instead of as part of the setup. Easier to implement, debug and change as you need to.
Fix: Try just adding this directly under the TARGETDIR element. This ensures that the standard directory LocalAppDataFolder is part of the compiled MSI file's Directory table:
<Directory Id="LocalAppDataFolder" Name="AppData">
Alternatively, here is a larger mock-up:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SetupProject2" />
</Directory>
<Directory Id="LocalAppDataFolder" Name="AppData">
<Directory Id="AppRootDirectory" Name="MyApplication">
<Component Id="Test" Feature="ProductFeature" Guid="{11111111-1111-1111-1111-A73067A1AE95}">
<RemoveFolder Id="AppRootDirectory" On="uninstall" />
<RegistryValue Root="HKCU" Key="Software\Something" Name="Flag" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</Directory>
</Directory>
</Directory>
I'm trying to to write installer for 3rd-party application.
The service should be installed and running with arguments. One of the argument it's home folder where the service was installed.
How I can read the folder where the application was installed and pass it to Wix Element: ServiceInstall as arguments.
<ServiceInstall Id="SInstall"
Type="ownProcess"
Name="myservice"
DisplayName="MyService"
EraseDescription="no"
Start="demand"
ErrorControl="normal"
Arguments="-folder '[INSTALLDIR]\config.txt'>
But [INSTALLDIR] is empty;
I suppose it's should be done by using SetProperty and read it but cannot find any references how to do this.
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="ManufacturerFolder" Name="OEM_XXX">
<Directory Id="INSTALLFOLDER" Name="Product $(var.ProductVersion)">
<Directory Id="DirA" />
<Directory Id="DirB" Name="SubService">
<Directory Id="DirC" Name="ComponentA">
<Directory Id="ComponentB" Name="content" />
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<DirectoryRef Id="DirB">
<Component Id="Svc1" Guid="b033eb95-ce88-48ac-b40f-6913c5e4b978" Win64="yes">
<File Source="$(var.SourceDir)\service.exe" />
<ServiceInstall Id="SInstall"
Type="ownProcess"
Name="myservice"
DisplayName="MyService"
EraseDescription="no"
Start="demand"
ErrorControl="normal"
Arguments="-folder '???????\config.txt'>
<ServiceConfig DelayedAutoStart="no" OnInstall="yes" OnReinstall ="yes" />
</ServiceInstall>
<ServiceControl Id="SControl"
Stop="both"
Remove="uninstall"
Name="myservice"
Wait="no" />
</Component>
</DirectoryRef>
</Fragment>
Thanks.
Use [{directoryId} as a reference;
In my case it was
<ServiceInstall Id="SInstall"
Type="ownProcess"
Name="myservice"
DisplayName="MyService"
EraseDescription="no"
Start="demand"
ErrorControl="normal"
Arguments='-folder "[DirB]config.txt"'>
The full list of available system folder you can find on MSDN:
https://learn.microsoft.com/en-us/windows/desktop/msi/property-reference#system-folder-properties
Sometimes names can confuse you but read description.
For example if you would like to define a path to %PROGRAMDATA% you should use [CommonAppDataFolder]
P.S. Build-in variables ends with trailing slash
I have the following shortcut definition:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFiles64Folder">
<Directory Id="INSTALLFOLDER" Name="InGenius">
<Directory Id="APPLICATIONFODLER" Name="ICE Publisher" />
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder">
<Directory Id="CompanyFolder" Name="InGenius">
<Directory Id="AppFolder" Name="ICE Publisher" />
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="AppFolder">
<Component Id="ApplicationShortcut" Guid="*">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="App CMD Prompt"
Target="[SystemFolder]CMD.exe"
Arguments="/K [APPLICATIONFOLDER]app.bat"
WorkingDirectory="APPLICATIONFOLDER"
Show="normal"/>
<RemoveFolder Id="CompanyFolder" Directory="CompanyFolder"
On="uninstall" />
<RemoveFolder Id="AppFolder" On="uninstall" />
<RegistryValue Root="HKCU"
Key="Software\Microsoft\InGenius ICE Publisher"
Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
I get a shortcut with the following target:
C:\Windows\SysWOW64\cmd.exe /K app.bat
And nothing in the Start in: field.
I was expecting a target of:
C:\Windows\SysWOW64\cmd.exe /K c:\ProgramFiles\appfolder\app.bat
and have
c:\ProgramFiles\appfolder\app.bat
in the Start in: field
What did I do wrong?
Looks like APPLICATIONFOLDER property is not set. Check its value in debug log and set the value of APPLICATIONFOLDER property before installation starts.
I want to create a subfolder in start menu, in my case PMFCompanyFolder already exists and contains links and I don't want remove when uninstalling my product.
So I don't push the RemoveFolder Property and I get :
ICE64: The directory PMFCompanyFolder is in the user profile but is not listed in the RemoveFile table.
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramMenuFolder">
<Directory Id="PMFCompanyFolder" Name="MyCompany">
<Directory Id="PMFProductFolder" Name="MyProduct"/>
</Directory>
</Directory>
</Directory>
<DirectoryRef Id="PMFProductFolder">
<Component Id="PMFProductFolderComponent" Guid="A13A7784-4C82-4CBE-9018-CEC6F266743B">
<RemoveFolder Id="null" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\Microsoft\MyCompany\MyProduct" Name="installed" Type="integer" Value="1" KeyPath="yes"/>
</Component>
</DirectoryRef>
<Feature Id="ProductFeature" Title="" Level="1">
<ComponentRef Id="PMFProductFolderComponent"/>
</Feature>
You should pass the folder id:
<RemoveFolder Id="PMFCompanyFolder" On="uninstall"/>
It is safe to remove it on uninstall - pre-existing items will not be removed.
When I'm uninstalling my product directory where custom action binary was placed stays. How can I delete it. Also strange named directory is created on installation - unistallation: "RSCustomActions.CA.dll-" and "RSCustomActions.CA.dll-0" (my binary name RSCustomActions.CA.dll)
My WIX code is
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="Product.Id" Name="Product">
<Directory Id="INSTALLLOCATION" Name="Product">
<!-- TEST -->
<Directory Id="Installer" Name="Installer">
<Component Id="InstallerFiles"
Guid="{0904DB36-2496-419c-A992-B7D86F068F12}">
<File Id="RSCustomActions.CA.dll" Name="RSCustomActions.CA.dll" Source="Binaries\RSCustomActions.CA.dll" />
</Component>
</Directory>
<!-- END TEST -->
<?include "Product.Files.wxi" ?>
</Directory>
</Directory>
</Directory>
<Directory Id="ProgramMenuFolder" Name="PMenu">
<Directory Id="ProgramMenuDir" Name="Aspose">
<?include "Product.ProgramMenu.wxi" ?>
</Directory>
</Directory>
<Component Id="Main" Shared="yes" Guid="{EDD4477A-D188-469c-B8D0-4423377C03C6}" Feature="Main.InstallFeatures">
<RemoveFolder Id="DeleteProgramMenuDir" Directory="ProgramMenuDir" On="uninstall" />
</Component>
</Directory>
"Product.Files.wxi" also contains
<Component Id="Product.Remove" Guid="{C6D9D74C-66E8-442a-8E53-78A8D0E2B24D}">
<RemoveFolder Id="Product.RemoveFolder.Action" On="uninstall"/>
</Component>
Please suggest any way how can I remove Installer folder and those strage folders with binary name.
Thanks!
Why do you need installing the CA DLL as a file of the product? You can simply put it to Binary table and forget about it, like this:
<!-- This is a reference to the DLL where all custom actions reside -->
<Binary Id="CustomActions" SourceFile="$(var.Root)\CA\CustomActions.CA.dll" />
And the custom action definition is something like this:
<!-- Sample CA definition -->
<CustomAction Id="MyAction" BinaryKey="CustomActions" DllEntry="MyActionMethod" />
Note that MyActionMethod should be defined in that CA assembly and marked appropriately. There's a good sample of this in dtf.chm in WiX distribution.
Hope this helps.