In previous version of installer, created by Wix, next code exists:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
In order to work around the bug in Windows Installer described in this knowledge base article code has been fixed:
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallFinalize" />
</InstallExecuteSequence>
But now, if I install program with installer with first code and then install program with installer with second code without remove installed program, all files remove and my path exist empty folders (all files in both installer have equal name).
If I open second installer and press Repair - all files appear.
What wrong and how this problem fix?
P.S. Sorry for my English :(
Just a guess: It sounds like the first and the second setup install the same files but as part of components with different component id's. To verify this, you can open both msi files with orca.exe and compare the component ids.
The component IDs should stay the same, so that they can be properly reference counted. Otherwise you will get different components trying to manage the same files, which will in this case result in disappearing files when either of the components is uninstalled.
If you follow the windows installer rule that the content of a component should never change (i.e. never remove or add files to it) then the component GUIDs generated by wix should automatically stay stable. This is one of the reasons why it is best to have one component per file.
Related
I am creating my first .msi installer using WiX 3.5 setup project in vs2015.
I have 2 <CustomAction> defined in my .wxs page, they are both .exe files.
The First .exe file executes fine as it waits for the After="InstallFinalize" state.
However the first .exe actually does a job that downloads another .zip file from the web which contains our 2nd .exe.
I need to complete the 2nd Custom Action after the first .exe finishes exploding the package. I have tested both custom actions independently and both will install.
<Custom Action="LaunchInstallSoftwareAutoUpdaterProcessAction" After="InstallFinalize" />
<Custom Action="LaunchSoftwareAutoUpdaterProcessAction" After="InstallFinalize">NOT Installed AND NOT REMOVE</Custom>
I am new to WiX but I do not think there is another way to wait that I am aware of. How can I accomplish this?
I'm having installshield project and I several powershell custom actions.
The scripts change the file system (extract zip files, copy files, install packages, etc).
I wonder where in the install sequence should I put them?
I looked at the guilde here but they don't cover it.
I tried to put it in the execute sequence after "InstallInitialize" but that made my scripts behave weird (some of the cmdlets work and some don't).
Then I moved them to the UI sequence after "ExecuteAction" and that seems to be working fine but I read somewhere that I shouldn't put in the UI sequence any scripts that change the file system..
What is the right place?
Thanks
Events that change the system should not be placed in the UI sequence, one reason is that there isn't anything preventing your user from skipping the UI sequence.
During the execute sequence, you cannot install another MSI package. Some installers may look like a .exe but have a bundled MSI. If your goal is to handle installing prerequisites, then you need to possibly use the InstallShield Suite/Advanced UI install. That has a method of managing multiple install prerequisites. I suspect that the problem you encounter is that some of those packages you try to install have imbedded MSI installs.
I've created a patch with Advanced Installer by using an old (target image) msi and the new one (upgrade image). Inspecting MSP file I've discovered that it contains both modified and completely new files. The problem is that during the installation it installs only the "added" files. Existing files are ignored. I've already tried MSIEXEC switches like:
REINSTALL=ALL
REINSTALLMODE=sumo / aums / omus etc...
UPGRADE="Yes"
IS_MINOR_UPGRADE = "1"
..in different order and combinations (i.e. "REINSTALLMODE=aums REINSTALL=ALL"), so don't reply or comment just by telling me to try REINSTALLMODE=omus or something similar.
When creating a patch there is a set of rules that need to be followed, have you checked those? Breaking one of those can lead to unexpected behavior, such as the one you are now encountering.
To check for the rules you can start with a diff between the project files, as they are standard XML ones, and check for their product code, component GUIDs, etc... For example folder synchronization is a common problem encountered when a patch is created, as this changes the component GUIDs.
For some odd reason all the core components (exe, dlls) I wanted to update were set to "Do not register this component with Windows Installer".
I suppose this is some kind of project bug, because it's very old and was migrated through different Advanced Installer versions (7, 8 and 9).
Anyway, I was not able to update my application correctly even with a fixed patch. Windows Installer kept on asking me to browse to target image msi file (cached installer of the previous version).
However not all of my customers keep those files (usually this cached files are stored in %APPDATA% folder). So I found a workaround:
I've applied "Hash files" option in order to create a MsiFileHash table
I've packed my msp patch in a bootstrapper (exe file) that starts it with the TWICE with following command-line parameters:
first time:
"myPatch.msp" /n {150F6CE2-8C12-414B-9377-F087A62E6B67} REINSTALLMODE=c /qb
second time:
"myPatch.msp" /n {150F6CE2-8C12-414B-9377-F087A62E6B67} REINSTALLMODE=dep /qb
REINSTALLMODE=c switch forces file compare algorithm based on hashes, so it doesn't require the original setup sources anymore
REINSTALLMODE=dep restores all the other missing files, files with unknown or different (from target) version
I hope this workaround will be useful to people that use MSI/MSP authoring tools other than Advanced Installer
I am developing a package using Installshield 2008 Primer Edition and Project type is Installscript MSI project.
The problem I am facing is during installation I am installing some of the files to the following location C:\Program Files\Company\SystemFiles from this location I am copying and adding the set of files into System32 folder, it contains DLLs and OCX files, copying into the System32 folder has been done using Installscript.
Due to this during uninstallation, the installed file is getting removed from System32 due to this other dependent application which requires the same set of DLLs have stopped working.
I have approached Installscript to copy files from ProgramFiles to System32 Folder rather than using built-in options because we have an issue during the upgrade in order to avoid that I am using Installscript.
Even I have tried several workarounds like setting the file attributes after file copies to System32 using Installscript like FILE_ATTR_SYSTEM which sets the system attribute but still files are getting removed during uninstallation.
Any idea how to give file attributes as PERMANENT or SHARED; will this help, and if it will, then how can I set it using Installscript?
I have 2 ideas
1)I think you can use SHARED option as this wont remove the files while uninstallation.
2)Also when i was facing similar issue , what i did was putting all the required files in the installation directory itself so that while uninstalling only the installed files will be removed.(I know this is not a best solution)
(NOTE:I have worked on Install shield some 6 years back and so remember only certain things)
You can also disable logging from Install Script. This will make the installer "forget" that it installed specific files groups or features.
You should make sure to enable logging once again after you have copied the files that you want to permanently leave on the system.
If you don't remember to enable logging after you have disabled it, your uninstall process may not work correctly.
Syntax is as follows:
Disable(LOGGING);
//Add code to copy your permanent files here
Enable(LOGGING);
For InstallScript projects:
To prevent the files in a particular Component from being removed during uninstall:
1-Select the Components view from within the Organization folder.
2-Select the component that contains the files you do not wish to remove during uninstall.
3-Change the "Uninstall" property in the right pane to a value of "No."
For MSI Projects:
To prevent the files in a particular Component from being removed during uninstall:
1-Select the Components view from within the Organization folder.
2-Select the component that contains the files you do not wish to remove during uninstall.
3-Change the "Permanent" property in the right pane to a value of "Yes".
I see this is an old question but I just came across this. Seems to be a common problem. One good solution is to stage the files to a private directory mostly program files and then have a custom action do the copy and register (ocx etc). Installshield remembers what it copied so it tends to remove them. Do not disturb anything else like logging (my recommendation). Set conditions on the custom action so that it doesn't run during Uninstall.
Although sometime back I did another weird implementation which only programmers are used to doing.. Packed the files as resources and created my own code to extract and deploy (Something that Process Explorer kind of tool does). There were certain use cases that warranted this kind of implementation. But again this is complicated and obviously reinventing the wheel. Unless you are good with C/C++ and Windows API this would be difficult. I would still suggest you stay away from this kind of implementation because it is also considered a "virulent behavior". Yet, so far I never got warnings from the Anti-malware products.
Using WiX (Windows Installer XML) I have created an MSI installer which installs Word templates into the users Application Data folder, e.g. on Windows XP
C:\Documents and Settings\<user>\Application Data\Microsoft\Templates
I'm retrieving the path to this folder from the registry:
<Property Id="APPDIR" Secure="yes">
<RegistrySearch Id="RegSearch_AppData"
Type="directory"
Key="Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"
Name="AppData"
Root="HKCU" />
</Property>
<CustomAction Id="ActionWordTemplateFolderAssign"
Property="TEMPLATEFOLDER"
Value="[APPDIR]Microsoft\Templates" />
<InstallExecuteSequence>
<Custom Action="ActionWordTemplateFolderAssign" Sequence="1" />
</InstallExecuteSequence>
However, some users installing the MSI file on Windows Vista receive an error because the APPDIR property is empty.
Is APPDIR not the correct way to retrieve the Application Data folder? Or do I have to consider another property on Vista?
EDIT: This is just a short version of the WiX Code to retrieve Word's template folder. First I'm actually checking whether the user has a custom template folder defined by a policy or under HKCU\Software\Microsoft\Office\12.0\Common\General\UserTemplates. However, if none of these are set the fallback is to use the default location under %APPDATA%\Microsoft\Templates which is retrieved by the above code.
You should use [AppDataFolder] instead. I can't find anything about "appdir" in the windows installer property reference.
Edit after question edit: The shell folders key (great blogpost btw) where you get your appdir value from is a very old and deprecated way to get at the system folders. It is only there for backwards compatibility and you should not rely on it. Especially if you live near Raymond Chen.
Edit 2: Since the real question turns out to be "how do I find the user's word template folder"... The word template folder is not always
[AppDataFolder]\Microsoft\Templates
This is because the template folder can be configured under tools - options - file locations - user templates. Ironically we are back to searching the registry if we want to detect this:
<Property Id="USERTEMPLATES">
<RegistrySearch Id="SearchUserTemplates"
Root="HKCU"
Key="Software\Microsoft\Office\11.0\Common\General"
Name="UserTemplates"
Type="raw" />
</Property>
This registry value is normally not present however, and you cannot specify a default value that contains [AppDataFolder] here (I tried).
Instead, I would try to define two components, one which installs to USERTEMPLATES and one which installs to [AppData]\Microsoft\Templates. You can then make use of Condition elements to test for the existence of USERTEMPLATES, and install only the right one.
Some additional information:
The reference for MSI properties containing special folders:
http://msdn.microsoft.com/en-us/library/aa370905(VS.85).aspx#system_folder_properties
And a link to a related blog post:
What is the WiX equivilent of Environment.SpecialFolder.ApplicationData from .NET?
Divo - In response to your comment on localized Vista installations, the problem probably isn't so much localized Vista (unless I'm reading you wrong) but localized Office.
Microsoft\Templates might become Microsoft\Vorlagen with German office for example. It's a pain in the ass, because I haven't found a reliable source of documentation on what folder names have been localized in Office, and what haven't.
My particular problem was with installing Macros to [AppDataFolder]Microsft\Word\STARTUP - which is localized for some languages only. #$%# in the end we just get customers to manually move the templates, the majority of our markets don't have a problem but we've noticed Italian and Turkish office plus a couple of others seems to exhibit this rather annoying behaviour.
On Vista there is a new standard folder available called TemplateFolder. I think that is what you want. To use it in WiX just do something like:
<DirectoryRef Id="TARGETDIR">
<Directory Id="TemplateFolder" Name="Templates"/>
</DirectoryRef>
Then you can reference the TemplateFolder Directory where ever you may need it.