Как предотвратить запуск установщика при удалении файлов данных приложения?
У меня есть приложение, написанное на VB.Net с Visual Studio 2005. Приложение позволяет пользователю создавать и сохранять файлы проекта. Когда я распространяю приложение, я включаю некоторые демонстрационные файлы проекта, которые я устанавливаю в общую папку данных приложения.
XP - C: \ Documents and Settings \ Все пользователи \ Данные приложения
Vista & 7 - C:\ Данные программы
Я обнаружил неожиданное поведение - если какой-либо файл в общей папке данных приложения удаляется, и приложение запускается из меню "Пуск", то запускается процедура установки и попытается восстановить отсутствующие файлы. Если файл MSI больше не существует в его исходном местоположении или был изменен, то приложение не будет работать. Я чувствую, что это "особенность", но она мне не нужна. Может кто-нибудь сказать мне, что происходит и как я могу избежать этого?
Еще несколько деталей:
Я создал пакет установки с помощью проекта развертывания Visual Studio.
Такое поведение не произойдет, если я запускаю EXE напрямую. Поэтому я ожидаю, что это поведение связано с ярлыком в меню "Пуск". Я заметил, что ярлык не является обычным ярлыком - у него нет "Целевого местоположения".
Все советы приветствуются.
-TC
1 ответ
Я узнал, что это поведение включает в себя то, что называется "Install-on-Demand" ("Самовосстановление"). Необычные ярлыки, созданные пакетом установки, называются "Advertised Shortcuts". Теперь, когда у меня есть название проблемы, легко найти информацию о том, как ее решить. В частности:
- http://msdn.microsoft.com/en-us/library/aa368297.aspx
- http://groups.google.com/group/microsoft.public.dotnet.distributed_apps/browse_thread/thread/401847045f104af3
- http://blog.jtbworld.com/2007/11/enable-target-and-change-icon-of.html
Эти страницы содержат огромное количество информации. Для удобства других, кто может наткнуться на этот пост, я суммирую то, что они говорят:
Рекламируемые ярлыки - это специальные ярлыки, которые делают причудливые вещи. В частности, они переустанавливают поврежденное приложение перед запуском своей цели. Есть некоторые споры о том, являются ли они добрыми, злыми или безвредными. По моему мнению, они делают то, чего большинство пользователей не ожидают, и это делает их злыми. Поэтому я хотел бы отключить их для моего приложения.
Проекты установки Visual Studio автоматически создают пакеты MSI, которые по умолчанию генерируют объявленные ярлыки. При установке пакета MSI легко изменить это значение по умолчанию, используя DISABLEADVTSHORTCUTS=1 в качестве аргумента командной строки для Setup.exe. Кроме того, с помощью такой утилиты, как Orca, вы можете вручную изменить значение по умолчанию, вставив DISABLEADVTSHORTCUTS=1 в качестве свойства MSI. Однако, если вы хотите, чтобы Visual Studio автоматически создавал пакеты MSI, которые не создают объявленные ярлыки, это сложнее. Я сделал это так:
Сначала я создал VBS-файл, используя код DisableAdvt, предоставленный Гэри Чангом по одной из ссылок выше (я повторил этот код ниже). Просто создайте текстовый файл, вставьте в код. и сохраните его как DisableAdvt.vbs.
Затем создайте событие после сборки для вашего проекта установки. Точный синтаксис зависит от расположения ваших файлов. Поскольку мой 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