请注意,这很可能不是您想要做的。无论如何,我会解释几种方法来做到这一点..
将 MST 文件与 MSI 一起使用:
您可以使用 user-id 属性创建 MST 文件,并在每个用户下载 msi 并让他们使用转换安装 msi 时为他们生成这些文件:
msiexec -i c:\temp\The.msi transforms=c:\temp\YourPerso.mst
在此处查看更多信息:使用命令行安装转换。
MST 文件在大型组织中使用很多,其中所有 MSI 都具有嵌入序列号等的 MST 文件。
要制作 MST 文件,您需要下载并安装Microsofts Orca Tool,它是 Microsoft Windows SDK 的一部分。
打开 Orca 并从 MSI 文件中创建一个 MST 文件。基本上你打开 MSI 文件导航到表“属性”,在那里你会看到一个参数列表。
请注意,在 MSI 文件中,您会看到需要默认值的参数。
在添加/更改参数之前,通过单击菜单中的“变换”->“新变换”来创建一个新的变换。
之后,您可以根据需要更改参数或添加新参数。完成参数更改后,使用“转换”菜单中的“生成转换”功能生成 MST 文件。
如果您随后使用 HexEditor 打开 mst 文件,您可以看到刚刚添加的属性:
您可以通过简单地编辑值来编辑每次下载的文件,例如:
您当然可以(并且可能应该)使用 WindowsInstaller.Installer 的 API 以正确的方式执行此操作。这是一个例子:
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
提示:要使用托管代码执行此操作,您最好使用http://wix.codeplex.com/Microsoft.Deployment.WindowsInstaller.dll
中提供的那些
为每个用户构建一个 MSI:
恕我直言,使用 Nullsoft (WiX、InstallShield、INNO 等)并为每个用户构建一个 MSI会容易得多。为此,您将在例如nsi 脚本中嵌入一个唯一的用户 ID,并为每次下载启动一个 MSI 构建。在安装过程中,唯一的用户 ID 将存储在文件、注册表项等中。我建议您尝试使用此 NSIS 向导编辑器快速启动基本的 NSI 安装脚本并通过命令行构建 MSI:makensis。
注意:虽然“在 MSI 文件名中包含用户 ID”比为每个用户构建 MSI 更容易,但用户可以轻松更改文件名。用户使用 Orca 审核 MSI 以查找内置用户 ID 的可能性要小得多。
最简单和最合乎逻辑的方法:
将事件发送到我的服务器很容易,但是如何从 php 服务器获取用户 ID,以便我可以知道哪个用户在 .NET 应用程序上做了什么?
做@Jhuliano Moreno 然后@WouterHuysentruit 推荐的:
当您的应用程序第一次启动时,只需让用户使用他们的网站凭据登录到程序,并将他们的用户 ID 记录在配置文件、注册表项或数据库记录中。基本上是创建一个cookie,这样你下次打开程序时就会知道它们——或者让它们每次都登录。