Environment Variables don't get updated - visual-studio-2010

I have made an installer, a Visual Studio SetupProject, which installs a software I developed and checks if a certain program is installed on the target machine. If not, it launches its original installation file. This file is copied to the target machine during the installation and is launched throughout a CUSTOM ACTION.
Everything goes well with the installation but I have only one problem:
The separate installer, which I didn't develop, should append a PATH to the User Environment Variables referring to the path of a BIN folder in its own installation folder. It doesn't! I checked the PATH registry value of the User Environment Variables and it really doesn't get updated.
However when I install the program separately everything goes well!
I tried to to change the PackageAs Property of the attached installation file from vsdpaDefault to vsdpaLoose in order to make the operation, probably, a bit more "separate" sort of say but it didn't change anything.
Why do the Environment Variables not get updated? My guess is that my installer doesn't have some kind of rights necessary to change these variables.
BTW I'm using Visual Studio 2010.

I believe Hans has the answer. If you fire off that setup from yours as a custom action then it runs with the local system account. That means it is not running as the current interactive user therefore it cannot update the current user's path because it's not running as the current user.
This setup by definition cannot be an MSI-based install because it would fail - you can't do recursive MSI installs - therefore it is code based and depends on running in the interactive user's context.

Related

getting the DLLs in the application's home directory to be called upon instead of the registered DLLs

Yes, I know vb6 ancient and all that. It's still an interesting question. and the issue might not even be with vb6....
Background: We have a server running a vb6 application for our users who access this via Citrix. This installed application accesses its DLLs (also written in vb6) from a "shared folders" location.
What I want to do is have the previous version of this same app on the same server, accessing it's own set of (previous versions) DLLs. I am half way successful. the renamed app in another directory runs. But it crashes immediately upon using any feature that draws from the DLL's code.
Apparently the registered DLLs of the current version are being called upon. I dont want that. I want the DLLs found in the same directory as the renamed older app to be called upon.
Can that happen in a windows server? is this an installer's settings issue? Have you ever had this situation before? were you successful?
thanks in advance.
Harry
Post Script:
The bosses decided that experimenting with the DLLs and system settings was a waste of my time and not worth the risk. So they're throwing money at it and another server will come online for the sole reason of providing the previous version to the citrix users who want it. Thank you to all of you who pitched in with great tips and leads to other posts. (yeah I'm sort of disappointed too. Kind of wanted to know what the solution was to this.....)
The OS should be looking for the dll’s in the following places and order
The directories listed in the App Path registry key (HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionApp
Paths) if any
The directory where the executable module for the current process is located
The current directory
The Windows system directory
The Windows directory
The directories listed in the PATH environment variable
Given that you are using a shared folder for your dll’s, I would suppose that the app is setting the current directory to your shared folder OR is using the PATH environmental variable to specify where to look. I don’t think it is using the app path registry key path because that is version specific and you said you are using a different version.
I would suggest your try setting the path via HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionApp Paths

After aborting the installer if i try to install again, installer is still pointing to old path

I am trying to install a installer developed using InstallShield 2008. While installing after selecting the destination path i am aborting the installation.
When i try to install again by default it is taking the destination path as previously given path which was provided before aborting the installation.
And also it is not allowing me to install in different path.
For Example:
*Step1 : Installation starts
Step2: Destination path as C:\Installer
Step3: Click next and abort installation
Step4: Start the installation again
Step5: Provide Different destination path as C:\Installer1*
Here installation is failed. Because destination is still pointing to Step2
My question is from where Installer is taking the old path.?
Persisted Path: The technicalities appear to be relatively straightforward: the old path is read back either from the registry or from disk each time the setup is launched, and a custom action in the setup's GUI sequence must have persisted the path "somewhere" during the first run (this is erroneous design, see technical comment below). Reading back the value can be done by using AppSearch (built-in MSI feature) or by means of a custom action.
Registry / Disk: As to finding where the value is read from. The easiest would be to just search the registry first for the literal path. Just open regedit.exe and search for the path there. You can also look for the custom action that does the persisting (or the AppSearch or custom action that does the retrieval) and see if it is a script with code you can see - then you should be able to see where it has persisted the path. Use Orca or a similar tool to view the Custom Action table. The custom action can also be compiled and undecipherable. Do you have the setup source? The path can also be persisted to disk, but the registry is most commonly used. Remember to search both HKCU and HKLM.
Involved Debugging: I can't see why you would, but it is also possible to use ProcMon.exe to monitor what registry locations your MSI reads and / or writes to. This is involved debugging and should never be needed for something this simple. Just mentioning it as a technical option. Generally the last resort we have to figure out the strangest problems.
Technical Comment: MSI setups are not supposed to write anything to the registry or disk from the setup's user interface sequence (setup dialogs). All changes should be made from the installation sequence (InstallExecuteSequence) which also generally runs with elevated rights - the user interface normally runs with user rights. This InstallExecuteSequence sequence is kicked off from the last dialog in the GUI sequence, and runs the file copy and system change operations. Control then returns to the GUI sequence to show the setup complete dialogs. It is also possible to run the setup silently, in which case the InstallUISequence never runs and all custom actions inserted there fail to run. Accordingly custom actions should be present in the InstallExecuteSequence as well as the InstallUISequence if they are to run in silent mode. This potential design flaw is a very common silent deployment error which occurs when setups are not designed properly for silent running. Remember that all corporate deployment runs silently. Setup GUI is highly overrated (in my opinion - a "fact" that could change in the future).
It is still possible for an MSI setup to write to the registry or disk from the InstallUISequence by using a custom action to do so. Such a custom action would normally not have access to write to HKLM or to protected parts of the disk - unless the whole setup runs elevated because it was launched from an elevated command prompt (for example), or launched by an admin who elevates it via the UAC prompt.
In other words: this setup is badly designed, but I guess that is clear already.

