Ярлыки, созданные установщиком в проекте установки Visual Studio 2008 SP1 - PullRequest
2 голосов
/ 28 декабря 2010

У меня есть проект установки Visual Studio 2008, который создает ярлыки на рабочем столе и в меню запуска во время установки.Созданные ярлыки вызывают приложение, если пользователь нажимает на них.Тем не менее, ярлыки не могут быть использованы в качестве цели отбрасывания.Кроме того, ярлык также нельзя использовать с помощью команды SendTo из проводника.Если вы проверяете свойства ярлыка из Проводника, у цели есть только имя приложения и он недоступен (например, MyApplication).В ярлыке, созданном вручную, у цели есть полный путь к приложению (например, C: \ Program Files \ MyCompany \ MyApplication.exe).Остальные настройки такие же.После более детального изучения ярлыка, созданного установщиком, выяснилось, что внутренне ярлык имеет цель, указывающую на некоторый исполняемый файл, созданный установщиком: C: \ WINDOWS \ Installer {6806F37B-0B4F-4002-AB09-380926EC572E} _F9EFFA12305AA4213985DC.exe,Я полагаю, что этот промежуточный исполняемый файл предназначен для проверки целостности установки или чего-то подобного.Расположение значка также перенаправлено на этот исполняемый файл.Хотя намерение могло быть хорошим, как я упоминал выше, похоже, что это не дает ярлыку распознаваться как цели отбрасывания и отправки.Есть ли способ сказать установщику создать ярлыки для фактической цели, а не промежуточного exe?

Возможность SendTo в проекте установки, по-видимому, имеет дополнительную проблему, поскольку она устанавливает ярлыки SendTo только для текущего вошедшего в систему пользователя, даже если установлено «Установить для всех пользователей».Похоже, что разработчик просто выполнил незавершенную работу, потому что немного сложнее установить SendTo для всех пользователей, поскольку профиль «All Users» не поддерживает SendTo.Вместо этого вы должны установить ярлык в профиль «Пользователь по умолчанию», который позаботится обо всех будущих профилях пользователей, затем перечислить все существующие профили пользователей и добавить SendTo в каждый существующий профиль.Я предполагаю, что кодировщик ярлыков проекта установки взял ярлык здесь ...

В настоящее время я просто позволяю установщику установить все, что он хочет, а затем в действии после установки измените установленные ярлыки и вручную установите ярлыки sendto для всех пользователей (как описановыше).Это работает, но мне было интересно, есть ли более чистое решение обеих этих проблем.

1 Ответ

0 голосов
/ 08 августа 2011

Я использую следующий скрипт, чтобы сказать 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
...