Why is it a good idea to limit deployment of files to the user-profile or HKCU when using MSI? - wix

Why is it a good idea to limit deployment of files to the user-profile or HKCU from my MSI or setup file?
Deployment is a crucial part of most development. Please give this content a chance. It is my firm belief that software quality can be dramatically improved by small changes in application design to make deployment more logical and more reliable - that is what this "answer" is all about - software development.
This is a Q/A-style question split from an answer that became too long: How do I avoid common design flaws in my WiX / MSI deployment solution?.

As stated above this section was split from an existing answer with broader scope: How do I avoid common design flaws in my WiX / MSI deployment solution? (an answer intended to help developers make better deployment decisions).
9. Overuse of per-user file and registry deployment.
Some applications won't run correctly for all users on a machine, because the user-specific data added during installation isn't correctly added to other user's profiles and registry. In other words the application just works for the user who installed the software. This is obviously a serious design error.
There are several ways to "fix" this, but the whole issue of deployment of per-user files and settings is somewhat messy for a few fundamental reasons:
How do you reference count components installed multiple times? (for each user on the machine)
What do you do with the installed data and settings on uninstall?
How do you deal with new files and settings to install that differ from the ones that are on disk and in the registry and have user-made changes? Surely you don't overwrite automatically?
There are no real clear cut answers, but there are several alternative ways to deal with the "problems". My preferred options are 2 & 3 since I don't think Windows installer should deploy, track or attempt to modify or worse yet, uninstall user data and settings at all - it is user data that shouldn't be meddled with:
9.1 Using Windows Installer Self-Repair or similar
The first option is to get settings and files and HKCU registry keys deployed properly via the setup itself or setup-like features. There are two major ways to do this: relying on Windows Installer "self-repair" generally triggered by an advertised shortcut, or using Microsoft Active Setup.
Self-repair is what happens when you launch a shortcut to start your application, and Windows Installer kicks in and you see a progress bar whilst "something" is being installed. What is typically added are HKCU registry entries and user-profile files.
There is also another alternative to achieve this, it is called Active Setup and is also a Microsoft feature. It essentially registers "something runnable" to run once per user on logon. This can be used to set up per-user data. Active Setup allows "anything runnable" to be executed - for example a copy of files to the user-profile. .
Both of these options mean that the user data and settings are copied in place once - and from then on they are not generally touched, but in the case of "self-repair" might get uninstalled for any user who actually runs the uninstall of the application (unless the setup is designed not to do so).
Although setting up user data with self-repair and Active Setup are "established" methods to get applications running properly, it seems wrong to track user data with Windows Installer components. Why? Because it is really user data that shouldn't be meddled with once initialized.
Accordingly my honest take on the whole issue is to try to avoid deploying user specific data or registry keys and values altogether, and this is what is described next as two other user-data deployment methods.
9.2 Application Initialization of User Data
The second alternative, and one that I find much cleaner, is to change your application executable to be able to initialize all per-user settings and files based on default setting and templates copied from a per-machine location or based on application internal defaults (from the source code) instead of writing them via your setup.
In this scenario Windows Installer will not track the files or settings that are copied to each user. It is treated as user data that should not be interfered with at all. This avoids all interference such as reset or overwritten user data during upgrades and self-repair (and manual uninstall and reinstall).
If there are cases where "fixes" must be made to application settings, this can be achieved by having the application executable update the settings for each users on launch, and then tag the registry that the update has been completed.
The overall "conclusion" is that your setup should prepare your application for first launch, it should not set up the user data and settings environment. All user-profile files and HKCU settings should be defaulted by the application in case they are missing on launch - this yields a much more robust application that is easier to test for QA personnel as well. This is particularly important for Terminal Servers where self-repair is not allowed to run at all. In such cases the application data will be missing if you rely on self-repair to put user data in place.
9.3 "Cloud" or Database Storage of User Settings
To take things a step further in today's "cloud environment" - and this is in my opinion the preferred option. Why should your application be restricted to files and registry keys and values? Why not store all user specific settings in the solution's database?
Full access, control and persistence for all settings without any deployment issues at all.
You do get new management issues though, and they must be shared between developers, system administrators and database administrators. But isn't the cloud pretty much the industry standard by now?
We have been struggling long enough with roaming profiles, corrupted user registry, mishandled user-profile data files, etc.... Developers, save yourself a lot of trouble, and create yourself some new database management issues instead of deployment issues - and start yelling at a whole new bunch of people! :-).
Settings in databases are:
Not suffering from "dual source problems". There is one instance, and it is updated in real time. Not like the synchronization problems seen with user-profile and "roaming".
Inspectable, manageable and patchable
Revisable (version control - can revert older settings)
You could even "tweak" all the user settings from your setup still by running database scripts as part of deployment, but if you are in a corporate environment - isn't the thought of just raising a ticket and then have your database administrator run the maintenance scripts with proper transaction support and rollback much more appealing?
Even if you are delivering a large, fat-client vendor application for general distribution and third party use (in other words not a tailored, corporate client/server solution where you are guaranteed to have a back end database), one should consider cloud storage of user settings by having users log on to a cloud using their email or similar and then synchronize settings in real time.
Such large applications generally always need to "cache" some settings files on the computer and in HKCU, but it seems more and more possible to save all settings in a single temporary file in the user profile area which is entirely "sacrificial" and even possible to delete if it is corrupted and then download the last saved settings.
Instead of hosting the cloud yourself, it is obviously possible to use company DBOs to configure their own company-wide cloud where they have full control of all settings, and can also enforce mandatory policies and restrictions for your software's operation. Not to mention the proper backup that is possible for all user settings.

