We want to have an installer A which must :
Remove another product B (we know its product guid)
redistribute MFC 2008, 2010 and 2012
write registry entries in HKLM
B is installed per-user. Since in our current implementation A redistributes MFC using merge modules, it installs per-machine. Therefore MajorUpgrade with same upgrade code doesn't work. We also tried running the script "msiexec /x {PRODUCT GUID OF B} /q" as a custom action during installation of A, but Windows has a mutex (_MSIExecute) that allows only one execute sequence per machine; therefore this idea doesn't work too.
Our ideas are now :
redistribute MFC using another way than merge modules, and install A per-user (even if it writes in HKLM, yes I know it's bad practice, but it is simple to implement)
implement the installer of A as a bootstrapper/chainer (and therefore the installer of A will be a file like setup.exe) and run the uninstall command after execution of MSI
What are you suggestions ?
Finally I found a solution :
Write a program (in C# .Net 3.5 for example) which will install A. If this install succeed, we uninstall B. Also we are sure that C# .Net 3.5 is installed on our customer's machine.
"Wrap" the above program and the msi using iexpress. The output will be a self extracting .exe file, which will execute the above program. We deliver this file to the customer.
Related
I made a laucher application in c++ that use direct 2d and 3d. Now i making a installer for this. I followed microsoft docs and i made it but there is a issue.
I use 'Microsoft Visual Studio Installer Projects' extension to make that.
The issue is if i already installed my launcher with a previous installer msi file, if i rebuilt a new installer msi and try to run it it show me this error
This is the microft docs i followed to make this: https://learn.microsoft.com/en-us/cpp/ide/walkthrough-deploying-your-program-cpp?view=msvc-160
In the future maybe i need make a update for my laucher. It isn't good idea everytime need go to control panel, search and delete the previous application and install the new one manually.
Anyone know how can i make it automatic remove old version and install new one? Maybe there is a better way to create a installer?
Major Upgrade: In order to upgrade properly, you need to use a major upgrade so that your new version uninstalls the old one and then installs itself (this can happen in reverse order too: new version installed and old remnants deleted afterwards, but this is another story). There are further upgrade types, but stick to major upgrades for simplicity.
The message you are receiving is basically because you have a different package code for the new MSI, but not a new product code or version number (or just one of those problems). You need to get the settings straight.
Recommended step-by-step:
Set "RemovePreviousVersions" to True in the project properties.
In the same place: bump up your version number (one of the first 3 digits)
Answer yes when asked to change product code, or do so yourself manually.
Keep the UpgradeCode the same - it needs to be stable across releases.
Rebuild your setups. Clean out your box of old remnants before testing or test on a virtual.
Testing: Remember to simulate your full upgrade process from first version installed to the new one with different version numbers for a few core files and also try to add a few files and such things. Very important to verify.
Heads-Up: Before ending, it is standard procedure to warn about the potential limitations of VSInstaller Projects (shorter list form).
MSI Tools: Here is a short "review" of other MSI tools.
MSI Upgrade Types: Shamelessly stolen from the InstallShield help file (towards bottom):
I created the MSI build package for our application. After this installation, we triggered another dependent driver software in the separate process in a committed event of Installer class like below,
Process.Start (" Path of driver software ")
We are facing an issue, installed directory ( It's empty ) folder is not removing while un-installing the same. Actually like installation, we triggered the un-installation of dependent driver software in the separate process by overriding the Uninstall method of installer class.
Anyone, please help me to overcome this issue? How could I remove the installed directory?
I can't change the installation procedure, since we are aware that we can't process another installation/un-installation when another one is going.
You are running a non-MSI driver install EXE from within your MSI? Correct? Or maybe it is an MSI wrapped in an EXE?
Do you have Installshield Premier? Could you use a suite project and install the EXE via the bootstrapper before (or after) the MSI install? I have honestly never used this feature, but running setups in sequence is what it is for. Embedded custom actions in MSI files kicking off EXE files are notoriously unreliable. This is - in my opinion - especially true if you are running with managed code as well (which I think you are).
In the long run managed code may yield safer custom action code (security-wise based on CAS), but for now it seems to cause unwanted runtime dependencies - especially for very large-scale distribution (global distribution) targeting diverse Windows versions (Vista, 7, 8, 10).
I am told it takes a while to get used to Installshield's suite feature, but maybe it is better for you? You can run EXE files, MSI files, patches and zips in sequence. Some fiddling to define uninstall and upgrade behavior I guess and lots of testing. I am pretty sure corporate application packagers would be happy to see a suite rather than an MSI with lots of strange stuff embedded in it.
UPDATE: Once you have compiled a suite setup.exe file it can be extracted as described here: Regarding silent installation using Setup.exe generated using Installshield 2013 (.issuite) project file
Alternatively you could try to extract the setup.exe files for the driver setup and install the drivers as regular MSI components and run DPinst.exe to install / uninstall the drivers (tool from DIFx). Also quite clunky - especially when you need to include uninstall.
Your driver setup likely uses DPInst.exe already. I would check if you can extract an MSI from the EXE and use it instead of the EXE to include in the suite project. Some hints for how to deal with setup.exe files (extraction, runtime paramenters etc...): Extract MSI from EXE.
WiX has the Driver element in one of its extensions to deal with driver installs. I have never had the chance to test it.
I created an installer using InstallSheild Limited. During the install process, I have a Custom Action which runs a C++ exe after registering the product. In the C++ exe, I move files that are in the installers program directory to various places on the computer.
Now, I need to make the uninstaller be able to remove those files. Is there a way to do this in InstallSheild Limited Edition. If not, what can I do to achieve the same results?
This ought to be simple, but seems to be anything but.
I wish to create an installer that can be used by those using group policies to install products. I do not know then if this must be an MSI, or an EXE. Can an EXE install be installed via a group policy? I chatted with another Wix novice who seemed to think it was a bad idea to have an install that was a plain MSI file.
My product uses the Visual C++ 2010 redistributables. I do not wish to use merge modules. Both this and this link give some of the disadvantages of using them. I object to 1) installing things that the user has not consented to, and 2) not having a control panel uninstall item with a version number that users can inspect and see if they have the latest version of. Thus, I am not interested in responses consisting of people lecturing me on why I ought to use merge modules. If what I am asking for is truly IMPOSSIBLE without merge modules, then please explain why.
I do not know if it is necessary to use a bootstrapper to kick off an EXE install. I gather that it is, but it seems bizarre for me, for an MSI with such involved tables and descriptions, not to be able to kick of a mere EXE, ON THE CONDITION that the redistributable is not installed already.
If it is necessary to use a bootstrapper, I would like to know if anyone can find a complete example, with both bootstrapper and Wix code, for an example of a product install; ideally, together with the command lines necessary to compile them, for such a common case as installing a VC++ 2010 (or possibly 2012) program, together with its redistributable - with the latter being installed as the EXE.
I have found this to be straight-forward and easy to do in Inno Setup Pascal - except for the Group Policy part. I have found anything but COMPLETE examples and/or straightforward explanations to accomplish this using a Microsoft installer. No matter what Microsoft says, I would consider such an installer to be best practices. My code is not managed, and I would like to support XP. Thus, a bootstrapper that requires some .net to already be installed would only add another unsolved layer of complexity to the problem. One that statically links to a .net library might not be too bad, if it did not create very much overhead. My MSI install seems to work pretty well. I did not realize that installing a vcredist_x86.exe would be a problem with such an elusive solution. I do not have Visual Studio. I am using the Qt framework, and have Visual Studio installed only to compile my application. If you have a bootstrapper solution, please specify which bootstrapper you are using. Ideally, the same idea could be extended to more than one prerequisite, and the same coding pattern could be used. If there were a way to use a merge module or additional MSI so that the redistributable would have its own control panel entry, that could be acceptable.
Brownie points for suggesting a mailing list, forum or well-populated chat channel to talk about Wix that does not require one to receive a lot of unnecessary mailing list traffic.
Group Policies by default don't allow EXEs to be installed. I did read about some admins that repackage EXEs into MSIs to deploy them via GPO but that is rather hacky. There is also the possibility to script the deployment - GPOs support script execution, machine or user level.
You can't embed an MSI within another MSI either because only one installation can execute at any time (Windows Installer design).
I don't know how you will be providing your product to your customers but vcredist_x86.exe (I am trying this with the v100 version) uncompresses into the root folder and generates an msi and a cab (vc_red.msi and vc_red.cab) among other files. If you provide these to your customers they can add them to the same GPO used to deploy your product.
I asked this question in a more general design context before. Now, I'd like to talk about the specifics.
Imagine that I have app.exe running. It downloads update.exe into the same folder. How would app.exe copy update.exe over the contents of app.exe? I am asking specifically in a C++ context. Do I need some kind of 3rd mediator app? Do I need to worry about file-locking? What is the most robust approach to a binary updating itself (barring obnoxious IT staff having extreme file permissions)? Ideally, I'd like to see portable solutions (Linux + OSX), but Windows is the primary target.
Move/Rename your running app.exe to app_old.exe
Move/Rename your downloaded update.exe to app.exe
With the next start of your application the update will be used
Renaming of a running i.e. locked dll/exe is not a problem under windows.
On Linux it is possible to remove the executable of a running program, hence:
download app.exe~
delete running app.exe
rename app.exe~ to app.exe
On Windows it is not possible to remove the executable of a running program, but possible to rename it:
download app.exe~
rename running app.exe to app.exe.old
rename app.exe~ to app.exe
when restarting remove app.exe.old
It's an operating system feature - not a C++ one.
What OS are you on?
In Windows see the MoveFileEx() function, on linux simply overwrite the running app ( Replacing a running executable in linux )
On Windows at least an application running is locking its own .exe file and all statically linked .dll files. This prevents an application from updating itself directly, at leads if it desires to prevent a re-boot (if re-boot is OK the app can pass in the MOVEFILE_DELAY_UNTIL_REBOOT flag to MoveFileEx and is free to 'overwrite' it's own .exe, as is delayed anyway). This is why typically applications don't check for updates on their own .exe, but they start up a shim that checks for updates and then launches the 'real' application. In fact the 'shim' can even be done by the OS itself, by virtue of a properly configured manifest file. Visual Studio built application get this as a prefab wizard packaged tool, see ClickOnce Deployment for Visual C++ Applications.
The typical Linux app doesn't update itself because of the many many many flavors of the OS. Most apps are distributed as source, run trough some version of auto-hell to self-configure and build themselves, and then install themselves via make install (all these can be automated behind a package). Even apps that are distributed as binaries for a specific flavor of Linux don't copy themselves over, but instead install the new version side-by-side and then they update a symbolic link to 'activate' the new version (again, a package management software may hide this).
OS X apps fall either into the Linux bucket if they are of the Posix flavor, or nowadays fall into the Mac AppStore app bucket which handles updates for you.
I would day that rolling your own self-update will never reach the sophistication of either of these technologies (ClickOnce, RPMs, AppStore) and offer the user the expected behavior vis-a-vis discovery, upgrade and uninstall. I would go with the flow and use these technologies in their respective platforms.
Just an idea to overcome the "restart" problem. How about making a program, that does not need to be updated. Just implement it in a plugin structure, so it is only an update host which itself loads a .dll file with all the functionality your program needs and calls the main function there. When it detects an update (possibly in a seperate thread), it tells the dll handle to close, replaces the file and loads the new one.
This way your application keeps running while it updates itself (only the dll file is reloaded but the application keeps running).
Use an updater 3rd executable like many other apps.
Download new version.
Schedule your updater to replace the app with the new version.
Close main app.
Updater runs and does the work.
Updater runs new version of your app.
Updater quits.