I have a setup project. If the user modifies one of the installed files and then un-installs the application, I'd like the file to NOT get deleted by the uninstall (so that when the user re-installs later, the modified file is used rather than the default one that the installer would normally use). Is this at all possible?
Note: Files which have not been edited should be applicable for upgrades/removal.
To prevent uninstall you should mark the files' component as Permanent
http://msdn.microsoft.com/en-us/library/windows/desktop/aa368007(v=vs.85).aspx
Since it is not possible to prevent the setup project from removing modified files when uninstalling, the best approach I have found (as mentioned by Ciprian) is to create a custom action which backs up the modified files before uninstallation, and restores them in another custom action afterwards.
Related
I want to make backup of my application config files. This files are in specified directory. All i want to do is make subdirectory of this directory, and move there this config files on uninstall.
I know that this is possible with WiX custom action, but i think, that there is the simpler way.
I can do this scenario with CopyFile WIX element, but i don't know how to fire it at uninstalling only.
A common way to do this is have the application make a copy of the config file when it first runs, and the copied file is updated and used by the application. The uninstall doesn't remove it (because it didn't install it) but it can be optionally removed with a RemoveFile element or a custom action (and removing with a CA is more straightforward than copying).
One of the reasons this technique is used is that individual config files might be required for each user. In these cases the template installed file is copied by the app to per user locations. Another reason is upgrades and patches. Careless patches and updates can overwrite the original file (because REINSTALLMODE=vamus is used). Also upgrades can be used to deliver updated config files without jumping through hoops figuring out how to preserve the existing config file and yet deliver the new one at install time - the older unchanged template config file can be replaced without impacting current app settings.
Here. Custom action which triggered only on ununstall.
<Custom Action='CREATE_BACKUP' Before='...'>REMOVE="ALL"</Custom>
I have an msi. In it I have several config files (a.config, etc) and exes (jux.exe, etc).
In my msi I created a custom actions - commit for one of the exe (jux.exe). I make the installerclass false.
The idea is for the msi to call jux.exe right after install.
jux can start ok until it tries to validate the existence of some of the files (jex.exe, jax.exe etc.) and reading files inside the msi (a.config, b.config etc). seems like jux.exe cant find the files.
Should I not use commit? ideas?
It's most likely failing because you are making assumptions about the locations of the files, and they are incorrect. Your exe is being run from an msiexec.exe with the system account and an unknown working directory. It is not being run from an interactive user shell with explorer setting the working directory and running it with your credentials. If your code just tries to open a.config without specifying the full exact path then it won't find it.
All VS custom actions run after everything is installed, so you got lucky there. You don't need a Commit custom action - an install custom action will work too. That will also be called after all the files are installed. It's not clear why you want to validate the existence of the files - there's no point. An MSI install either works and installs everything or fails, rolls back and restores the system to its previous state. So there's no point in checking that it installed files.
There's no good way around this problem using this project type. It simply fails to expose full control over when to schedule your custom action and boils it down to overly simplistic choices. If I was you I'd factor this custom action out into a WiX merge module and then merge that into your VDPROJ installer (or go full WiX).
I am using a custom action during install to write a text file to my install directory. When I uninstall, that file is not removed nor is the corresponding install directory. However everything else is uninstalled properly.
I understand the reason that WIX cannot uninstall this file using the uninstaller, I'm just wondering what's the best way to call into a "clean up" action on uninstall which in which I can manually delete the directory/file?
You could include a RemoveFile element in whatever component your text file is most closely associated. When that component is uninstalled, the text file will be deleted as well.
<RemoveFile Id="CleanUpLogFile" On="uninstall" Name="log.txt"/>
You could install an empty text file and then have the custom action write to the file instead of creating it.
In general, I would suggest to stay away from custom actions as much as possible (they can get quite messy when dealing with install, uninstall, patching, repair, etc.) You may want to consider having your application itself configure the file on first run or have an additional configuration app that is executed on first run.
you can always run a console app for example that removes the file through code. You would just add that project only to the uninstall custom actions.
Out of curiosity what is the nature of the text file? In similar situations where the text file is an install log I'd recommend logging to a temp directory or a location that is not under Program Files (such as the Program/AppData folders - C:\ProgramData\Manufacturer\ on windows 7 for instance).
This approach bypasses this issue completely eliminating the need to create custom clean up scripts or actions.
We currently have 4 installers for our client software:
ClientSetupTest
ClientSetupProduction
ClientUpdateTest
ClientUpdateProduction
The only differences between them are that Setup contains the Crystal Reports redistributable files, and Update doesn't. Test and Production just specifies which environment they run in and the only difference there is one line in the Client.exe.config file.
Dumb, I know, which is why I replaced them all with one installer after getting rid of Crystal Reports. The new installer writes the selected environment out to setup.config, which is referenced by the file attribute (see here).
The "file" attribute is new to the config file with this new installer. The problem I'm running into is that if we modify the Client.exe.config file on an old installation, then run the new installer, the config file never gets updated with the "file" attribute.
Is there any way to force it to update a file? RemovePreviousVersions doesn't exactly work, since it's a different installer, unless I'm misunderstanding something. My current idea, which will probably work, is to add code in the OnBeforeInstall method to rename the old Client.exe.config to a backup file, so it'll always write the new one. Seems like there should be a simpler solution within the installer itself, though. Any ideas?
EDIT: Renaming the old config file to Client.exe.config.old before calling base.OnBeforeInstall() didn't work. It renamed the file, but never wrote the new one.
Windows Installer won't update a modified file.
Nonversioned Files are User Data—If the Modified date is later
than the Create date for the file on the computer, do not install
the file because user customizations would be deleted. If the Modified
and Create dates are the same, install the file. If the Create date
is later than the Modified date, the file is considered unmodified,
install the file.
You have some options:
include a custom action that modifies the file in place. This might be a script or .NET code.
do as you say - move the existing file out of the way. The installer won't stop on it. But you need to make sure it happens in the order you are imagining. You may need Orca to figure out the ordering.
include a custom option to set the create date to be "today". This should be really simple with a scripted custom action, using the Scripting.FileSystemObject. Then Windows installer will overwrite it.
I'm building an application that is used by several different customers. Each customer has a fair amount of custom business logic, which I have cleverly refactored out into an assembly that gets loaded at runtime. The name of that assembly, along with a number of other customer-specific settings, are stored in the application's configuration file.
Right now, here's what I have to do in order to debug the application for customer foo:
Go to the filesystem in my project directory and delete app.config
Copy app.config.foo to app.config.foo - Copy.
Rename app.config.foo - Copy as app.config.
Tell Windows that yes, I want to change the file's extension.
Switch back to Visual Studio.
Open the Settings.settings item in my project.
Click "Yes" 13 or 14 times as VS asks me if I want to use the new settings that have been changed in app.config.
Close Settings.settings.
Okay! Now I'm ready to debug!
It seems to me that the rigamarole of opening Settings.settings is, or ought to be, unnecessary: I don't need the default values in Settings.cs to be regenerated, because I don't use them. But it's the only way I know of to make VS aware of the fact that the app.config file has changed, so that the build will copy it to the output directory.
There's got to be an easier way of doing this. What is it?
You can also let Visual Studio automate Robert`s approach by:
Define a Build Configuration for each client
In the post build event, simply xcopy app.config.xxx to your bin folder. Where XXX is the name of a Build Config accessible in VS. Something like: xcopy app.config.$(ConfigurationName) $(OutDir)/app.config
VS will drop a distinct build for your clients in separate folders, aolong with the proper config file.
bin/Client1/
bin/Client2/
You can refer this post for some good practices : Managing Multiple Configuration File Environments with Pre-Build Events
Thinking about the mess of managing multiple configuration files I made this tool: http://envride.codeplex.com/
Its purpose its exactly to make it easier to manage multiple configuration files in an automated way. I would be very pleased if you would take a look at it.
A couple of people suggested using multiple VS configurations, which I think would have worked, except that it would require me to rebuild the solution every time I switched between configurations.
What I did instead seemed a little stupid while I was doing it, but I've been using it for nearly a year now and it works extremely smoothly. In my project directly, I create a separate app.config.XXX file for each customer. The actual app.config file is used solely to generate Settings.cs - it has all of the correct setting names and their default values. It doesn't get copied to the build directories, ever.
Then I wrote a little program that lets me select a customer, and that simply goes through the directories for each project and, if I selected customer XXX, copies app.config.XXX to bin\debug\myprogram.exe.config and bin\release\myprogram.exe.config. As long as this program knows where the root of the solution is (I have to be a little careful whenever I branch the code), it works like a charm.
This thread is too old to represent current tools in VS.
You can use an addon that acts similar to web.debug.config but for app.config.
https://marketplace.visualstudio.com/items?itemName=GolanAvraham.ConfigurationTransform
And for the same app.config transformations without addon.
https://www.linkedin.com/pulse/multi-appconfig-visual-studio-2017-benjamin-davis/
You may opt to define multiple Visual Studio solution configurations, one for each customer, and have customised MSBuild targets for your Windows app project.
I have documented the steps of how I handled this here. Multiple app.config files for deploying to different environments
After a little digging and work around I got my Test project working with multiple configurations,
In the Configuration Manager, create the configurations you need
Copy paste your app.config and add the name of the configuration, in my case is AHI, FIV, MGC, so my config files look like: App.AHI.config, App.MGC.config, App.FIV.Config. You can name it how ever you wanted, but keep the same convention
Add a Post-Build event. In my case it would look like: xcopy $(ProjectDir)app.$(ConfigurationName).config $(TargetDir)$(TargetName).dll.config /y
here is my post, so you can read it with more details
Running a Test Project with Multiple Configurations