由 Visual Studio 2008 SP1 安装项目生成的安装程序创建的快捷方式

发布于 2024-10-09 19:30:52 字数 897 浏览 3 评论 0原文

我有一个 Visual Studio 2008 安装项目,它在安装过程中创建桌面和启动菜单快捷方式。如果用户单击创建的快捷方式,则会调用应用程序。但是,快捷方式不能用作放置目标。此外,也无法通过资源管理器中的 SendTo 命令使用该快捷方式。如果您从资源管理器检查快捷方式的属性,目标只有应用程序名称并且呈灰色显示(例如,MyApplication)。在手动创建的快捷方式中,目标具有应用程序的完整路径(即 C:\Program Files\MyCompany\MyApplication.exe)。其他设置相同。对安装程序创建的快捷方式进行进一步调查后发现,该快捷方式内部的目标指向安装程序创建的某些可执行文件:C:\WINDOWS\Installer{6806F37B-0B4F-4002-AB09-380926EC572E}_F9EFFA12305AA4213985DC.exe 。我认为这个中间可执行文件旨在提供一些安装完整性检查或类似的东西。图标位置也被重定向到该可执行文件。虽然意图可能是好的,正如我上面提到的,但这似乎阻止了快捷方式被识别为 drop 和 sendto 目标。有没有办法告诉安装程序创建实际目标而不是中间 exe 的快捷方式?

安装项目的 SendTo 功能似乎还有一个额外的问题,因为它只为当前登录的用户安装 SendTo 快捷方式,即使设置了“为所有用户安装”。看来开发人员只是做了不完整的工作,因为为所有用户安装 SendTo 有点棘手,因为“所有用户”配置文件不支持 SendTo。相反,您必须在“默认用户”配置文件中安装一个快捷方式,该配置文件将处理所有即将出现的用户配置文件,然后枚举所有现有用户配置文件并将 SendTo 添加到每个现有配置文件。我猜安装项目快捷方式的编码者在这里走了一条捷径......

我目前只是让安装程序安装它想要的任何内容,然后在安装后操作中修改已安装的快捷方式并为所有用户手动安装 sendto 快捷方式(如上所述)。这可行,但我想知道是否有更干净的解决方案来解决这两个问题。

I have a Visual Studio 2008 Setup Project that creates desktop and startup menu shortcuts during the install. The shortcuts created invoke the application if user clicks on them. However, the shortcuts cannot be used as a drop target. Also, the shortcut also cannot be used via SendTo command from Explorer. If you check properties of the shortcut from Explorer, the Target has just the application name and is grayed out (for example, MyApplication). In the manually created shortcut, the Target has full path to the application (i.e. C:\Program Files\MyCompany\MyApplication.exe). Other settings are the same. Upon farther investigation of the shortcut created by the installer, it turned out that internally the shortcut has the Target pointing to some executable created by the installer: C:\WINDOWS\Installer{6806F37B-0B4F-4002-AB09-380926EC572E}_F9EFFA12305AA4213985DC.exe. I suppose that this intermediate executable is intended to provide some installation integrity check or something like this. The Icon location is also re-directed to this executable. While the intend may have been good, as I mentioned above, this seems to prevent the shortcut from being recognized as drop and sendto targets. Is there a way to tell the installer to create shortcuts to the actual target and not the intermediate exe?

The SendTo capability of the setup project seems to have an additional problem as it only installs the SendTo shortcuts for the currently logged on user even though “install for all users” is set. It seems that the developer just did incomplete job because it is a bit tricky to install SendTo for all users because “All Users” profile does not support SendTo. Instead, you must install a shortcut into “Default User” profile which will take care of all forthcoming user profiles, then enumerate all existing user profiles and add SendTo to each existing profile. I guess the coder of the Setup Project Shortcuts took a shortcut here…

I currently just let the installer install whatever it wants and then in the post install action modify the installed shortcuts and manually install the sendto shortcuts for all users (as outlined above). This works but I was wondering if there is a cleaner solution to both of those issues.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

季末如歌 2024-10-16 19:30:52

我使用以下脚本告诉 VS 创建“常规”快捷方式。将安装项目的 PostBuildEvent 属性设置为:

cscript //nologo "{path}\WiRunSql.vbs" "$(BuiltOuputPath)" "INSERT INTO Property(Property, Value) VALUES ('DISABLEADVTSHORTCUTS', '1')"

并在上面使用的路径中创建一个包含以下内容的 WiRunSql.vbs 文件:

' Windows Installer utility to execute SQL statements against an installer database
' For use with Windows Scripting Host, CScript.exe or WScript.exe
' Copyright (c) Microsoft Corporation. All rights reserved.
' 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.  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

I use the following script to tell VS to create "regular" shortcuts. Set the PostBuildEvent property of your Setup project to:

cscript //nologo "{path}\WiRunSql.vbs" "$(BuiltOuputPath)" "INSERT INTO Property(Property, Value) VALUES ('DISABLEADVTSHORTCUTS', '1')"

And create a WiRunSql.vbs file at the path used above with the following content:

' Windows Installer utility to execute SQL statements against an installer database
' For use with Windows Scripting Host, CScript.exe or WScript.exe
' Copyright (c) Microsoft Corporation. All rights reserved.
' 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.  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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文