Overview
This is a quick demonstration of modifying application behavior at installation time when the app uses Windows Installer. It is not a deep dive but will include some links along the way for further study.
Well-behaved programs don’t force undesirable behavior on users. That’s why I’m normally opposed to programs setting themselves to run automatically without the user’s permission. I didn’t mention this in my earlier post, Providing a Great Software Deployment Experience, but let me add to my list of Guidelines for Great User Experience in that post that installers should let the user decide whether the program should automatically run at computer startup or user sign-in. This should be implemented as a Windows Installer property overridable on the command line so that IT staff can make that choice during unattended installation.
Here, I am focusing on an app whose installer does not configure it to run automatically. That’s good at first glance. An important characteristic of this app, though, is that if you have installed it, you probably want it running all the time. The app is the PaperCut NG Client, and it is the user-facing component of the PaperCut NG printing management system. Organizations implement this to providing accounting around printer costs, among other functions. The client notifies users of printing quota and prompts for approval of printouts, so that users are aware of how much they or their departments will be charged for each printout. If a user tries to print to a printer controlled by PaperCut NG, but they don’t have this app running, they will not be prompted for approval, and so the print job will never be sent to the printer. (Behavior may vary depending on configuration; I’m describing how it works with my organization’ configuration.) This will make users sad and very liable to call for support.
Therefore, IT staff want this app running all the time on any computer where it is installed. The problem is that this app’s installer does not provide a way to make it automatically run. At my organization, we work around this by using Group Policy to run the program as user sign-in:
- Group Policy setting: User Configuration > Policies > Administrative Templates > System > Logon > Run these programs at user logon
- Item: C:\Program Files\PaperCut NG Client\pc-client.exe –silent
This has the unfortunate effect of separating the “automatically run” behavior mandate by IT from the collection of computers where the software is installed. IT must ensure that, over time, both the policy and the app are always applied to the same set of computers. It would be better to have the behavior built into the installer, and that is the subject of the rest of this post.
Approach
I am not going to try to teach the Windows Installer system and file format here; whole books have been written about it, and it is documented extensively on Microsoft Learn. The minimum you need to understand here is that Windows Installer installs a set of features, and features are composed of components. Typically, every individual file or registry value needed by the app is defined as a separate component in the Windows Installer file, which always has an “msi” (Microsoft installer) extension.
The approach here will be to transform the vendor-supplied Windows Installer file so that it adds the command line above to one of the standard “Run” keys in the registry at installation time. I will do this by applying a transform file (*.mst) to it the installer file supplied by the vendor. This is a way to alter the behavior of the installer file without editing it directly. That makes the altered settings shareable and leaves the integrity of the vendor’s digitally signed installer file intact.
If you are building your own MSI from scratch (such as if you work at PaperCut), you should consider keeping the default of not running things automatically without the user’s consent, and you should provide a property settable at the command line or through the installer’s user interface so the user can override your default setting. Since I am not the vendor in this case, I am just going to make the change; if I don’t want the change, I won’t apply the transform file. A property would not provide additional value for me, since I have to make the effort of building a transform file already.
Gather Software and Tools
- Copy the client software from your organization’s PaperCut NG server. For example, if your PaperCut NG server is “papercutsvr”, and you want to work in your Downloads folder:
Robocopy "\\papercutsvr\PCClient\win" "%USERPROFILE%\Downloads\PCClient\win" /E /J /DCOPY:DAT /XJ
- Install Orca, the Windows Installer database editor, using Windows Package Manager, from an elevated Command Prompt:
winget install Orca
Create the Windows Installer Transform File
Follow these steps to build a windows Installer transform file that configures PaperCut NG Client to run automatically for all users.
NOTE: I plan to build on what I am doing here in a future post to address another issue with the PaperCut NG Client installer. Keep reading below to understand what I am doing and to create the transform file yourself, but be aware that I plan to provide the finished transform file with an additional bug fix next time. If you can wait, you can avoid the work.
- Run Orca.exe
- Open “%USERPROFILE%\Downloads\PCClient\win\pc-client-admin-deploy.msi”, and select the option “Open as read-only”. This prevents you from accidentally modifying the installer file provided by the vendor.
- Open Windows PowerShell (or the newer PowerShell—either one works for this), and use the New-Guid cmdlet to generate a new GUIDs for use as the identifier for our new component and as the identifier for our new registry value.
The following will create the registry identifier in the same format as others in the MSI file:
“reg$((New-Guid).ToString().ToUpper())” -replace ‘-‘
The following will create the component GUID in the same format as other GUIDs in the PaperCut NG Client MSI file:
“{$((New-Guid).ToString().ToUpper())}” - In Orca, select Transform menu > New Transform.
- Select the Registry table.
- Tables menu > Add Row…, and create a new row with these values:
- Registry: [Paste the registry identifier generated above.]
- Root: 2
- Key: SOFTWARE\Microsoft\Windows\CurrentVersion\Run
- Name: PaperCutNG
- Value:
"[APPLICATIONROOTDIRECTORY]pc-client.exe" --silent
- Component_: RunAtSignIn
- Select the Component table.
- Tables menu > Add Row…, and create a new row with these values:
- Component: RunAtSignIn
- ComponentId: [Paste the component GUID generated above.]
- Directory_: APPLICATIONROOTDIRECTORY
- Attributes: 260
- Condition: [Leave blank.]
- KeyPath: [Paste the registry identifier generated above.]
- Select the FeatureComponents table.
- Tables menu > Add Row…, and create a new row with these values:
- Feature_: PCClient
- Component_: RunAtSignIn
- Transform menu > Generate Transform, and save the transform file in the same folder as the MSI file as “PCClientAutorun.mst”.
Deployment
Now, when deploying PaperCut NG Client, you must apply the transform file to get the autorun behavior. The command line with verbose logging will be:msiexec /package pc-client-admin-deploy.msi /quiet /norestart TRANSFORMS=PCClientAutorun.mst /l*v "%TEMP%\PaperCutNGClientLog.txt"
Once this is installed across your organization, the PaperCut NG Client will run automatically at user sign-in wherever it is installed, and you can remove any existing measures to make that happen, such as Group Policy settings or logon scripts.
Next time, I’ll combine the modifications above with a bug-fix to allow the PaperCut NG Client to install in the system context when delivered via Microsoft Intune, and I will make my final transform file available for you to use so you don’t have to do most of the work described above.
Posts in this series:
- Transforming PaperCut NG Client installer to run the program automatically
- Modifying PaperCut NG Client to install in the system context via Microsoft Intune
<update date=”2023-12-08″>Added link to the second post in the series and struck the offer to supply an MST file.</update>