WiX Shortcuts Not Detecting Files In Application Directory - wix

Part of my application needs to read a config file, which I keep in the same directory as my application's exe. My issue is that the shortcuts created by WiX don't find this file.
I can create my shortcuts post install, and they work, but I would rather fix this issue instead of doing that.
This is what my component looks like:
<Component Id="MyApp.exe" Guid="G-U-I-D">
<File Id="MyApp.exe" Name="MyApp.exe" Source="$(var.MyApp_TargetDir)MyApp.exe">
<Shortcut Id="DesktopShortcut" Directory="DesktopFolder" Name="My Application" Icon="Icon.ico" Advertise="yes" />
<Shortcut Id="StartMenuShortcut" Directory="ProgramMenuFolder" Name="My App" Icon="Icon.ico" Advertise="yes" />
</File>
</Component>

UPDATE: If I understand your comment correctly, I am wondering if you simply do not set the shortcut's WorkingDirectory attribute?
WiX Markup Sample:
<Directory Id="MyDir" Name="My Dir">
<Component Id="My.exe" Feature="Main">
<File Source="My.exe">
<Shortcut Id="DesktopShortcut"
Directory="DesktopFolder"
Name="My Product"
Advertise="yes"
WorkingDirectory="MyDir">
</Shortcut>
</File>
</Component>
</Directory>
Shortcut Properties:
If this is a settings file that you intend to write to you should put it in the user profile so that it is writeable for the launching user. Your application.exe file should be able to find the config file regardless if it is in your application installation folder or in the user profile?
C# mockup (should use Path.Combine, but this is just for illustration):
string filepath = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile) + #"\MyFolder\MyFile.xml";
Is there a specific need to specify the file path in the shortcuts?
Some Links:
Various ways to deal with config files and writeability.

Related

Wix toolset: How to remove Shortcut on install?

We recently changed the name of our application from let's say test1app to test2app. So now when our customers update my application from the old version to this new one I want the shortcuts for test1app to get removed because I have already removed all the files with that name(I removed them with RemoveFile and RemoveFolder).
Is it possible to remove .lnk files with RemoveFile as well?
I have one shortcut on the desktop and one in the program files.
I have tried to remove the .lnk file with remove file but it does not get removed. I even tried to add a plain .txt file and remove it from the desktop but it does not get removed either so maybe I am calling the wrong Dictionary or something?
This is a snipped from my code:
`<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramMenuFolder">
<Directory Id="ApplicationStartMenuDirectory" Name="Test2"/>
</Directory>
<Directory Id="DesktopFolder" Name="Desktop" />
</Directory>`
`<DirectoryRef Id="ProgramMenuFolder">
<Component Id="delete_test1_shortcuts" Guid="*">`
//Here I am trying to remove the shortcut from the Application start menu dir
`<RemoveFile Directory="ApplicationStartMenuDirectory" Id="test1.lnk_shortcut" Name="test1.lnk" On="install" />
<RegistryValue Root="HKCU" Key="Software\Company\test1" Name="installed" Type="integer" Value="1" KeyPath="yes"/>`
//Here I am trying to remove the desktop shortcut
`<RemoveFile Directory="DesktopFolder" Id="desktop_test1.lnk" Name="test1.lnk" On="install" />
</Component>`
`</DirectoryRef>`
//then reference the component
`<Feature Id="MainApplication" Title="testapp" Level="1">
<ComponentRef Id="delete_test1_shortcuts"/>
</Feature>`
The goal is that when the customers upgrade their version that the all the test1 shortcuts get removed so they only see the test2 shortcuts on install.
Please try this:
Remove the old component containing the old binary (EXE) AND the shortcut (and whatever other content is there).
Add a new component with the new binary (EXE) AND the new shortcut with the new name (important). Make sure it has a new component GUID.
This is all related to how component reference counting is done in MSI: Change my component GUID in wix?
Essentially: there is a 1:1 match between absolute installation path and the component GUID. If one changes, change the other and the older component will be uninstalled as a whole entity: all settings will be removed. There should be no overlapping resources between the components (not the same name shortcut for example).
I am not sure, why it did not work for you, I just had to do the same and the code below worked for me (some properties omitted for clarity). Wix 3.11.2
<DirectoryRef Id="ProgramMenuFolder">
<Component Id="StartMenuShortcut" Guid="{guid}">
<Shortcut Id="StartMenuShortcut"
Name="Myapp"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<!-- added the line below -->
<RemoveFile Id="RemoveOldStartMenuShortcut" On="install" Name="MyOldShortcut.lnk"/>
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="DesktopShortcut" Guid="{guid}">
<Shortcut Id="DesktopShortcut"
Name="Myapp"
WorkingDirectory="APPLICATIONROOTDIRECTORY"/>
<!-- added the line below -->
<RemoveFile Id="RemoveOldDesktopShortcut" On="install" Name="MyOldShortcut.lnk"/>
</Component>
</DirectoryRef>