Related

Prevent authorization popup when using SMJobBless

we are developing an application with a Helper Tool - which is installed into the system using SMJobBless. This works as expected; but there is a caveat.
We do frequent automatic deployments - sometimes more than one per week. Everytime the Helper Tool version changes, we re-register it - causing a password prompt. These 2 factors would quickly become irritating to our users.
Is there a way to have the password prompt appear only once, during the initial Helper Tool installation? Could subsequent updates happen without a prompt? Perhaps there is a way to leverage the existing Helper Tool to install a newer version of itself?
Short answer: No. SMJobBless() always prompts for admin credentials. There's no way to stop it from prompting. If you call this API, it'll prompt (or fail).
Longer answer on workarounds:
If your helper tool is running with admin/root privileges, it could theoretically replace itself with a new version. Think very carefully before doing this. Getting this right and maintaining security is very difficult, and the fact that even the major OSes have had vulnerabilities in installer functionality is a strong indicator that the risks of going this route may outweigh the benefits.
If you must proceed, read up on:
Race Conditions, Secure File Operations, and Time of Check vs Time of Use
Apple's Security APIs, particularly SecRequirementCreateWithString and SecCodeCheckValidity.
macOS Code Signing In Depth and the Code Signing Requirement Language
You would have to ensure that your helper tool cannot be tricked into replacing itself with (or executing) malicious code, or you will have opened your software up to being a trivial root exploit vector.
Also note: Regardless of what Apple currently does to verify helper tools installed by SMJobBless, it is conceivable that they could tighten the requirements in the future and refuse to run helper tools that have been modified since they were installed via SMJobBless. The safest method (in multiple respects) is to just call SMJobBless whenever you need to install/update the helper.

How to prevent unauthorized MSI installation?

I have two versions of the same MSI package: 'genuine' and 'developer'. The former is intended for shipping, whereas the latter is built on developers' computers for the sake of testing, etc. I want to prevent accidental leaking of the 'developer' version, so that the end user couldn't have it installed. What are the possible approaches?
The MSI is built with WiX, just in case.
I've seen Securing an msi to prevent unauthorized use, but the answers there are focused on preventing launch not installation. I don't need to obfuscate, encrypt or protect the package contents. I only need to protect unqualified users from accindentally screwing things on their machines, due to erroneous packages being installed.
Honestly, because MSI is an open book ( Edit with ORCA ), it's best to do this type of enforcement (DRM) in the application at runtime. I could suggest all sorts of techniques in the MSI but they could be removed by someone knowing what they are doing.
What is your "leaking" concern? Do you not trust your developers? Do you not trust your CM / Release practices? Do you have a strong NDA in place? Proper IT security?
If you are trying only to prevent accidental misuse - that is, someone unknowingly installing a developer copy who wanted a user copy - I would suggest a simple launch condition. You would document that "developers" must put something on their machine (perhaps a file, a registry key, or even an environment variable), and have the msi check for that. It would then refuse to install unless the "I am a developer" footprint was there.
If you want to avoid the footprint, you could require that "developers" launch the msi from the command line and pass DEVELOPER=1 and instead check for the property. Or more extreme you could require specific and changing values for the DEVELOPER property. It all depends on how annoying you want to make it to be a "developer" for your product.
Note that this is not secure in the slightest against malicious misuse. Among other limitations, it does nothing to prevent administrative installations that allow access to all the files.
Note as well that it's still a smart idea to follow the usual launch condition patterns to avoid preventing uninstallation of the package.

