I wanna use minor upgrades, but I have two questions about the requirements for this type of upgrade.
Is it possible:
to remove a file(not KeyPath) from a component which is shared just in one existing feature (and after the removing the component is still not empty)?
to remove an existing component (I guess that it will violate the rules)?
Thanks for help!
to remove a file(not KeyPath) from a component which is shared just in
one existing feature
You can remove it from your upgraded package, but the update won't remove it on the target machine. A component is updated only if it's key path is changed: http://msdn.microsoft.com/en-us/library/windows/desktop/aa368599(v=vs.85).aspx
To remove it you can try using a custom action, but I'm not sure it will work. The best approach for removing resources when updating is using a major upgrade.
to remove an existing component (I guess that it will violate the
rules)?
If you remove a component it's no longer a minor upgrade. This falls into the major upgrade category.
It's possible, but it is not recommended. Changing the Component Code documents that addition or removal of files requires changing the component code. If you do not, What happens if the component rules are broken describes some of what can go wrong. Note that minor upgrades are often particularly picky about component rules.
Removing a component across a minor upgrade is also a no-no. Instead some people recommend marking that component as transitive and giving it a false condition to have it be removed during the minor upgrade. Note that component rules still apply to the component that only exists to be removed.
Related
I have an app that runs perfectly without new dependencies like this one:
A newer version of androidx.navigation:navigation-fragment-ktx than 2.4.2 is available: 2.5.0
If I upgrade to v.2.5.0, my app has warnings about unrelated elements like for example references to menu objects.
Should I wait and allow these Gradle warnings such as above notice until another upgrade comes along and try the new dependency then?
You shouldn't need to update anything unless you have a reason to. It's often a good idea (as well as new features you also get bug fixes) but it's usually not required. Specifying all your dependency versions means you get a repeatable build that should always work, so long as those versions are available
The thing about libraries is they often have dependencies on other libraries, and updating one might introduce a requirement for other stuff to be updated (which might be why you're seeing other errors appear. That broadly shouldn't happen (making things independently updateable is part of the reason for breaking everything out into separate libraries!) but here's a blog post from when they introduced it:
Starting with the AndroidX refactor, library versions have been reset from 28.0.0 to 1.0.0. Future updates will be versioned on a per-library basis, following strict semantic versioning rules where the major version indicates binary compatibility. This means, for example, that a feature may be added to RecyclerView and used in your app without requiring an update to every other library used by your app. This also means that libraries depending on androidx may provide reasonable guarantees about binary compatibility with future releases of AndroidX -- that a dependency on a 1.5.0 revision will still work when run against 1.7.0 but will likely not work against 2.0.0.
Really you have to look at the release notes for a library to see if there are any breaking changes you need to worry about. For example, here's the one for the Activity Jetpack component and if you search "dependency changes" you'll see where updating actually requires a specific minimum version of another thing
Also sometimes a library will pull in an old version of another library it depends on, so you might be explicitly interacting with a very old version of a component just because you never added it as a dependency yourself. Then if that first library requires a much newer version of that dependency, you might suddenly get a large jump that requires a bunch of changes to your code, even though it doesn't seem to have anything to do with what you updated!
I have a big program in WiX that uses a bunch of MSIs, C# custom action programs, UIs, bootstrapper, you name it, it's there.
I'm having this problem: when I run a major upgrade, the previous version isn't being erased. That is, if I upgrade from version 1.0.0.x to 1.1.0.x, Programs & Features shows that both versions are installed on the machine.
This is a common problem, with many solutions here on SO. None of them are working for me -- if there's a post of SO about this, I've tried it.
I've been told that there's a one-to-one relationship between components in a major upgrade. That is, for every component that is removed, another component has to be added. When it's NOT a one-to-one relationship is when the old version doesn't get removed -- because there are still old components hanging.
Is there a way to determine what components are hanging? Like, in the log files or something? If I could determine what MSI is having the problem I could be far more proactive in solving the issue.
EDIT:
Although I haven't solved the problem, thanks to Mr. Urman's suggestions I may be on the right track.
I created that registry key, but... it didn't seem to do anything. However, I did search my uninstall logs for the word "Disallow", and I found this phrase 9 times:
Disallowing uninstallation of component: {GUID-HERE} since another client exists.
Also, this phrase appears before each grouping of the "Disallow" phrase:
PROPERTY CHANGE: Adding INSTALLLEVEL property. It's value is '1'.
This gives me something to go on. However, I can't seem to find the GUIDs that are mentioned! They're not in my solution nor are they searchable in the registry. Besides searching the registry, is there a way (Windows 7 32 bit) to find out what component a specific GUID corresponds to?
I've been told that there's a one-to-one relationship between components in a major upgrade. That is, for every component that is removed, another component has to be added. When it's NOT a one-to-one relationship is when the old version doesn't get removed -- because there are still old components hanging.
This is not strictly true. It's quite true of minor upgrades, and in certain configurations (those involving a late RemoveExistingProducts) major upgrades are just as picky. But your typical major upgrade functions more like the user had chosen to uninstall the old version, then to install the new version. Start by verifying your assumptions: make sure you have a proper major upgrade (you changed your ProductVersion and Product Code, and have the right entries in your Upgrade table, right?). Then diagnose.
How best to identify what's going on? In my experience, log files are your best bet. Since the older version is being uninstalled indirectly, you cannot use command lines to log it. So instead set the Logging policy by creating or setting the following registry value. (Remove it later when you want to revert the setting.)
HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\Installer
Value (Reg_SZ): Logging
Data: voicewarmup
Then run your major upgrade, find the appropriate log file that was generated in %temp%. (Consider cleaning out %temp% ahead of time to make finding it easier. Or sort by date.) Look especially at the uninstallation (which you can identify by ProductVersion, or the presence of UPGRADINGPRODUCTCODE). I'd look especially for lines like Disallowing uninstallation of component ... that contain a component GUID.
Once you have that GUID, you have to figure out what component it is, and how it got into its current state. You can manually examine your built .msi files (with a tool like Orca) to find the component, but few tools will tell you all the clients. My employer's product comes with a helper tool called InstallShield Msi Sleuth that can list all the installed products referencing a component code, or you can build your own from MsiEnumProducts or Installer.ComponentClients. You cannot just search the registry directly, because Windows Installer stores GUIDs in a compressed or packed form.
Then identifying the "why" could be the hard part. Or it could be as simple as an incorrect Shared DLL reference count, especially if you've only encountered this on a test machine that has seen non-released versions of your product.
As a related alternative, but only relevant to a minor upgrade or small update, you could set the EnforceUpgradeComponentRules Policy. This helps reveal problems as you hit them, rather than allowing Windows Installer to do its best to continue anyway.
I have a product.msi having some custom action and it has been released.
patch.msp is a patch I made for product.msi.
when I remove this patch from Control panel => Add/Remove Program, custom action which in old package always run. that is not my expectation.
I don't want to run custom action when patch uninstall.
I also googled, but no good way fro released product, I can't change the wxs file to add condition for custom action.
Anyone can help me?
Most thanks your help!
A patch features patch-specific properties such as PATCH and MSIPATCHREMOVE. Use these conditions on custom actions to make them run or not run during a patch depending on what is necessary.
Be careful with the conditions on custom actions, they are complicated to get right. Here is a "MSI Conditions Cheat Sheet" to help you. I have not tested these conditions - testing is the only guarantee.
I am throwing in some further patching advice since this is difficult stuff to deal with. Please do read to save yourself trouble. Hate sending people down the wrong track with such a problematic technology:
If there are errors in a product's uninstall sequence your fix involves creating a very carefully designed minor upgrade that you can deliver as a patch. This is one of the best uses of a patch.
A minor upgrade does not uninstall the existing installation, but rater re-caches a new MSI file to use for maintenance and uninstall operations. Hence you can fix the uninstall before it is run.
Create a minor upgrade, test it fully as a regular upgrade install, and then package it as a patch. A patch is merely a distribution / delivery mechanism for an upgrade that works.
Don't waste time making a patch before the upgrade is verified. This is a common mistake that wastes a lot of time. In fact if the minor upgrade works, a patch may not be necessary at all. Just use the minor upgrade unless your MSI file is enormously big and you want to deliver a small "hotfix".
If you need to include files in your patch, I recommend enabling "include whole files". Otherwise bit-level patching is done, and this is unnecessary complexity (unless your binaries are enormous).
Include only what you need in a patch. Add no files or settings that are not required, and you can make a reliable patch. Avoid adding custom actions if at all possible.
Be aware that a patch uses the same InstallExecuteSequence as a regular install, but you can condition custom actions differently with patch-specific properties such as PATCH and MSIPATCHREMOVE. Use these conditions on custom actions to make them run or not run during a patch depending on what is necessary.
This "fix uninstall approach" is one of very few scenarios where I find MSI-patching can be successfully used. Otherwise patching is very complicated and error prone. It is also effective for small "hotfixes" to huge products - which obviously is what the whole technology is designed for.
Check Stefan Kruger's installsite.org for more upgrades and patching tips.
Check out this well known wix tutorial for upgrades and patches. And MSDN.
I'm using AjaxControlToolkit and they decided to change their version numbering scheme. The change is documented here : http://stephenwalther.com/archive/2013/01/24/new-january-2013-release-of-the-ajax-control-toolkit.aspx
Basicaly, the newer versions have a lower file version (4.1.7.123 is newer than 4.1.60501.0, but 7 is smaller than 60501.)
Obviously, this causes issues in my MSI as it is now seeing a component with an higher version number already on the machine and thus ouputs this:
MSI (s) (7C:10) [10:04:14:996]: Disallowing installation of component: {22C7D2FC-179E-515D-B650-CE20A7B3F9E0} since the same component with higher versioned keyfile exists
How would i go and force the installation of this newer but lower-version-number component ?
P.S. Personal rant: AjaxControlToolkit guys for justifying this number by saying "And yes, I realize that 7.0123 is less than 60,919, but we ran out of numbers.". 4.2.7.123 would have worked, guys. You ran out of 3rd numbers, fine, you need to increment the 2nd.
Easiest thing to do is to install to a new location. That will avoid the checks completely. A hacked thing to do is to fake the File.Version column in the MSI but that will only get you through this once, eventually you'll need to get to a new location to address the problem.
You could also set the REINSTALLMODE to include "a" but that will just create all sorts of grief for you lately, so I can't really recommend that as an option.
Note: The AjaxControlToolkit guys did give you a huge headache. If they renamed their .dll, that would be the most helpful. Seems like the least they could do since they just broke their world so badly.
I installed Darcs a few days ago and have a doubt.
I am the only programmer and I usually work on two or three instances of the application, making new feautures. The problems cames because this instances modify the same source code file, so when I finished them and send to main repository they make a conflict.
Is there any way to deal with this? Can I write the same file in multiple instances without making conflict when pushing to main repository?
thanks
First of all when changes occurs at different places of the file there is generally no conflicts when merging. When two patches can be merged without conflicts one says that they commute. In your case it happens that you've modified the same part of the file in two different branches. In this case darcs don't allow you to "push" the second patch that makes the conflict.
There is two ways to resolve such a confilct, but you have to start to locally merge the both patches to get the conflict in your working repo. To do this just pull the patches from the main repository. Then you have to edit the offended file and resolve the conflict.
The first way is simple and the prefered solution, you have to "amend-record" the patch that is not yet on the main repository (look at the usage of the "darcs amend-record" command).
The other solution is to record a resolution patch, by calling "darcs record" and then pushing both the conflicting patch and the resolution patch. This solution tends to complicate the history and can make some later operations longer. However when the branch has been heavily distributed this solution becomes needed.