Files not getting copied to install directory using WIX and WAX

I have some additional unmanaged dll's that need to be copied to the install folder. I am using WAX as well as it is supposed to make Wix easier to use. I have added the following markup to Product.wxs:
<Component Id="DataModel1.csdl" Guid="f8fb154d-f0c9-40f5-9bcf-593ed9540bda" Directory="INSTALLFOLDER">
<File Id="DataModel1.csdl" Name="DataModel1.csdl" Source="$(var.FLIR_TargetDir)DataModel1.csdl" />
</Component>
<Component Id="DataModel1.ssdl" Guid="a13c3c3b-e6a6-40ea-b9d8-84fd093ca0d5" Directory="INSTALLFOLDER">
<File Id="DataModel1.ssdl" Name="DataModel1.ssdl" Source="$(var.FLIR_TargetDir)DataModel1.ssdl" />
</Component>
<Component Id="DataModel1.msl" Guid="e308d75b-1f0b-4234-843d-6b44af2e80a9" Directory="INSTALLFOLDER">
<File Id="DataModel1.msl" Name="DataModel1.msl" Source="$(var.FLIR_TargetDir)" />
</Component>
<Component Id="Devart.Data.dll" Guid="a95a3053-7d4a-4030-b8c9-9d860a81a221" Directory="INSTALLFOLDER">
<File Id="Devart.Data.dll" Name="Devart.Data.dll" Assembly=".net" KeyPath="yes" Source="C:\Program Files (x86)\Devart\dotConnect\SQLite\Devart.Data.dll" />
</Component>
<Component Id="Devart.Data.SQLite.dll" Guid="16d0ca3c-425d-49e9-a754-043b0b9e4ada" Directory="INSTALLFOLDER">
<File Id="Devart.Data.SQLite.dll" Name="Devart.Data.SQLite.dll" Assembly=".net" KeyPath="yes" Source="C:\Program Files (x86)\Devart\dotConnect\SQLite\Devart.Data.SQLite.dll" />
</Component>
The files shows up as an unmapped file in the unmapped files area of the UI:
When the install happens the files do not get installed into the installation folder. What am I doing wrong?
The Assembly=".NET" tell's MSI to install the files in the Global Assembly Cache. The parent directory element is ignored/overridden. See:
http://wixtoolset.org/documentation/manual/v3/xsd/wix/file.html
If your looking for a tool to make WiX easier to learn/use then I'd suggest my own open source project:
https://github.com/iswix-llc/iswix-tutorials

WIX - Rename shortcut in MSP

