Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to Download MSI installer with argument for user-id

I have a .NET C# application, wrapped inside MSI installer - "myprogram.exe". I have a PHP website and a specific page where user can download the program via a link.

I would like to be able to track certain events on the .NET app. For example - "Program Opened".

It's easy to send events to my server, however how do I grab the user-id from the php server, so I can know which user did what on the .NET app?

I thought about passing an argument (the user-id) to the MSI installer but could not find a way to that.

How do I link between the PHP user-id and the .NET app?

Clarification -

Many people offered to use a login system to bind between the server and app.

This is indeed the easiest solution, however on my website I do not force the user to login to download the app (nor I request login details in the .NET app - its optional). If we dont have to ask for login details, I think we shouldn't, the experience for the user will be much better (far less steps to use the app) - greater chance for the user to download and use the Desktop app.

Consider that current flow is -> Webpage - Download click - Run - Use the app (takes 10 seconds)

With login -> Webpage - Register (confirm email?) - Redirect - Download Click - run - app Login - Use the app (takes 60-120 seconds for the user)

like image 402
yaron Avatar asked Aug 23 '15 07:08

yaron


1 Answers

Login from the program

The best way is to let the user sign-in with the same credentials in your program. This way, your program can use secure OAuth2 authentication to communicate with your back-end API. This also makes it transparent to the user that the program is communicating with the internet.

Include user-id in filename

An other way is to add the user-id to the filename of the installer during download and extract it when the installer runs. You will have to check if your installer tool allows this. Also, only do this if you user-id's are UUID's or something similar as you don't want the user to guess other id's.

App.config

A third option is to add the user-id to the App.config file. There are two ways to do this:

  1. Create your .msi with App.config uncompressed, add a user-id setting with fixed UUID. Your PHP script can lookup the UUID and replace it in the .msi binary before sending it to the user. See code snippet under MST transform
  2. Build the .msi on demand with the custom App.config. This will only work if your webserver is running on Windows or you have a remote Windows build server that can do this job.

MST transform

You could also use an MST transform and use the same binary replace trick as I've explained for point 1 under App.config.

For both options, you could use a PHP script that uses binary-safe functions to replace the values in the installer and sends the file to the user as a download:

<?php
$userId = // TODO get userId from the session or database
$data = file_get_contents("./my-installer.msi");
// I would use UUID's for template and userId, this way the size of the installer remains the same after replace
$data = str_replace("{fe06bd4e-4bed-4954-be14-42fb79a79817}", $userId, $data);
// Return the file as download
header("Cache-Control: public"); // needed for i.e.
header('Content-Disposition: attachment; filename=my-installer.msi');
header('Content-Type: application/x-msi');
header("Content-Transfer-Encoding: Binary");
echo $data;
?>

Serial number

Last method I can think of is to let the program ask for a serial number on first startup and let your website generate a unique serial number for each user.

like image 139
huysentruitw Avatar answered Oct 07 '22 14:10

huysentruitw