Как скачать MSI установщик с аргументом для идентификатора пользователя

У меня есть приложение .NET C #, обернутое в установщик MSI — «myprogram.exe». У меня есть веб-сайт PHP и определенная страница, где пользователь может скачать программу по ссылке.

Я хотел бы иметь возможность отслеживать определенные события в приложении .NET. Например — «Программа открыта».

На мой сервер легко отправлять события, однако как мне получить идентификатор пользователя с сервера php, чтобы я мог знать, какой пользователь что делал в приложении .NET?

Я думал о передаче аргумента (идентификатора пользователя) установщику MSI, но не смог найти путь к этому.

Как связать между идентификатором пользователя PHP и приложением .NET?

Пояснение —

Многие люди предлагали использовать систему входа в систему для связи между сервером и приложением.

Это действительно самое простое решение, однако на моем веб-сайте я не вынуждаю пользователя войти в систему, чтобы загрузить приложение (и не запрашиваю данные для входа в приложение .NET — это необязательно). Если нам не нужно запрашивать данные для входа в систему, я думаю, что нет, пользовательский опыт будет намного лучше (намного меньше шагов для использования приложения) — у пользователя будет больше шансов загрузить и использовать приложение Desktop.

Учтите, что текущий поток -> Веб-страница — Нажмите кнопку Загрузить — Выполнить — Используйте приложение
(занимает 10 секунд)

При входе в систему -> Веб-страница — Зарегистрироваться (подтвердить адрес электронной почты?) — Перенаправить — Загрузить Нажмите — Запустите — Вход в приложение — Используйте приложение
(занимает 60-120 секунд для пользователя)

11

Решение

Вход из программы

Лучший способ — позволить пользователю войти в систему с теми же учетными данными в вашей программе. Таким образом, ваша программа может использовать безопасную аутентификацию OAuth2 для взаимодействия с вашим внутренним API. Это также делает прозрачным для пользователя, что программа взаимодействует с Интернетом.

Включить идентификатор пользователя в имя файла

Другой способ — добавить идентификатор пользователя к имени файла программы установки во время загрузки и извлечь его при запуске программы установки. Вам нужно будет проверить, позволяет ли это ваш установщик. Кроме того, делайте это только в том случае, если вы используете UUID или что-то подобное, поскольку вы не хотите, чтобы пользователь угадывал другие идентификаторы.

App.config

Третий вариант — добавить идентификатор пользователя к App.config файл. Есть два способа сделать это:

  1. Создайте свой MSI с App.config без сжатия добавьте настройку идентификатора пользователя с фиксированным UUID. Ваш PHP-скрипт может найти UUID и заменить его в двоичном файле MSI перед отправкой пользователю. Смотрите фрагмент кода под MST преобразование
  2. Сборка .msi по требованию с обычаем App.config, Это будет работать только в том случае, если ваш веб-сервер работает в Windows или у вас есть удаленный сервер сборки Windows, который может выполнить эту работу.

MST преобразование

Вы также можете использовать MST-преобразование и использовать тот же трюк двоичной замены, который я объяснил для пункта 1 ниже. App.config.

Для обоих вариантов вы можете использовать PHP-скрипт, который использует бинарно-безопасные функции для замены значений в установщике и отправляет файл пользователю для загрузки:

<?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;
?>

Серийный номер

Последний способ, о котором я могу подумать, — это позволить программе запрашивать серийный номер при первом запуске и позволить вашему веб-сайту генерировать уникальный серийный номер для каждого пользователя.

10

Другие решения

Хм, пожалуйста, обратите внимание, это очень вероятно, что это не что ты хочешь делать. Тем не менее, я объясню пару способов сделать это ..

Использование файлов MST с MSI:

Вы можете создавать MST-файлы со свойством user-id и генерировать их для каждого пользователя, когда они загружают MSI, и заставляют их устанавливать MSI с преобразованием:

msiexec -i c:\temp\The.msi transforms=c:\temp\YourPerso.mst

Смотрите больше информации здесь: Установите преобразование с помощью командной строки.

Вы видите, что файлы MST часто используются в крупных организациях, где все MSI имеют файлы MST со встроенными серийными номерами и т. Д.

Для создания MST-файла вам необходимо скачать и установить Microsoft Orca Tool, часть Microsoft Windows SDK.

Откройте Orca и создайте файл MST из файла MSI. В основном вы открываете MSI-файл, переходите к таблице «Свойство», там вы видите список параметров.
Обратите внимание, что в файле MSI вы увидите параметры, которые требуют значения по умолчанию.

Прежде чем добавлять / изменять параметры, создайте новое Преобразование, щелкнув в меню «Преобразование» -> «Новое преобразование».

введите описание изображения здесь

