VS setup project destroys self when installed files are deleted - visual-studio-2010

This should be pretty simple, but I can't seem to get it. I have a setup project (VS2010) that packages a few dozen image files (along with my SQLite file) and copies them to the user's computer when the program is installed. As these are essentially "stock" images, it's ok if the user deletes them (there is functionality to do so from within the program.) However, after one or more of these images have been deleted, the next time the program starts it gives a "Windows installer" dialog box, and deletes all of the remaining data files!
What I think is happening is the program sees the missing files, assumes the installation has been corrupted, and tries to go into some kind of recovery/uninstall mode. I'd like to know how to indicate in the setup project that the files need to be installed, but may be removed by the user at any time.
I have tried several combinations of File properties, and nothing seems to do quite what I want, which is for my installer to put them where I say and never think about them again. Do I have to reinvent the wheel and do this through a custom action??
EDIT: Transitive and Vital had both been set to True. Setting them to False causes the program to re-add the deleted images back after it has been restarted! I'll probably go with a custom action if I don't get an answer.

When using a file association or advertised shortcut Windows Installer automatically checks if component key paths are missing. If a key path is not found, a repair is trigger to reinstall the component.
Most likely your installer repair process does something that removes the other files.
A solution is to not register your components with Windows Installer. This is done by using a null component GUID and it's not supported by Visual Studio setup projects (it is however supported by most of the other setup tools).
Another solution is to make sure that your image files are not key paths in their components. This is also not supported by Visual Studio.
If you want to use a setup authoring tool which offers more control, you can take a look at this list: http://en.wikipedia.org/wiki/List_of_installation_software

Related

Windows installer is too clever, tries to repair when tester deletes config file

Our application is deployed to the target machine with an msi file. All works nicely. Our tester has gone through his plan, and one of the tests requires deleting the application's configuration file. The application is designed to alert the user with a dialog on startup saying "missing config". However, what happens is that - somehow! - the software starts the installer again and retrieves the missing file from the msi! Which is nice, but not what we want. How do we disable that behaviour?
without going into much depth of the windows installer mechanics (if you interested in that there a plenty of articles about this), the shortcut of the software is probably advertised, which means the windows installer checks if everything is in its place before the software is started.
if you can edit the msi, make the shortcut non advertised.
if you can't, install it with DISABLEADVTSHORTCUTS
e.g. msiexec /i myMsi.msi DISABLEADVTSHORTCUTS=1
please note that this is only a quick (and dirty) workaround,
to fix this proper you need to understand the whole windows installer advertising (also called repair or self resiliency) mechanism.
but explaining all the causes and the mechanism of the repair is far beyond this answer and there are quite some articles and posts about that on the internet (and especially on MSDN and stackoverflow)
There is a more correct answer to this, and it is NOT DISABLEADVTSHORTCUTS. You set the component id to null in the MSI file to prevent repair of that individual file. See ComponentId comments here:
http://msdn.microsoft.com/en-us/library/aa368007(v=vs.85).aspx
Edit the MSI file with Orca to delete the Componenty ID, and write an uninstall custom action to delete the file at uninstall if it's there.
In addition, that's a redundant test. Windows will restore that file for you if it's missing, so the idea that you need a test to notify that it's missing is pointless. The true test should be that Windows will restore the file if it's lost, and your app needs to do potentially nothing about the missing file.
You don't mention what tool you are using to make your MSI but I'm going to go out on a limb and guess Visual Studio Deployment Projects (.VDRPOJ).
One of the (many) horrible things about this tool was that it fails to expose the foundational concept of components. Instead it makes every file a key file of it's own component and hides the existence of the component from you. I say 'was' because Microsoft killed this project type in VS. There are around 50k people complaining on UserVoice to bring this tool back and I'm guessing that 49,990 of them don't know what a key path is.
Windows Installer has a concept called the component rules and each component has a keypath. The keypath teaches MSI how to handle repair scenarios. But your tool has to allow you to be able to control this to make it work.
Windows Installer is functioning exactly the way it's supposed to function. You just aren't up to speed on what that is.
However, if you want to ignore Windows Installer best practices and continue using the tool you use today, the trick is to install the app.config file as a different file. Then have the application copy the file to the real file name on run. Windows Installer won't service what it didn't install.
Several answers have been provided that can work:
You can install the file with a blank guid. Then you need to remove it on uninstall using the RemoveFile feature. You will also run into issues if you want to replace it during an upgrade. Could be tricky at times.
You can disable the advertised shortcut(s), but this affects too much in my opinion.
Finally you can use my suggestion to install a separate non-advertised shortcut to use to launch the application. Such a shortcut bypasses the self-repair check. It may still be invoked by other means such as missing file associations, COM registration or similar, but those are exception states.
However, my preference is that an application can start without a config file present, if at all possible. I always suggest a good startup routine with "internal defaults" available. The startup routine should also degrade gracefully if faced with any file system access denied conditions.
Most importantly you should place this config file in the userprofile so you can generate the file on first launch for the user in question. It can even be copied from a read-only copy in the main installation directory.
When you generate a file from internal defaults and put it in a userprofile location, the file will have no interference with Windows Installer at all. The issues that results is how to clean up user data on uninstall. I discussed this with Stefan Kruger (MSI MVP) at one point, and I agree with his notion that user data is indeed user data and should not be automatically dealt with by your installer at all. Leave it installed, and clean it up via system administrator tools if necessary - for example logon scripts.