I am not that experienced with WiX and I am having a problem when renaming a shortcut during update via MSP. In my previous MSI I have created a desktop shortcut using the following
<DirectoryRef Id="TARGETDIR">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="MyShortcut" Guid="38EF1A86-5D1B-4D78-AD66-DD1AA6635A9B" Win64="$(var.Variables_Win64)" MultiInstance="no">
<Shortcut Id="MyShortcut"
Directory="DesktopFolder"
Icon="MyIcon"
Name="My Application"
Description="Runs my application"
Target="[URL]" />
<RemoveFolder Id='DesktopFolder' On='uninstall'/>
</Component>
</Directory>
</DirectoryRef>
In my MSP I want to rename the schortcut as such
<DirectoryRef Id="TARGETDIR">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="MyShortcut" Guid="38EF1A86-5D1B-4D78-AD66-DD1AA6635A9B" Win64="$(var.Variables_Win64)" MultiInstance="no">
<Shortcut Id="MyShortcut"
Directory="DesktopFolder"
Icon="MyIcon"
Name="My New Application"
Description="Runs my new application"
Target="[URL]" />
<RemoveFolder Id='DesktopFolder' On='uninstall'/>
</Component>
</Directory>
</DirectoryRef>
What I get when I run my upgrade is a new desktop shortcut as well as the orphaned old shortcut. I understand why this is happening from this post why two shortcuts after Major upgrade (migration)? but I am not sure how I can work around this behaviour and either update the original shortcut name or delete the orphaned one instead. I cannot build an MSI it has to be an MSP so any advice would be welcome.
Thank you in advance ;-)
The solution appears to be add in a RemoveFile but with the full name including extension to the shortcut. I had initially tried this approach before posting but had not specified the .lnk on the name so it did not work.
<DirectoryRef Id="TARGETDIR">
<Directory Id="DesktopFolder" Name="Desktop">
<Component Id="MyShortcut" Guid="38EF1A86-5D1B-4D78-AD66-DD1AA6635A9B"
Win64="$(var.Variables_Win64)" MultiInstance="no">
<Shortcut Id="MyShortcut"
Directory="DesktopFolder"
Icon="MyIcon"
Name="My New Application"
Description="Runs my new application"
Target="[URL]" />
<RemoveFolder Id='DesktopFolder' On='uninstall'/>
<RemoveFile Id='LegacyShortcut ' Name='My Application.lnk' On='install'/>
</Component>
</Directory>
</DirectoryRef>

Wix:How Can I Create Shortcut Without Registry

In our project, we are going to remove registry entries to make non-admin users able to install it.
Our current code is as follow, I tried to comment out the section from the XML file but failed.
Is there any chance that we can create the shotcut without registry key? thanks.
<DirectoryRef Id="ApplicationProgramsFolder">
<Component Id="ApplicationShortcut" Guid="C85221B1-70CA-455D-B322-093543BD4DF0">
<Shortcut Id="ApplicationStartMenuShortcut"
Name="$(var.ProductName)"
Description="$(var.ProductDescription)"
Target="[APPLICATIONROOTDIRECTORY]OMOffline.exe"
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
<Shortcut Id="RemoteAssistance"
Name="Request Remote Assistance"
Description="Starts Remote Assistance and creates a password-protected RA ticket that is attached to a new Remote Assistance invitation. The User must enter the e-mail address of the Helper in the To field to send the message to the Helper."
Target="[SystemFolder]MSRA.exe"
Arguments="/email"/>
<Shortcut Id="UninstallProduct"
Name="Uninstall $(var.ProductName)"
Target="[SystemFolder]msiexec.exe"
Arguments="/x [ProductCode] SQLSERVER="[SQLSERVER]""
Description="Uninstalls $(var.ProductName)" />
<RemoveFolder Id="RemoveApplicationProgramsFolder"
Directory="ApplicationProgramsFolder"
On="uninstall"/>
<!--<RegistryValue Root="HKCU" Key="Software\$(var.ProductManufacturer)\$(var.ProductName)" Name="shortcutsinstalled" Type="integer" Value="1" KeyPath="yes"/>-->
</Component>
</DirectoryRef>
<DirectoryRef Id="DesktopFolder">
<Component Id="DesktopShortcut" Guid="C03900DF-FFD8-44B8-AA42-1BC72BB9E1F4">
<Shortcut Id="ApplicationDesktopShortcut"
Name="$(var.ProductName)"
Description="$(var.ProductDescription)"
Target="[APPLICATIONROOTDIRECTORY]OMOffline.exe"
WorkingDirectory="APPLICATIONROOTDIRECTORY" />
<!--<RegistryValue Root="HKCU" Key="Software\$(var.ProductManufacturer)\$(var.ProductName)" Name="desktopshortcutinstalled" Type="integer" Value="1" KeyPath="yes"/>-->
</Component>
</DirectoryRef>
HKCU is per-User entry, That should not Interfere with your goal of Making per-user Install. You can use http://blogs.msdn.com/b/rflaming/archive/2006/09/30/778690.aspx to make a package per-user Installable.
To answer your question, I tried installation without registryvalue. Program Was allowed to build (with ICE38/ICE41 error), I was able to see the link post Installation of MSI

