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 
相關問題