Visual Studio setup project "PackageAs" "extremely loose"

We were hoping to create a setup project which would allow for a pick-n-mix approach to which files were included for each local client installation.
Basically we've got a core setup.exe which we only want to build once, and which contains most of the product. But for each client there's a custom DLL which fits their solution. The custom DLL is loaded dynamically at runtime by the software and that's working fine. The problem is in the setup.
Of course we could 1) write an individual custom Setup.exe for each client too 2) keep a single setup.exe and customise it each time we want to do a build for the customer
But both those approaches are problematic.
For reasons too complicated to go into, the below approach is going to be the safest and most straightforward:
Maintain a single setup project
add all the custom DLLs to the setup project but set them to PackageAs=Loose (and also Vital=False)
then, every time we want to rollout the install files to the customer we send the setup files minus all the custom DLLs except his own
Our problem is that this approach falls down when you run the setup.exe on the client. Everything's fine except that the setup.exe still knows about all the DLLs you've quietly removed from the file system for this customer. And the installer starts shouting if it doesn't find all the files where it expects to find them:
Actually, this isn't a problem because you can hit Continue and then everything works fine.
Except that actually it is a problem because if you're selling to Pepsi (we're not, but say we were) you sort of don't want the installer to moan that it can't find CocaCola.foo.dll in the middle of its install.
We almost want an additional setting of Extremely Loose for the PackageAs field so that the installer knows not to even worry if it doesn't find the file.
Is there a solution within our existing approach without having to learn a third-party installer?
It sounds like your optional components should be created as Merge Modules and then you'd need a specific installer created that includes only certain modules. It sounds like you have some client specific libraries you don't want exposed to your other clients. Of course this means you'll need a build for each client, but that is something that could be automated.

Where does VS2010 store the Base Url for Classic ASP websites?