Installer with Online Registration for Windows Application

We have developed a software in vb.net using Visual Studio 2013. Now we want to build a custom installer with following steps/features:
User Start to install our software.
At 'Enter Serial Key' option, user enters the 16 digit Serial which have we provided.
When clicking 'OK' button, our software connect to our IP and save the Serial Key with some other user's information to our database.
A confirmation Key is returned back to our software.
Software writes a file and save it to the system folder.
It is almost like Adobe or Corel registration process.
We are open to other techniques also which must secure that our software must install on a single machine only.
Please be noted that we are a group of novice programmers(not so advance level), so; if the process is elaborated, it will be very helpful to us.
One-Shot Setups: "A setup is run once, an application can be started again - in order to resolve and debug problems interactively - with meaningful error messages show to the user."
Hence: avoid license validation in the setup.
Short version on licensing.
License Key: Preferring to deal with license keys in your application seems logical for several reasons: the one-shot nature of setups
yields poor reliability (no interactive debugging - poor ability
to resolve problems). The end result is lots of support calls for something very trivial.
Further, the risk of piracy and hacking is a major concern when
exposing a license validation DLL in the setup. And finally
communication over the Internet is difficult with today's setups (proxies, firewalls, etc...) - which is a modern way to validate license
keys (in the future setups might have full Internet access, but be careful assuming too much since corporate users may have lots of restrictions and poor deployment could hurt sales and acceptance of the software for corporate use).
Finally your application must usually support a trial version,
and then you need a license dialog in your application anyway.
Why complicate your setup too?
CAs: Custom actions are complex and vulnerable to failure in general - due to complex sequencing-, conditioning- and
impersonation issues and overall poor debugability. More information:
Why is it a good idea to limit the use of custom actions in my WiX / MSI setups?
Overall Complexity of Deployment: A short, attempted summary of the overall complexity of deployment:
Windows Installer and the creation of WiX
(section "The Complexity of Deployment").
I would remove all licensing features from the setup and add them to the application. Your setup can still write a license to disk or to the registry by passing it to msiexec.exe as a public property -
UPPERCASE properties (or you can "hide" things a little more by using a transform to apply the serial property - it has exactly the same effect as setting the property on the command line). You can also set the LICENSE property from a dialog in the setup when it is run interactively, but my favorite approach is to allow adding the license key unvalidated to the registry in silent deployment mode, and to instead enter the license key directly in the application, and not the setup, for interactive deployments (the above description is for silent deployment):
msiexec.exe /I "C:\Install.msi" /QN /L*V "C:\msilog.log" LICENSE="123-456-789"
This will allow the license to be easily added to each machine in a corporate deployment scenario. The license value is simply written to disk or registry without validation. The application will verify it (more secure than a validation dll in the setup).
There is no need to mess with any complex setup dialogs, but you will need a license dialog in your application as explained below.
As a setup developer you should offer to help implement the feature in the application instead of the setup so it doesn't seem like a case of "passing the buck". This is all for overall software reliability and foolproofness - and several reasons are listed below.
Almost all large corporations deploy MSI files silently, so the setup GUI will be ignored most of the time anyway. You are then simply adding risk and wasting resources if you deal with licenses in the setup.
One drawback: An application run as a non-admin user after installation can not write to HKLM to share a serial between all users on the computer (a setup running with elevated rights can). It must either write to HKCU or the setup must have prepared write access to a specific HKLM location in the registry for the application to write to. I prefer writing to HKCU for each user since the license is then less available for copying by others, and it is kept as user specific data (allows roaming, though that is a hated feature by most IT professionals). However, a HKLM license key written by the application or the setup during installation (as explained above with a public property set) allows all users to share a license when launching the application.
There are several more concrete reasons to keep license handling and validation out of your setup:
A significant number of support requests always result from people who have problems registering their license keys in the setup. A setup is run once, an application can be started again if there are problems. This is more important than you might think for inexperienced users. You also have better features available to handle exceptions and error conditions and whatever unexpected problems may occur in the application.
Serial validation in the setup exposes a validation dll / method that is easily cracked by pirates. You won't prevent piracy by eliminating it from your setup, but at least you make it more difficult. It is more secure in the application if you cloak things a bit (static linking, encryption, obfuscation, putting the validation process online, and / or whatever is done by security professionals that I am unfamiliar with).
Allow application trial version: If the setup needs to support a trial version of the application, you should allow the user to enter a license key if they end up buying the product - preferably without having to re-run the setup or uninstall / reinstall just to add the license key. In other words you will likely need to deal with licensing in your application anyway, why complicate your setup too? More risk, more QA, more potential support requests and potential for multiple required fixes in both setup and application. High total cost?
If your application runs with different editions, what if the user buys an upgraded license? They should just be able to enter it into the license dialog and unlock features if possible and not uninstall and reinstall with all the clunk that involves. For some upgrades this is hard to achieve though, and you often end up with separate setups for different editions.
If the network is using a proxy server for Internet access, you will have problems registering the license over the Internet during the setup (often asked for by marketing). You have more features to check and deal with this in the application - it can try again and wait for access (generally you hook up to IE for automagic proxy configuration if possible). For corporate deployment you need a silent install option too which doesn't validate the key but just writes it to the registry. Trying to access the Internet from a silent install of an MSI is in my opinion a rather extreme deployment anti-pattern. I find it dubious in the setup GUI as well. Do the registration in the application - much less controversial, and you can set up firewall rules to allow it to access the Internet (msiexec.exe is likely blocked - and for good reason). There could also be hardware firewalls and / or security software to deal with that makes Internet access difficult or even impossible without some clunky admin server configuration. This could kill your software from consideration is my experience: "Just get this off our network and application estate - there must be better options - far too clunky and error prone".
UPDATE: As deployment technology matures and becomes more "Internet based" this "truth" may change, and we could end up doing everything "online" with deployment designed specifically to run via online "repositories" for example. We will have to wait and see. For now my opinion is that any setup Internet access requirements are erroneous and undesirable.
Setups that mess with licensing may sometimes cause license data to be deleted during upgrades, patching and migration scenarios due to bugs in the setup. This is a lot more serious at times than you would think - the package might hit thousands of workstations in large companies and be cumbersome to fix.
There is a rather bad "anti-pattern" in the MSI technology itself whereby self-repair or manually triggered repair will reset values in the registry that has been changed by the application. This can wipe out license keys. We see this all the time, and it is the technology's fault. It is just not logical in this area.
There are some fixes - or rather workarounds - for this (use a permanent component, write license from a custom action instead of from a component, etc...), but I find them quite clunky and you have to have a lot of experience to know all the pitfalls - and even experienced users mess this up.
Licensing is a huge corporate headache - often what is desired by a company or corporation is that licensing is centrally managed on a server, and not based on text serial numbers at all (for example concurrent or floating licenses acquired on application launch via the network). Just mentioning this though it is sort of out of scope for the question. In these cases what you specify during installation is generally an IP address pointing to the license server, or just a regular host name to be resolved by WINS or DNS.
As you might have already guessed Windows Installer doesn't provide any out the box feature to handle licencing. But there are commercial licencing solutions which you can go for if affordable.
LogicNP
DESAWARE
Since this is very broad question difficult to explain low level implementation details. I can give you a direction.
First of all you will need a custom UI where user can type in the License/Activation key. There are ways to incorporate a custom UI into windows installer, I have already explained few approaches in SO, refer to the following threads.
Show custom Form during installation
How to add additional custom window to VS setup projects UI flow
By following above approaches you should be able to add a UI where user will type in a key. Once user added the key, he will press Activate button on the custom UI, Button click event handler will invoke the necessary logic to Insert/Validate the activation key entered by the user.
Maybe you could try Inno Setup which is free (even open source) installation system.
It is script based which allows you to tune your installer and perform in it everything!
Creating custom page with entering serial number is really easy, see this example: CustomPage for Serial Number in Inno Setup
and there is also integration for Visual Studio.