InstallShield Custom Action failing because user installing in 64-bit Program Files directory?

I have a 32-bit legacy application that allows users to specify the install path as part of the setup (pretty normal stuff...). I also have a custom action defined that runs a silent background install of another required bit of software after the initial installation is complete.
All is well when users install to the 32-bit Program Files (x86) directory.
Where I am running into problems is when users specify the 64-bit installation directory, Windows automagically changes the install path in the background to use the (x86) Program Files folder, which is fine, except that my custom actions that use the same INSTALLDIR property after the initial install is finished still think that it should be the 64-bit "Program Files" path - so the install fails when the custom action can't find the EXE file it's looking for.
My program is essentially exactly the same as the one described here by another developer but never resolved in that forum: http://community.flexerasoftware.com/archive/index.php?t-216268.html
Does anyone have a clue what a valid workaround for this is? It seems pretty basic that an installer should not fail just because users think they should install to "C:\Program Files\Appname" instead of "C:\Program Files (x86)\AppName".
I did peruse the similar questions on here but I don't see anyone else with this issue using custom actions.
In my experience you need to change to a 64 bit template to install to program files. General information in the tree > Template summary > change to x64;1033. At least one file needs to be marked as 64 bit in each directory. It is a check box on the component property. Be sure to check your custom actions still obey run conditions on major upgrades. I am having issues with that currently. Major upgrades on mine is set to remove all and it runs all custom actions no matter the conditions on the removal portion of the script.

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.

C# Deployement retaining files over an installation

I have created a Setup and deployment project using the Visual studio and install the setup.
After i install the setup it copies a few files(XML) which on using of the application are configured programmatically .
Now , If the user is reinstalling this setup again i need to ask the user whether these configured files need to be overwritten or be retained ??
Any idea as to how this can be accomplished ?
Thanks & Regards,
Fran
Look into file versioning rules for Windows Installer.
In short, assuming that these XML files you refer to are unversioned text files, MSI will compare the Created and Modified dates and will not replace the updated XML files which you say are updated programmatically (post-install-time).
I would suggest several other variables you need to consider to make sure things are working as you expect: major vs. minor upgrade, and the REINSTALLMODE property.
I find that the best way to approach this kind of scenario is to implement the "preserve changes" logic in your application as opposed to via the setup. This avoids complicating your setup and yields greater control of the config process since all logic is embedded in your main EXE file. This means you can step through the process and debug it the normal "development way".
To achieve this you can install your "base config" files to a read-only location such as
%ProgramFiles%\MyCompany\MyApp\MyConfig*.*
Then your application can detect on launch whether existing config files exist in the user profile (or in a writable shared location), and ask the user whether the new config files should overwrite the existing config or not. You can also easily implement backup functionality for the old config.
In order to ask the question only once per user after deployment, the normal apporach is to flag HKLM with the latest installed version of the application and then write a corresponding flag in HKCU when the copy operation has completed or the user dismissed it:
HKLM\Software\MyCompany\MyApp\Version = 2.0.0
HKCU\Software\MyCompany\MyApp\Version = 1.0.0
In the above scenario version 2.0.0 of the application has been installed, but the per user config copy has not run for the user in question yet. Once it has run the HKCU version will be set to 2.0.0 and the operation is not run again until HKLM is incremented.

Resources