Uninstall exceptions in InstallShield - deployment

I have a setup project with InstallShield 2010. I'm deploying a configuration file during installation. However, when uninstalled, InstallShield decides to delete it (which is normal).
The question is, is there a way to keep the file on the hard disk even after the application in uninstalled? I don't want to reconfigure the application every time the user uninstalls/installs.
Edit: I'm using MSI project.

You don't say what project type you are using. Either way, put the config file in it's own component. For MSI projects, set the Permanent attribute to true. For InstallScript projects, set the Uninstall attribute to false.

Related

Is there a way to reset a UWP app using powershell?

I see that there are way to Get Get-AppxPackage or Remove Remove-AppxPackage UWP app from windows 10 using PowerShell.
I am wondering if there is a way to reset a UWP app? I require it for automated testing, I would rather reset the UWP app than uninstall and install again, as that would slow down the testing.
If you're looking to clear your package's ApplicationData then you want
appdata = Windows.Management.Core.ApplicationDataManager.CreateForPackageFamily(pkgfamilyname)
appdata.ClearAsync()
See MSDN for ApplicationDataManager.CreateForPackageFamily() and .ClearAsync()
Powershell has no 'await' affordance last time I looked (though it's been a while) so not so viable. If you're looking to muck with applicationdata you may find APPDATA.EXE handy. You can probably guess why I wrote it... :P For instance
APPDATA.EXE Clear foo.bar_1234567890abc
If you're looking to reset a package to its initially installed state, then no, there is no API other than uninstall + install
Remove-AppxPackage foo.bar_1.2.3.4_x86__1234567890abc
Add-AppxPackage foobar.msix
Settings' Reset option for an installed package essentially does that just slightly more efficiently. You're still going thru the full deregister and uninstall the package and then install and register it for the user so it may not be instantaneous. But that's the only way to truly reset a package to its initial state. Windows has various forms of user data associated with a package (ApplicationData, IndexDB, more) as well as system state cribbed and wired up when a package is installed for a user (what is the package, where's it live, that the user has it, that it's status is not tampered or otherwise unhealthy, more). The only way to truly 'reset' that to the initial state is a full remove then add.
If you just need to wipe appdata then .ClearAsync is the ticket.
I am not aware of any command that would do that for you (except for the UI available in Settings app). However, you may write a PowerShell script that would clear up the application data files in the app's folder (this is not an official solution, but seems to work based on my trials).
Go to
C:\Users\{your_username}\AppData\Local\Packages\
And find your app's folder there. There are several folders containing the application state.
The nuclear option is to just delete all the folders. Then the app will crash once on startup, then the system will automatically reset it and restore the folders.
The less invasive option I have now tried seems to be to keep the folders and just delete their content, except for the AC folder, which seems to be system protected. When I tried this with my app, it launched successfully without crashing and system recreated the state files anew on its own.
The rest of application files lives in C:\Program Files\WindowsApps, but those are just application DLLs and content files and are read-only, so they should not affect the app state at all.
You may want to perform additional deletion if you use a shared publisher folder.
For windows 10 build 2004+ there seems to be a powershell command Reset-AppxPackage now.
UPDATE
My mistake, it is available from version 20175 onward. So, should be available in 20H2.

How to reference a specific DLL for functionality in said DLL

Good day,
I have an application that I developed that transfers files between two machines ("site" and "server"). This application was set to target dotNet 3.5. Furthermore, I am using Renci.SshNet to handle the connections between the machines and the transferring of said files.
The issue that I am facing currently though is that about 70% of the "site" machines do not have a standard dotNet and is also quite old; thus these machines do not support all the required functionality as the external dll makes calls to System.Threading.WaitHandle.WaitOne() and System.Threading.WaitHandle.WaitAny(WaitHandle[], Int32) and other overloads of these methods.
The workaround that I have for this though is to install netfx20SP2 or netfx30SP1, yet I am not in the position to perform this update on all machines as they are scattered across the country and have data limitations (bandwidth and cap).
What I want to do possibly is to embed the System.Threading dll that I have downloaded and then the application should use those classes instead, or alternatively just point the application to use the said dll.
Is this at all possible, or do you have to load the dll into the GAC? And also, will it be possible to "run" this higher version of System.Threading in the application while the system itself is on a lower framework version. Something is telling me that the best bet will be to actually run the service pack installation to avoid unnecessary coding but I'm not sure exactly how to approach this.
Thank you in advance for any assistance / suggestions,
JD
To allow the execution of an application that, let's say, targets .Net 4; while the machine itself only has let's say, .Net 3.5, installed, one can redirect Windows to check the local (executing) directory for dlls that should contain the required symbols loaded into memory instead of the default symbols that get loaded upon execution (the default would be the NetFx installed on the machine - which I believe the highest version of the framework that can be found upon loading when the execution starts or would be the highest available version that is lower or equal to the targeted framework).
This file's contents (myApp.exe.local) are ignored. It is just there to tell Windows to
look in that folder for the applicable symbols and if not found, the system will roll back to attempt to load these symbols from the NetFx directory.
Read more at Microsoft Dev Center - Docs (link is attached to the following paragraph which is a Copy-Paste of a section of this document).
To use DLL redirection, create a redirection file for your application. The redirection file must be named as follows: App_name.local. For example, if the application name is Editor.exe, the redirection file should be named Editor.exe.local. You must install the .local file in the application directory. You must also install the DLLs in the application directory.

Custom Action not being fired

Recently, I was assigned the task to create a deployment package for an application which btw, I'm totally new at. So far, so good.. Now there is a requirement to extract files from a zip file which will be bundled with the setup file. So, I had to write custom actions in the 'Commit' section of the Installer class. I added the Installer class in a new project of type 'Class Library' under the same solution. I wrote the code after 'base.Commit(savedState)'.
I tried showing MessageBox at the event entry point, used Debugger.Launch(), Debugger.Break() but somehow, no matter what I do, it seems that the custom action is not willing to be hit at all and the application just installs itself. I searched a lot of sites and blogs but no help so far.
I've assigned my installer class (SampleApp.exe, in my case) to all the Custom Action's modes (Install, Commit, Rollback and Uninstall) in the Deployment project. Any help.
P.S. I'm using a Visual Studio 2010 setup project.
Thanks, in advance!
You should probably be trying a class library Dll, not an executable (which is typically for something like a service).
You don't need it all the nodes if all you're doing is calling at Commit. And why Commit? Install is just the same in most cases.
If you're not seeing a MessageBox then probably your CA isn't being called, and that may because it's not a class library. Note that your CA is not running in the interactive user context - it's being called from an msiexec process running with the system account, so you must be very explicit about (say) the path to the zip file, and any user profile folders will probably fail because the system account doesn't really have them.
What files are these and where are they going on disk? If they are user profile files you can install the zip files to a per machine location and then have the application itself unzip the files to the desired location on first launch. Unzipping from within your setup is not good practice - it is error prone and bad design.
Using the application allows proper exception handling and interactivity (the user can be informed if something goes wrong). Set some registry flags in HKCU when you have completed the unzipping so it doesn't happen more than once, and perform the unzip once per user.

MSI, Repair runs but I don't know why

I have an MSI package I maintain with Installshield 2012 Pro.
The package was created a few years again and requires periodic maintenance as new versions of the application is installs are released by our development team. This MSI has been used in many locations, on many machines without issue.
At one customer location, they've install about 20 copies of the application on 20 machines. Each machine is built exactly the same.
Periodically, for an unknown reason registry entries relating to that application go missing. Not all of them, a select one or two... the same entries always go missing.
We so far have failed to track the exact root cause, however one of our support engineers noticed the MSI repair dialogue appearing when they opened the application shortcut. Following this, the registry entries went missing.
On each instance of the registry entries going missing we have removed the MSI from the c:\Windows\Installer directory. On machines we've made this change too, the registry changes so far have not disappeared again.
This leads me to think the MSI is somehow removing the selected registry entries during the repair, but I don't understand how.
There are at least 50 registry entries under the same key as the entries that get removed. (these are created by the application not the installer)
The MSI package doesn't insert any keys at all during install
There are no custom actions at all
I only have one key file set in the whole MSI, and this is for a component installed in Windows\system32
None of the shortcuts are 'Advertised'
There appears to be a clear link between removing the MSI from the Installer directory and no further occurrences, but I fail to see what in my MSI could cause specific registry keys to disappear.
I realize the exact reason this this is subjective to my MSI or the customers systems, so as generally as possible I ask:
Why would Windows launch the MSI repair function, considering the above
Can an MSI alter the registry, considering the above
Is there anyway post installation of an MSI to disable the auto repair function for this MSI?
How should I alter the MSI to ensure auto repair doesn't occur?
Thanks
Start by proving whether the auto repair is related to your product. Check the application event logs for the component id that caused Windows Installer to kick off the auto repair. Then, if it's part of your installer, figure out why.
It seems unlikely that your MSI would alter the registry. Although you do not specifically say there are no RemoveRegistry table entries, it's hard to imagine any snuck in accidentally.
There are only bad ways to disable auto repair (some global, some involving not registering your installer). Avoid them.
First figure out what's wrong. Then figure out how to fix it. For instance if in step 1 you determine the component triggering auto repair is part of your install, perhaps set the logging policy on a machine where this occurs so you can get a verbose MSI log.

Uninstalling an in-use shared assembly leaving WinSxs in a bad state

I am having troubles uninstalling a shared win32 SxS assembly using Wix3 on WinXP. My wix file looks pretty much like the one described in http://n2.nabble.com/Tutorial-How-to-install-files-into-WinSxS-td841475.html.
The problem is, if a module from the assembly is in use, the uninstaller completes with a success errorcode but leaves the assembly in a broken state: the manifest and security catalogue have been deleted, but the assembly directory still exists with my dlls in it. The DLLs survive reboots, so are not marked for deletion in any way. There are no obvious errors in the MSI log file.
If I try re-installing the package, it skips installation of the assembly. The components are no longer registered, so I can't get Installer to try uninstalling again. The following is shown in the msi log on subsequent installs:
MSI (c) (98:44) [11:46:56:263]: skipping installation of assembly component: {26A273E7-7F9A-4F77-9FA8-5E413A155BEC} since the assembly already exists
I can't find a way of bringing the SxS back into a good state short of manually deleting my assembly's directory, which at this point is no longer being protected by XP System Restore.
While my actual installer is much more complicated, I have been able to reproduce this with a very basic installer that has a single feature containing a single component. That component contains a dll, a manifest and a security catalogue. The dlls <File> element has KeyPath, Assembly and AssemblyManifest attributes set. Once installed, I can simulate a process loading the assembly by opening the DLL in MSVS.
Is there an extra action I should be invoking on uninstall to detect and prevent this situation? Alternatively, is there a way of forcing the install operation to be performed even though the DLLs already exist in WinSXS?
Somewhat related, I also have a problem if I try to upgrade the package that installed the assembly if the assembly is not changing. The installer decides that it does not need to reinstall the assembly (since it has not changed), but then when the SxsUninstallCA runs, it goes and removes the assembly. From Installer's point of view, the component is still installed, but the files are gone.
I'm working on something which I believe I'll run into this same problem.
My assumption at this point is that I’d have to solve this with a little mojo from the HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations regkey, and a possibly bit of file permission smacking (if the files were still locked).
Which of course, requires a reboot.
Of course, in your installer, you could check for the presence of the keys and block on install until they're gone. (ie "you need to reboot").