ClickOnce Set Up and other Questions vb.NET

I am attempting to write a small, lightweight client, using vb.net winforms, that can install without needing elevated privileges. Before I ask my questions, let me give you a bit of an idea of what it is supposed to do.
The app will start when Windows loads, set like this from the install, with a system/notification tray icon that can be clicked on to load up specific functionality. The application install from a website, or possibly a file share, haven't quite decided yet. This client will initially request user credentials for one of our web programs, and it will talk to an already built web service to determine what functionalities of our services they have licensed access to. After this, credentials will be encrypted and saved to the users pc locally. Every five minutes, the client will pass the credentials to the websites they have access to and check to see the status of jobs that are being processed, and download available reports if needed.
So, here is what I am trying to understand. If I configure this app as a ClickOnce application, once it installs from the url or shared drive, the user will not need to do anything else, correct? Or do they have to visit that url every time they boot up to reinstall/run the client?
Another thing, I wanted to get some opinions on the best ways to do some of the things this app will be doing. I have a good idea of where I am going with it, but I have no idea of which solution to go with yet.
For instance, what is the best way to store user passed credentials on their system for a "remember me"?
Also, is the best way to have the client install with automatically starting on windows startup to configure it to create a shortcut of itself in the windows startup folder?
I am trying to keep this as lightweight as possible, and using a very small GUI, so it shouldn't be too intrusive, so any ideas on how to ensure that, while keeping it from needing admin privs to install, will also help.
If I configure this app as a ClickOnce application, once it installs
from the url or shared drive, the user will not need to do anything
else, correct? Or do they have to visit that url every time they boot
up to reinstall/run the client?
Well if they need to reinstall it, they would have to download the setup.exe file again, but why would users need to do that? CilckOnce supports automatic updates. Visiting url is certainly not needed for running the program.
what is the best way to store user passed credentials on their system
for a "remember me"?
Probably storing them as application settings. Haven't used visual studio 2012, but in visual studio 2010 you have to right-click on project in solutions explorer, go to project propeties and then create variables in Settings tab. Then you can access those variables in code using My.Settings.variableName. Not sure about security though, if you need any.
As for privileges, I think you just need a privilege to install a program. Maybe you should publish a primitive clickOnce application and experiment with it and that will answer all your other questions about clickOnce.

