1

我有一个用VB.Net和Visual Studio 2005编写的应用程序。该应用程序允许用户创建和保存项目文件。当我分发应用程序时,我会包含一些演示项目文件,我将其安装在通用应用程序数据文件夹中。如何在应用程序数据文件被删除时阻止安装程序运行?

XP - C:\ Documents和Settings \所有用户\应用数据

Vista的& 7 - C:\程序数据

我发现了一个意想不到的行为 - 如果在常见的应用程序的任何文件数据文件夹被删除,并且应用程序从开始菜单运行,然后安装程序将启动并尝试恢复丢失的文件。如果MSI文件不再存在于其原始位置或已被更改,则该应用程序将无法运行。我认为这是一个“功能”,但它是我不想要的。任何人都可以告诉我发生了什么以及如何避免它?

更多的细节:

  • 我通过使用Visual Studio的部署 项目创建的安装程序包。

  • 如果我直接启动EXE,则不会发生此行为。因此,我预计该行为与开始菜单快捷方式 有关。我注意到这个快捷方式不是正常的 快捷方式 - 它没有“目标位置”。

所有建议表示赞赏。

-TC

回答

1

我已经了解到,这种行为涉及到一些所谓的“安装点播”(又名“自愈”)。由安装程序包创建的不寻常的快捷方式称为“播发快捷方式”。现在我有了一个问题的名称,很容易找到有关如何解决问题的信息。值得注意的是:

这些网页包含了丰富的信息。为方便其他人可能会偶然发现这篇文章,我会总结他们的说法:

广告快捷方式是做一些奇特的事情的特殊快捷方式。最值得注意的是,他们在启动目标之前重新安装受损的应用程序。对于它们是好还是坏,还有一些争议。在我看来,他们做了大多数用户不期望的事情,并且这使他们变得邪恶。因此,我想为我的应用程序禁用它们。

Visual Studio安装项目会自动创建默认生成广告快捷方式的MSI包。通过使用DISABLEADVTSHORTCUTS = 1作为Setup.exe的命令行参数来安装MSI软件包时,很容易覆盖该默认设置。此外,通过像Orca这样的实用程序,您可以通过插入DISABLEADVTSHORTCUTS = 1作为MSI的属性来手动更改默认值。但是,如果您希望Visual Studio自动创建不创建广告快捷方式的MSI包,则更困难。我就是这么做的:

  1. 首先,我使用张智强在上面(我重复下面的代码)的链接之一提供的DisableAdvt代码创建了一个VBS文件。只需创建一个文本文件,粘贴代码。并将其另存为DisableAdvt.vbs。

  2. 然后,为您的安装项目创建后期生成事件。确切的语法将取决于您的文件位置。因为我DisableAdvt.vbs是在解决方案文件夹的“工具”子文件夹,我的生成后事件看起来是这样的:

    • “$(PROJECTDIR).. \工具\ DisableAdvt \ DisableAdvt.vbs”“$ (BuiltOuputPath)”

这就是我不得不这样做。它像一个魅力。

-TC

一些注意事项:

在Visual Studio 2005中,生成的事件不同的方式访问的安装项目比它们对于其他类型的项目。在解决方案资源管理器中单击项目名称,然后在“属性”窗格中查找PostBuildEvent。

Orca是一个实用程序,可用于手动将DISABLEADVTSHORTCUTS属性插入到MSI文件中。用我的方法,Orca是没有必要的。但是,它对验证构建事件正在进行预期更改非常有用。

在生成事件时,拼写错误 “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 
相关问题