Managing User config in WIX migrations - wix

We're making a project that is primarily a Windows Service EXE.
We're using WIX (with heat) to create an installer, that creates the relevant files and registers the EXE with Windows Services.
We've got to the point of implementing the installer upgrade logic, which largely JustWorks(TM) by setting the Version attribute of the Product tag in the .wxs file.
One issue that I can't see how to manage is the config files of the tool.
The tool has various config settings that can be modified from within the tool.
We're using ASP.NET, which has built in settings/config management, and the config settings that get changed are declared as "User" settings. When we run the save the config changes, it creates a secondary config file which overrides the default settings in the primary config file.
The primary config file exists at <installRoot>\MyCustomService.exe.config, and the secondary config file is at <complicated\Path>\vX.Y.Z\user.config.
Where X.Y.Z is the AssemblyInfo version number which is held in sync with the WIX Version number.
When we install a new version, the tool starts looking in a new path for the user.config ... and can't find it. So functionally, installing a new version resets all of the user's configuration :( .
What is the appropriate way to get a WIX upgrade installation to maintain the existing config?

ASP.NET config supports upgrading user settings from one version to the next, using the .Upgrade() method. You're better off using that rather than manage this in the installer.
This question has details on how to manage that: How do you keep user.config settings across different assembly versions in .net?
but the core solution is:
if (Settings.Default.UpgradeRequired)
{
Settings.Default.Upgrade();
Settings.Default.UpgradeRequired = false;
Settings.Default.Save();
}
Having created UpdateRequired as a user property existing only to manage this process

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 edit a .NET config file with WiX AFTER its installation

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.

What is the purpose of msbuild's GenerateRuntimeConfigurationFiles?

I upgraded a netcore1.1 project to the new VS2017/csproj.
In my test projects only, it added:
<PropertyGroup>
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
</PropertyGroup>
I did some digging to discover that it generates these files in the bin directory:
ProjectName.Tests.runtimeconfig.json
ProjectName.Tests.runtimeconfig.dev.json
What is this setting and these files, and why do I need them?
Why were they only generated for my test projects?
These are specific to .NET Core projects and specify
Which runtime and version to use. Typically Microsoft.NETCore.App. The "host framework resolver" looks for a matching folder inside the shared folder (e.g. C:\Program Files\dotnet\shared\Microsoft.NETCore.App\1.1.2). This is important since multiple runtimes can be installed side-by-side and the host needs to know which one to use when you run dotnet myapp.dll.
Additional options for the runtime. The most prominent is probably the garbage collection setting that switches between "desktop" and "server" mode. When you set <ServerGarbageCollection>true</ServerGarbageCollection> int he csproj file, this will cause a value in the runtimeconfig.json to be set. (This property is defaulted to true for web projects)
Additional options for the host. additionalProbingPath for example is set to your local NuGet cache which contains the restored packages. You may have noticed that referencing a NuGet package does not cause its dll files to be copied to the output directory (by default). The host uses the additional probing path to look for packages / dlls referenced to in this location (actually it is a two-step lookup: deps.json tells the host which packages to use and this property tells where to look for this package). Since this is only used for development and shouldn't end up in the published output (since this would mean relying on a NuGet cache on the target), this settings is put into a runtimeconfig.dev.json.
"Classic" .NET Framework projects also had a concept of letting the application set some runtime settings. This was accomplished by having an .exe.config file (which would be built from an App.config file in a project if present). You can think of runtimeconfig.json as "the new .exe.config" but the only have a few overlapping concerns.

dotNetInstaller with output MSI file

I have an application, which can be installed via MSI package. Right now I need to extend this package to check if .NET 4.0 is installed. I want to use dotNetInstaller, but I can't change name and extention of file (dotNetInstaller creates an exe file). Is it possible to create file with MSI extention?
If you targeted your project for .net 4 in the project-setting the standard MSI-installer from that project would check for such a dependency and would provide the user with a solution to fullfill the dependency on setup but only if you havn't scrued with the standard-settings. (There are checkboxes to disable such a behavoir) You can also add additional dependencies to check for at setup time.

Always update files in minor upgrade (how to)

I am creating an install package using InstallShield Pro X. The upgrade works properly. However, the product manager wants the upgrade to replace all files on an upgrade even if the create date != modify date on the file.
I see that to do this I need to set REINSTALLMODE=vamus rather than vomus. However, I don't see how to tell InstallShield that I want it to use that setting. By default setup.exe always passes vomus to windows installer.
There is a property in the InstallShield project named ReinstallModeText that I changed from omus to amus but that seemed to have no effect.
So, how what do I set in the install project so that when setup.exe detects to run an upgrade it sends REINSTALLMODE=vamus? Thanks.
Update: Tried adding the following to the MSI Command Line value in the Release section:
REINSTALLMODE=vamus
This did not work. Setup.exe didn't set REINSTALL=ALL on the command line what I did this. I added that to the MSI Command line and the upgrade worked as expected. But, not the problem is if it is a NEW install those properties are still being set and the installer fails.
In investigating this further and testing more options I think the best answer is to modify the product code in addition to the product version and author it as a major upgrade which removes the previous version first and then installs the new files.
The main problem with this is that it takes alot longer for the installer to run. I also think that you can not issue this as a patch, but I could be wrong on that count.
Don't set the REINSTALLMODE to amus or vamus (force overwrite files). These settings apply to all components in the MSI, and could hence in theory downgrade system files or at least shared files - this typically involves files included via merge modules. It is normally safe to set REINSTALLMODE to emus (replace files with lower or equal version number). Even this can trigger a file replacement error if you try to overwrite a system protected file on newer versions of Windows featuring Windows Resource Protection (wikipedia) (Windows Server 2008 and Vista onwards). On older Windows versions the file would likely be overwritten and then restored in its right version from the dllcache via the Windows File Protection feature provided that feature had a good day. There was (and is) an associated tool for system file checking: System File Checker.
If you have issues with files that should be replaced even if they have been edited, you can use the RemoveFile table to schedule the file for removal during install (and then it will be reinstalled).
The real solution is to consider the installation folder in %ProgramFiles% as read only, and not have the application save ANY settings or change any files. All config files should go to the user profile or the alluser profile and the application EXE file should be responsible for the copy to the profile locations.
See my answer here.
I don't have IS X handy, but in later versions of InstallShield you would go to "Releases", highlight your release, go to the "Setup.exe" section and there's a field called "MSI Command Line Arguments". There you would indicate any command-line arguments that you want Setup.exe to pass to Windows Installer. E.g. REINSTALLMODE=vamus
You mentioned you used ReinstallModeText with "amus". Have you tried ReinstallModeText equal to "vamus". The "v" causes the installer to run off the source package, not the cached package, and that may be your problem.