InstallShield SQL .bak

The problem is that recently on my company we need to make an installer, since anyone haven't worked with InstallShield Before we have a lot of questions about it.
So here are the questions:
Am I able to restore a database using InstallShield? I mean, giving to it the path of the .bak file and then run a script and recover the database on mssql?
Does Install Shield have configuration files, so I'm able to change the files that are going to be used, depending on the client and the software version we are installing? Nowadays we use our own setup, but we have to select the files manually, so when a client whants to install a software we have to go with them and do it, because is really complex. Now we need to change that by making an installer that can be configured here in our company by and IT member, then send the files and the installer to the client and he only press "Next, Next..."
Sorry for my bad english
You might find that treating the front-end software and database as two separate items is easier for you and your clients. While many vendors offer the ability to run scripts against SQL Server (and other databases) during the course of the installation, you'll find that there are all kinds of issues you need to contend with (do you need to first install SQL Server, does the user have permission to access the SQL Server, what if they are installing the software on a new pc but don't need the database created again, etc). None of these are showstoppers, but they do create headaches that you need to deal with.
By treating the database and front-end separately, you can build an installation package that installs your front-end software and related components on the target machine. This in and of itself can be tricky to deal with depending upon how complex your software is and the amount of references and prerequisites you need to manage.
When it comes time to manage the database aspect of the program, you may find that the majority of your clients are capable of restoring a .bak file to their SQL Server, and the ones that aren't can always be assisted (probably remotely) by your staff.
If you discover that this isn't the case, you can always create a separate "Server" installation package that manages the database aspect of the installation.
With regards to your question about InstallShield, you'll probably find better information from their website and \ or sales staff, but here's a list of their current features.
There are other vendors in the space as well, so look at all of them including InstallAware and my personal favorite Advanced Installer. Pick the one in your budget that offers the features you need. They all should offer trials as well. Download and use them before you buy to find one that works best for you.
Yes installshield can call a script that will restore a db, you just need
to do so in silent mode. and yes there is a cfg file for install shield.
the documentation will show this in detail
here is some documentation for version 12
http://kb.flexerasoftware.com/doc/Helpnet/installs hield12helplib/IHelpContents.htm
they are currently on version 2012, however if you are doing this
crossplatform, don't use installshield, but use installanywhere. it is cross
platform.