C# 独特的';代码';对于每个应用程序部署

C# 独特的';代码';对于每个应用程序部署,c#,winforms,C#,Winforms,我们正在开发一个WinForm应用程序,希望将其部署到特定的计算机用户。我们想唯一地识别每个安装了某种“代码”的应用程序,我们可以在它们的系统上安装之前定义这些代码 现在,我们计划将唯一的代码(我们自己键入的)放入xml或文本文件中,并让应用程序在安装时读取它。应用程序将在安装后删除该文件并将其保存在某个位置 我们希望能够自己键入代码以便跟踪,但有没有更好的方法来代替将其放入某种平面文件中并让应用程序在安装后将其删除?就我个人而言,如果我要编写这样的方案,我会有一个应用程序在第一次运行时检查的服

我们正在开发一个WinForm应用程序,希望将其部署到特定的计算机用户。我们想唯一地识别每个安装了某种“代码”的应用程序,我们可以在它们的系统上安装之前定义这些代码

现在,我们计划将唯一的代码(我们自己键入的)放入xml或文本文件中,并让应用程序在安装时读取它。应用程序将在安装后删除该文件并将其保存在某个位置


我们希望能够自己键入代码以便跟踪,但有没有更好的方法来代替将其放入某种平面文件中并让应用程序在安装后将其删除?

就我个人而言,如果我要编写这样的方案,我会有一个应用程序在第一次运行时检查的服务器。服务器将为计算机生成一个ID(可能是GUID),然后客户端应用程序将保存该ID


如果使用这样的方案,则在安装时手动执行此操作可能不太可能,但如果这是手动执行此操作的唯一原因,服务器没有理由不能为您保留安装了应用程序的计算机目录。

您可以使用主网卡的MAC ID,系统驱动器的序列号,或其组合。 如果您完全控制用户的机器,那么CPUID也可能是合适的

这取决于您对用户的信任程度。如果ID主要用于识别,则上述操作将起作用。
如果是针对某种安全系统或包含其他信息(例如,应用程序中要打开的功能),则使用某种基于服务器或基于Active Directory的解决方案(假设为intranet环境)可能更好。

在MSI安装程序中添加自定义操作,动态生成GUID并将其存储在注册表中。然后,程序将在必要时访问该注册表项。

如果使用MSI安装应用程序,则可以编辑每个MSI以包含特殊代码,并将其作为安装的一部分写入注册表

您可以使用ORCA手动编辑MSI,甚至可以使用脚本访问MSI并更改其中的值,这样您就可以编写一个小应用程序来完成这部分工作

否则,您可以将其加密到配置文件中,并在启动时输入

如果没有更多的信息,在这里提供帮助是相当棘手的

我使用此脚本(WiRunSQL.vbs)访问MSI

' Windows Installer utility to execute SQL statements against an installer database
' For use with Windows Scripting Host, CScript.exe or WScript.exe
' Copyright (c) 1999-2001, Microsoft Corporation
' Demonstrates the script-driven database queries and updates
'
Option Explicit

Const msiOpenDatabaseModeReadOnly = 0
Const msiOpenDatabaseModeTransact = 1

Dim argNum, argCount:argCount = Wscript.Arguments.Count
If (argCount < 2) Then
    Wscript.Echo "Windows Installer utility to execute SQL queries against an installer database." &_
        vbLf & " The 1st argument specifies the path to the MSI database, relative or full path" &_
        vbLf & " Subsequent arguments specify SQL queries to execute - must be in double quotes" &_
        vbLf & " SELECT queries will display the rows of the result list specified in the query" &_
        vbLf & " Binary data columns selected by a query will not be displayed" &_
        vblf &_
        vblf & "Copyright (C) Microsoft Corporation, 1999-2001.  All rights reserved."
    Wscript.Quit 1
End If

' Scan arguments for valid SQL keyword and to determine if any update operations
Dim openMode : openMode = msiOpenDatabaseModeReadOnly
For argNum = 1 To argCount - 1
    Dim keyword : keyword = Wscript.Arguments(argNum)
    Dim keywordLen : keywordLen = InStr(1, keyword, " ", vbTextCompare)
    If (keywordLen) Then keyword = UCase(Left(keyword, keywordLen - 1))
    If InStr(1, "UPDATE INSERT DELETE CREATE ALTER DROP", keyword, vbTextCompare) Then
        openMode = msiOpenDatabaseModeTransact
    ElseIf keyword <> "SELECT" Then
        Fail "Invalid SQL statement type: " & keyword
    End If
Next

' Connect to Windows installer object
On Error Resume Next
Dim installer : Set installer = Nothing
Set installer = Wscript.CreateObject("WindowsInstaller.Installer") : CheckError

' Open database
Dim databasePath:databasePath = Wscript.Arguments(0)
Dim database : Set database = installer.OpenDatabase(databasePath, openMode) : CheckError

' Process SQL statements
Dim query, view, record, message, rowData, columnCount, delim, column
For argNum = 1 To argCount - 1
    query = Wscript.Arguments(argNum)
    Set view = database.OpenView(query) : CheckError
    view.Execute : CheckError
    If Ucase(Left(query, 6)) = "SELECT" Then
        Do
            Set record = view.Fetch
            If record Is Nothing Then Exit Do
            columnCount = record.FieldCount
            rowData = Empty
            delim = "  "
            For column = 1 To columnCount
                If column = columnCount Then delim = vbLf
                rowData = rowData & record.StringData(column) & delim
            Next
            message = message & rowData
        Loop
    End If
Next
If openMode = msiOpenDatabaseModeTransact Then database.Commit
If Not IsEmpty(message) Then Wscript.Echo message
Wscript.Quit 0

Sub CheckError
    Dim message, errRec
    If Err = 0 Then Exit Sub
    message = Err.Source & " " & Hex(Err) & ": " & Err.Description
    If Not installer Is Nothing Then
        Set errRec = installer.LastErrorRecord
        If Not errRec Is Nothing Then message = message & vbLf & errRec.FormatText
    End If
    Fail message
End Sub

Sub Fail(message)
    Wscript.Echo message
    Wscript.Quit 2
End Sub

我建议您在安装中使用NSIS(Nullsoft安装系统),并在安装脚本中设置一个变量,该变量在安装时保存在注册表的某个位置

NSIS脚本中的变量可以在编译时使用特殊的命令行开关定义。这使得创建一个轻量级c#或vb.net应用程序成为可能,该应用程序接受您选择的唯一ID,并使用嵌入的ID构建安装


这样,只需单击一次即可为客户创建新安装。您还可以将.NET build应用程序连接到SQL Express数据库(或等效数据库),并自动保存客户ID以备将来使用。

不幸的是,应用程序无法联系任何服务器(我无权更改此决定),唯一ID必须由分发应用程序的人员定义,所以它不能是生成的ID。
wscript D:\Scripts\wirunsql.vbs D:\MSI\msiName.msi "Update ISProductConfigurationProperty Set Value = 'Name of my Product' WHERE (Property = 'ProductName')"