How to edit a .NET config file with WiX AFTER its installation - wix

I need to change an entry of a .NET config file.
The problem is that the App.config in the project folder needs to stay untouched, because otherwise the application won't work within the IDE anymore.
I need the installed .NET config file changed after its installation.
Whenever I try to reference that file and build my installer, i get an error that the file can't be found. Of course it can't be found there, because the installation folder doesn't exist, when I build the installer.
How can I achieve that goal?

You are not saying how you are editing it, but WIX has two facilities for doing this properly. You can use XmlFile or XmlConfig. These are scheduled at the proper time by WIX for you. You can set the path to the file a few ways as they accept a formatted string, so you can use an expected installed path or the file id.

Related

VSTO appSettings of Word AddIn cannot be changed after using MSI installer (generated through Wix)

I have a Word AddIn which uses one setting to retrieve information from a webservice. This setting is stored in de settings section of the project (see image)
To be able to change this setting after the application is compiled, the access modifier is set to public. When I compile the application and use it in Word, I only have to change the ConfigURL in de [applicaitonname].dll.config. This works perfectly, the new URL is applied when trying to retrieve information from another webserivce address (URL).
In this project, I also have a Wix project to create an MSI for this AddIn. Now when I use the MSI to install the AddIn on a computer and after the installation, I change the ConfigURL, the new value is not applied, it still uses the value which was set when creating the MSI.
does anyone know if it is possible to create an MSI for deployment, and still able to change settings values in the config file after installation?
I assume that your Wix project installs the AddIn in the Program Files folder. If that's the case then most likely your user doesn't have the write permissions to this folder. You can either adjust your Wix project to setup necessary permissions to the AddIn's folder or deploy your configuration file to a different location e.g. %APPDATA%\Roaming\[AppName].
From what I've found the VSTO customization DLLs are always loaded from a temporary folder location and not from the original location irrespective of whether ClickOnce cache is used or not. The location of the temporary folder is the Shadow copy folder of .NET framework which is mentioned under the registry key HKCU\Software\Microsoft\Fusion\DownloadCacheLocation.
Shadow Copy is a feature where DLLs can be updated while they are being used. To implement this feature, DLLs are copied to a temporary location when they are being used so that DLL at original location can be updated.
The Shadow copy feature has been used in VSTO from the initial version and there is no way to disable it. Shadow copy can be disabled for .NET AppDomain while creating an AppDomain but in the case of VSTO customization, the developer has no control over the way AppDomain is created and hence cannot configure the behavior.
In order to load a configuration file, it must be located in the same folder where the assembly is loaded from. Unfortunately, your config file does not get copied to the shadow cache so it seems it uses some hardcoded values.
In order to solve this issue, you can explicitly load a configuration file from the installation folder. Take a look at this answer for more information.

how to get correct path for file stored in My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData folder under installer class

I have a windows forms application which stores data in
My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData + "\a.xml"
When I run and test this path, it shows path as:
C:\Users\<username>\AppData\Roaming\<Manufacture name>\<Product Name>\1.0.0.0\a.xml
I want to delete above file at the time of uninstall.
So I have created custom action using installer class (please note that I have created installer class in main project, not in setup project as setup project does not show option to add installer class). In installer class, I have override uninstall method and using same above code
My.Computer.FileSystem.SpecialDirectories.CurrentUserApplicationData + "\a.xml"
I have tried to delete file. Obviously I have pointed it to uninstall folder in setup project which should delete above file, but I can see that in setup project above is taking different path. It is taking path as
C:\Users\<username>\AppData\Roaming\Microsoft Corporation\Windows Installer - Unicode\5.0.7600.16385\a.xml
I am using Visual Studio 2013. Please suggest how to solve this problem.
The easiest workaround I found for this issue is to change the version number so no need to delete any file as it is creating different directory for different version number.

WiX repair from managed bootstrapper fails to fix some corrupted DLLs