We have some legacy Classic ASP websites to maintain, and are wanting to use VS2010 to edit them, due to familiarity because of lots of .Net work.
I can open the website inside Visual Studio.
I can configure IIS to run the website based on the working folder used in VS2010.
I can configure VS2010 to automatically open my default browser pointing to the correct location, using the 'Base Url' setting in the Properties page.
What I CAN'T do, is work out where VS2010 stores this value, as there's no mention of it in the solution file that VS2010 has created, and as there's no project file for the website, there's nothing there too. Yet, when I close and re-open VS2010, it somehow retains this information.
This is important to me, as I need to be able to commit all files to our source control for use by other developers and, ideally, not have them worry about setting this value themselves.
So, the question is: Where does Visual Studio 2010 store the Base Url when working on Classic ASP websites?
I don't know where this is saved, but in tracking things like this down in the past I typically take the following approach:
Open Visual Studio and change this one setting
Apply the changes
Look for all files that have been modified in the last 1 minute in the project folders and in the Visual Studio folders
You can be sure there will be at least a few other files changed that are not relate to this, but it should narrow your search. You may want to re-close VS before searching too, but that will modify other files as well (making for a slightly larger pile of changed files to sift through).
If you still don't have it, search the registry (but I cannot imagine this would be where it was storing anything project specific).
EDIT:
Just created a new project and played with setting this property. It is definitely stored in the .suo (Solution User Options) file for the project, in the root of the project folder as #Lankymart suggested (and is a hidden file if you are not seeing it). It is not stored in plain-text.
You may be able to access it programmatically here: http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.shell.interop.ivspersistsolutionopts.loaduseroptions.aspx
As there are a ton of absolute path settings in these files, moving it to other environments is not really an option. I would suggest you are stuck with project start up documentation that lists these settings as part of the project setup process. I think any other solution is going to be equally annoying|fragile (or worse).
Not sure if there is another way to accomplish what setting the base URL does without managing from the Start Options panel - that is likely your last-best hope for a solution.

visual studio 2010 setup project - removing registry

I have 2 msi files that I run silently one after the other from win forms application (master installer for that matter). Both of them configured to write to registry to same location,
for example:
HKLM\Software\MyProduct\MSI1
HKLM\Software\MyProduct\MSI2
Now, I run uninstall in reverse order and when uninstall done, MSI1 removed from registry, but MSI2 is stuck there... Is there anything can be done about that without custom action or coding?
This happens because your registry entries use the same component as another product installed on the machine. For example, you copied the setup project of an existing product and used the copy to create an MSI for a different product.
To avoid it, you need to make sure that each MSI uses unique component names and GUIDs. It's not easy in Visual Studio setup projects. You can try editing the project file. If it doesn't work, it's better to start from scratch with a new setup project.
Ok, I found problem in VS2010 (Big Thanks to Cosmin Pirvu) and just will go on and put here the 2 solution options I see so far. But first, the problem:
As I mentioned I have 2 entries:
HKLM\Software\MyProduct\MSI1
HKLM\Software\MyProduct\MSI2
But in code, they look the same because MSI1 and MSI2 being "place holders":
HKLM\Software\MyProduct[ProductName]
So, the name is identical and properties identical this is why we get same component id for both!
Two things (as far as i see) you can do:
Instead of [ProductName] enter actual product name (hard coded)
(What I did is) In registry entry property, in condition field, enter meaningless string (make it really meaningless, so it wont meat reasonable condition, i used guid with leading __).
Thanks for all answers

Why don't files automatically get checked out from VSS when I edit them?

This is driving me crazy and has resulted in lost work (not much, at least).
Normally, when I edit a file in Visual Studio, it's supposed to automatically check that file out in source safe. On multi-project solutions (e.g., web app with class libraries), sometimes none of the files in one project would automatically get checked out, though exiting & reloading visual studio may fix that problem temporarily. Furthermore, project files are never automatically checked out. Whenever I add/remove code files, I have to remember to explicitly check out the project file as well (otherwise we'll have issues with code files not showing up in the solution explorer, or trying to load non-existing files).
We're using VS-2008 and VSS 2005. Do you have any idea how I might fix this? There are no more visual-studio updates/fixes on Microsoft Update.
You need to ensure the files are read-only, or VS won't be able to tell that they are version controlled (or, at least that's what it uses to determine it). You can tell VSS to set itself up so getting the latest version places the files RW on disk.
There may be other problems here, but that's what comes to mind first. My advice (that I took myself) is to migrate to SVN or an alternative. Losing work is unacceptable.

Resources