Как предотвратить запуск установщика при удалении файлов данных приложения?

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

XP — C:\Documents and Settings\All Users\Application Data.

Виста и 7 — C:\Program Data

Я обнаружил неожиданное поведение: если удалить какой-либо файл из общей папки данных приложения и запустить приложение из меню «Пуск», запустится процедура установки и попытается восстановить отсутствующие файлы. Если файл MSI больше не существует в исходном местоположении или был изменен, приложение не запустится. Я понимаю, что это «функция», но мне она не нужна. Может ли кто-нибудь сказать мне, что происходит и как я могу этого избежать?

Еще немного деталей:

  • Я создал пакет установки с помощью проекта развертывания Visual Studio.

  • Это поведение не произойдет, если я запущу EXE напрямую. Поэтому я ожидаю, что это поведение как-то связано с ярлыком меню «Пуск». Я заметил, что ярлык не является обычным ярлыком — у него нет «целевого местоположения».

Все советы приветствуются.

-TC




Ответы (1)


Я узнал, что это поведение связано с так называемой «установкой по требованию» (также известной как «самоисцеление»). Необычные ярлыки, созданные пакетом установки, называются «Объявленные ярлыки». Теперь, когда у меня есть название проблемы, легко найти информацию о том, как ее исправить. В частности:

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

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

Проекты установки Visual Studio автоматически создают пакеты MSI, которые по умолчанию генерируют объявленные ярлыки. Это значение по умолчанию легко переопределить при установке пакета MSI, указав DISABLEADVTSHORTCUTS=1 в качестве аргумента командной строки для Setup.exe. Кроме того, с помощью такой утилиты, как Orca, вы можете вручную изменить значение по умолчанию, вставив DISABLEADVTSHORTCUTS=1 в качестве свойства MSI. Однако если вы хотите, чтобы Visual Studio автоматически создавала пакеты MSI, которые не создают объявленных ярлыков, это сложнее. Я сделал это следующим образом:

  1. Сначала я создал файл VBS, используя код DisableAdvt, предоставленный Гэри Чангом по одной из ссылок выше (я повторил этот код ниже). Просто создайте текстовый файл, вставьте код. и сохраните его как DisableAdvt.vbs.

  2. Затем создайте событие после сборки для вашего проекта установки. Точный синтаксис будет зависеть от расположения ваших файлов. Поскольку мой DisableAdvt.vbs находится в подпапке «Инструменты» папки решения, мое событие после сборки выглядит следующим образом:

    • "$(ProjectDir)..\Tools\DisableAdvt\DisableAdvt.vbs" "$(BuiltOuputPath)"

Это все, что я должен был сделать. Работает как часы.

-TC

Некоторые примечания:

В Visual Studio 2005 доступ к событиям сборки для проектов установки осуществляется иначе, чем для других типов проектов. Щелкните имя проекта в обозревателе решений, затем найдите PostBuildEvent на панели свойств.

Orca — это утилита, которую можно использовать для ручной вставки свойства DISABLEADVTSHORTCUTS в файл MSI. С моим подходом Орка не нужна. Однако это полезно для проверки того, что событие сборки вносит ожидаемое изменение.

В событии сборки неправильное написание «BuiltOuputPath» является преднамеренным.

Вот код DisableAdvt.vbs Гэри Чанга (обратите внимание, что я исправил опечатку в строке 21 — очень важно!):

Option Explicit

Const msiOpenDatabaseModeTransact = 1
Dim argNum, argCount:argCount = Wscript.Arguments.Count

Dim openMode : openMode =  msiOpenDatabaseModeTransact

' 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

query = "INSERT INTO Property(Property, Value) VALUES ('DISABLEADVTSHORTCUTS', '1')"  
Set view = database.OpenView(query) : CheckError
view.Execute : CheckError

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
person T.C.    schedule 01.09.2011