I have a WiX Managed Bootstrapper Application that installs some MSIs. I also have a series of tests that exercise the various functions of the installer. The problem I'm having is with the repair test. The test purposely corrupts all the DLLs we install then calls the EXE installer with "/repair /passive" flags. Once completed around 80% of the DLLs are repaired but the remaining ones are untouched and therefore still corrupted after the repair.
If I manually run msiexec on an individual MSI with the command line args "/fa" which instructs the MSI to forcibly replace all the files it installed, it fixes 100% of the DLLs.
My question is how can I force the MBA to instruct each MSI to repair in this way? I've tried setting the REINSTALLMODE property to 'amus' on the individual MSIs in their .wxs files but the MBA overwrites them at run time as is evident in the log via this line:
PROPERTY CHANGE: Modifying REINSTALLMODE property. Its current value is 'amus'. Its new value: 'cmuse'.
I've also tried to set the properties in the MBA to pass through to each MSI but it doesn't appear to pass them and instead uses it's default values.
I see many similar questions here but none actually address this specific issue. Any help would be greatly appreciated. Rob save me!
Here's your problem right here:
[12:25:25:874]: File: C:****\estimator.dll; Won't Overwrite; Won't patch; Existing file is unversioned but modified
The installer doesn't want to overwrite a file that has changed since it was installed if it cannot verify the version or language (and maybe some other properties?). Without these properties, it decides to look at the modified date. If it is newer than when it was first installed then it won't touch it assuming instead that something changed for a reason and reverting it will cause something to fail. (You can read more here)
One thing you can do in this case is use a Companion File
Set this attribute to make this file a companion child of another file. The installation state of a companion file depends not on its own file versioning information, but on the versioning of its companion parent. A file that is the key path for its component can not be a companion file (that means this attribute cannot be set if KeyPath="yes" for this file). The Version attribute cannot be set along with this attribute since companion files are not installed based on their own version.
Basically you will set the logic for installing/uninstalling this component to be the same as the "FileID" of another component in the install. In the estimator.dll component, in the File tag, remove KeyPath="yes" and instead replace that with CompanionFile="<NameOfAnotherFileID>".
The issue with this approach is that you may have a corrupted DLL but the companionFile it was linked to was fine so it is not reinstalled.
If this is a dll you do own, I would highly suggest versioning the file! Give it any version you want and this issue should go away.
Another thing you can try, although I don't know how it works really, is giving the file a DefaultVersion
This is the default version of this file. The linker will replace this value from the value in the file if the suppress files option is not used.
This would be the quickest solution to verify. Just build a new installer with DefaultVersion="1.0" in the estimator.dll's <File> and see if it gets replaced. I think this will have the installer think the file is versioned 1.0 but the installed file is not versioned so it will replace it (see here)

How to change the logs path in wix extended bootstrapper application

Can anyone let me know, how I can change the log path in wix standard Bootstraper application. By default logs are created in temp directory.
How to set or get all logs in a custom bootstrapper application
http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Burn-and-Msi-logging-revisited-td7578871.html
Above links say, at the end or when any error occurs, logs can be copied from tmp to different directory.
But I have to create the logs from the beginning in a different directory, rather than copying at the end.
Thanks
Just use /log C:\Path\to\log\file.txt in the command line of your bootstrapper. If you want to change teh default location of the log you would need to modify your burn code and build using your own burn.exe which is a nightmare to maintain when you update wix or need to distribute your wix build process to another build system.

Unable to build WixStdBootstrapperApplication - get error "C:\tools\WixBuild.props" was not found

I am trying to make changes to the WixStandardBootstrapperApplication.cpp and generate a dll as per the suggestion from this link. I have downloaded the wix310-debug source and am modifying the file present under wix310-debug\src\ext\BalExtension\wixstdba\ location. There is a wixstdba.vcxproj file under this location which I am trying to open using Visual Studio 2012. Whenever I try to do that I get the error:
Unable to read the project file "wixstdba.vcxproj". The imported project "C:\tools\WixBuild.props" was not found.
I am not sure what should I do to correct this. Also, based on the referenced link, I think I am updating the correct file but let me know if that is not the case. Any help in this would be great. Thanks in advance.
In your vcxproj there's a line like this:
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), wix.proj))\tools\WixBuild.targets" />
The debug source isn't really the source of wix. It includes all the wix source files but it is not really buildable. This zip has all the built pdbs and is used to debug only.
You want to download the wix source from wixtoolset's github so that you can build wixstdba. But, this is for version 3.10.3 currently and may have some version specific changes but I don't see anything that would be an issue using the dll built here against wix 3.10.2 since the engine and bootstrapper application interfaces should have remained the same.
But, you should be able to build all this with only the WixStdBA project. You will have to copy over the wixstdba folder. Edit the vcxproj and remove the import line mentioned above (it should be near the bottom).
Now, add this project to your a new solution or your installer solution in visual studio. We need to add addition include and library directories. All these include directories will be in your wix install location (default C:\Program Files (x86)\WiX Toolset v3.10) In Properties -> C/C++ -> General -> additional include directories add your wix SDK include path. If you are using visual studio 2013 you can use the full path or you can use "$(WIX)\SDK\vs2013\inc". $(WIX) should reference the WIX environment variable which points to the install directory which is added when installing wix. This should be the better option if you will be building on a build system with wix installed since the location may be different across machines.
Now for addition library directories, we go to the Properties -> Linker -> General -> Additional Library Directoryes and add in the correct lib path. If you are using visual studio 2013 you want to put in $(WIX)\SDK\vs2013\lib\x86. Finally we need to reference the libs that are needed to build the bootstrapper dll. Under Linker -> Input -> Additional Dependencies, add in "dutil.lib;balutil.lib". My additional dependencies has a lot more stuff and I don't remember if it was by default there. Here's my Additional Dependencies in full anyways
dutil.lib;balutil.lib;advapi32.lib;comctl32.lib;comdlg32.lib;gdi32.lib;gdiplus.lib;kernel32.lib;msimg32.lib;odbc32.lib;odbccp32.lib;ole32.lib;oleaut32.lib;shell32.lib;shlwapi.lib;user32.lib;uuid.lib;wininet.lib;winspool.lib;version.lib;%(AdditionalDependencies)
With this you should be able to build the wixstdba project and get a dll built. Without editing any code this should be the exact same as the wix included wixstdba.dll.
You could try referencing this dll instead of the wix included one (have to define your own BootstrapperApplication instead of using the BootstrapperApplicationRef to one of the wix ones) or just drop in this dll into your wix location's bin.