После этого вы можете изменить параметры или добавить новые, как вы хотите. Когда вы закончите изменения параметров, используйте функцию «Генерация преобразования» в меню «Преобразование» для создания файла MST.

введите описание изображения здесь

Если вы затем откроете файл MST с помощью HexEditor, вы увидите только что добавленное свойство:

введите описание изображения здесь

Вы можете редактировать файл для каждой загрузки, просто редактируя значение, например:

введите описание изображения здесь

Конечно, вы можете (и, вероятно, должны) сделать это надлежащим образом, используя API-интерфейс WindowsInstaller.Installer. Вот пример:

private function createTransform(mstfile, msi, config)
writeLog InfoLog, "Generating transform " & mstfile

dim vars: set vars = configvars(config)

dim createPropertyTable: createPropertyTable = "create table `Property` " & _
"(`Property` char(72) not null, `Value` longchar localizable " & _
"primary key `Property`)"dim addProperty: addProperty = "insert into `Property` (`Property`, `Value`) values (?, ?)"dim updateProperty: updateProperty = "update `Property` set `Value` = ? where `Property` = ?"
dim wi: set wi = createObject("WindowsInstaller.Installer")
dim base: set base = wi.openDatabase("base.msi", msiOpenDatabaseModeCreate)
base.openview(createPropertyTable).execute
dim tgt: set tgt = wi.openDatabase("tgt.msi", msiOpenDatabaseModeCreate)
tgt.openview(createPropertyTable).execute
dim props: set props = createObject("scripting.dictionary")
dim view: set view = msi.openView("select `Property`, `Value` from `Property`")
view.execute
dim record: set record = view.fetch
while not record is nothing
props(record.stringdata(1)) = true
base.openview(addProperty).execute record
tgt.openview(addProperty).execute record
set record = view.fetch
wend

set record = wi.createRecord(2)
dim prop
for each prop in properties_
on error resume next
dim val: val = expand(vars, prop(DepPropertyValueIdx))
if err then
writeLog ErrorLog, err.description
exit function
end if
on error goto 0
writeLog InfoLog, "Property " & prop(DepPropertyNameIdx) & "=" & val
if props.exists(prop(DepPropertyNameIdx)) then
record.stringdata(2) = prop(DepPropertyNameIdx)
record.stringdata(1) = val
tgt.openview(updateProperty).execute record
else
record.stringdata(1) = prop(DepPropertyNameIdx)
record.stringdata(2) = val
tgt.openview(addProperty).execute record
end if
next
if not tgt.generateTransform(base, mstfile) then
writeLog ErrorLog, "Failed to create transform"exit function
end if
tgt.createTransformSummaryInfo msi, mstfile, 0, 0
createTransform = true
end function

Совет: Чтобы сделать это с помощью управляемого кода, лучше всего использовать Microsoft.Deployment.WindowsInstaller.dll это доступно как часть http://wix.codeplex.com/


Создайте MSI для каждого пользователя:

ИМХО, было бы намного проще сделать это с Nullsoft (WiX, InstallShield, INNO и т. Д.) и построить MSI для каждого пользователя. Для этого вы должны встраивать уникальный идентификатор пользователя, например, в скрипт nsi и начать сборку MSI для каждой загрузки. Во время установки уникальный идентификатор пользователя будет сохранен в файле, ключе реестра и т. Д. Я предлагаю вам попробовать, используя это NSIS Wizard Editor быстро создать базовый скрипт установки NSI и построить MSI через командную строку: makensis.

Замечания: Хотя «Включение идентификатора пользователя в имя файла MSI» проще, чем создание MSI для каждого пользователя, пользователи могут легко изменить имя файла. Гораздо менее вероятно, что пользователь будет проверять MSI с помощью Orca, чтобы найти встроенный идентификатор пользователя.


Самый простой и логичный способ:

Легко отправлять события на мой сервер, однако, как мне получить
ИД пользователя с сервера php, так что я могу узнать, какой пользователь что сделал в приложении .NET?

Сделайте то, что @Jhuliano Moreno, а затем @WouterHuysentruit рекомендовал:

Когда ваше приложение запускается в первый раз, просто сделайте вход пользователя в программу, используя его учетные данные на сайте, и запишите его идентификатор пользователя в файле конфигурации, ключе реестра или записи базы данных. По сути, создание куки, чтобы вы знали их в следующий раз, когда откроет программу, или заставили их войти в систему каждый раз.

7

Когда файл вызывается, отправьте параметр UserID, если вы используете MVC-фреймворк в вашем PHP, вам понадобится новый контроллер, который получает MSI-файл и переименовывает его в name-userID.exe, а затем возвращает файл для загрузки. через браузер.

4
По вопросам рекламы [email protected]