Which would be the proper way to install one publisher policy in to the GAC using WIX?

Which would be the proper way to install one publisher policy in to the GAC using WIX 3.5?
I tried to do this:
<File
Id="LIBGAC"
Assembly=".net"
KeyPath="yes"
Vital="yes"
Name="ClassLibrary1.dll"
ProcessorArchitecture="msil"
DiskId="1"
Source="..\ClassLibrary1\bin\Release\ClassLibrary1.dll" >
</File>
</Component>
<Component Id="Config" Guid="F089B1AA-B593-4662-9DF4-F47EB9FBA1F4" >
<File
Id="LIBGACPolicy"
Assembly=".net"
KeyPath="yes"
Vital="yes"
Name="Policy.1.0.ClassLibrary1.dll"
DiskId="1"
Source="..\ClassLibrary1\policy.1.0.ClassLibrary1.dll" >
</File>
<File
Id="LIBGACPolicyConfig"
Source="..\ClassLibrary1\policy.1.0.ClassLibrary1.config"
CompanionFile="LIBGACPolicy">
</File>
</Component>
</Directory>
When compiling with VS2008 appears this error:
policy.1.0.ClassLibrary1.dll appears to be invalid. Please ensure this is a valid assembly file and that the user has the appropriate access rights to this file. More information: HRESULT: 0x8013101b
And lastly, when compiling with VS2010 doesn´t appear to be any problem. But
at finalizing the installation process, the DLL is well installed and the
publisher policy didn´t. Also I read the log generated during the installation and I wasn´t able to find a cause.
Thanks for reading.
I've been doing something similar and works well using Visual Studio 2010 and in a Build Server with MsBuild:
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="Gac" Name="Gac">
<!-- The component with the assembly -->
<Component Id="MiClassDLL" Guid="*">
<File Id="MiClass.dll" Assembly=".net" KeyPath="yes"
Source="$(var.MiClass.TargetPath)" />
</Component>
<!-- The component with the policy -->
<Component Id="PolicyMiClassDLL" Guid="{YOUR_GUID_HERE}">
<File Id="PolicyMiClass.dll" KeyPath="yes"
Source="$(var.MiClass.TargetDir)Policy.1.0.MiClass.dll" />
<File Id="PolicyMiClass.config" KeyPath="no"
Source="$(var.MiClass.ProjectDir)Policy.1.0.MiClass.config" />
</Component>
</Directory>
</Directory>
</Directory
In my case I have the policy.config file in the same project directory and I build the policy dll in the same output to make easier the installer script.
I noticed that the policy component must have a guid and for some reason it requires internally that policy dll and config files in the same directory/component.
I build the policy assembly in the Post-Build event of MiClass project with this command:
"C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\al.exe"
/link:"$(ProjectDir)Policy.1.0.MiClass.config"
/out:"$(TargetDir)Policy.1.0.MiClass.dll"
/keyfile:"$(SolutionDir)MyKeys.snk"
/comp:"My Company"
/prod:"My Product"
/productv:1.0
/version:1.0.0.0
I hope this works for you.
I did some work with policy dlls, and the only difference I can see is that your file naming convention is a little different than ours was.
Instead of
policy.1.0.ClassLibrary1.dll
policy.1.0.ClassLibrary1.config
We used
policy.1.0.ClassLibrary1.dll
ClassLibrary1.dll.config
instead of /link switch use /embed to compile the xml-config into publisher policy. then you can install the resulting assembly into GAC without problems