
[英]Custom actions in MSI setup not working properly when upgrade to VS2010
[英].NET App Shortcut for MSI When Run By Regular User
我有一个 C# 应用程序,它使用 Visual Studio 2005 中的内置 MSI 构建器。
使用 MSI(通过 CD)将应用程序部署到目标计算机后,我启动桌面快捷方式(作为特权用户),程序按预期运行。 但是,如果我注销然后以非特权用户身份重新登录并尝试运行应用程序,计算机会开始寻找 MSI,因为它想要修复/配置它。 当然这会失败,因为它无法再次找到 MSI。
但是,我可以在 Program Files 中浏览到应用程序的文件夹并将快捷方式复制到桌面并运行得非常好。
我如何解决这个问题? 我已经更改了许多设置,试图在没有运气的情况下解决这个问题。
编辑:我设置了 InstallAllUsers=True 。
正如这里所解释的,Visual Studio 只能创建使用 MSI 文件来检查所有文件和注册表值是否存在的“广告快捷方式”。
在同一链接中,您可以找到解决方案:编辑 MSI 数据库以在属性表中添加一个值。 我测试了它,你只需要添加值“1”的“ DISABLEADVTSHORTCUTS ”。
要添加它,您可以使用 ORCA 工具,它是Windows 安装程序 SDK的一部分。 这是手动方式......我想你不会喜欢它。
因此,我进一步查看,发现您可以使用 Window 安装程序 SDK 提供的命令行和 VBS 脚本来执行此操作:
Cscript WiRunSQL.vbs Test.msi "INSERT INTO `Property` (`Property`.`Property`,`Property`.`Value`) VALUES ('DISABLEADVTSHORTCUTS',1)"
现在您只需为您的设置项目设置一个构建后事件(它与“常规”项目有点不同,请参见此处)以执行此脚本。
它对我很有用!
其他资源:
MSI 属性表参考
使用命令行编辑 MSI
如果 MSI 将任何注册表项写入 HKCU,那么当新用户第一次运行该应用程序时,Windows 安装程序会看到该用户不存在这些条目并尝试创建它们。 为什么 Windows 安装程序认为它需要原始 MSI 文件,这超出了我的理解(C:\Windows\Installer 中的存根应该足够了,但似乎还不够)。
在任何情况下,替换快捷方式都不是完整的快捷方式,因为其他操作(例如调用 COM 组件)可以调用与广告快捷方式调用相同的自愈过程。
当您安装时,通常有一个选项可以为“每个人”或“只是我”安装。 一定要检查每个人。 您甚至可以在构建 msi 时将其设置为默认值。
作为附加说明,旧版本的 MS Office 也有同样的问题(也许它仍然存在;我不需要检查最近的版本——也许这意味着没有解决方案)。 早在我以前在一家小型电脑商店工作时,每当我们建立一个新版本时,我们总是会创建初始用户帐户,然后手动启动一次办公室,以便为我们的用户排除额外的步骤。
基本上,桌面快捷方式是触发 windows 安装程序弹性检查的特殊快捷方式 - 尝试恢复丢失的文件、文件夹和注册表项。
我很可能会说您缺少一些每个用户的注册表项(HKCU 或 HKCR),因此 Windows 安装程序会尝试找到 MSI 来重新创建它们。
编辑 2010 年 6 月:我创建的 MSI 在 Windows XP 上的 VS 2005 下。 当我尝试在 Vista 下使用相同的 MSI 安装/卸载时,卸载不是很干净。 我没有评估其程度或原因,但我不建议在没有进一步调查的情况下在 Vista 上使用此解决方案。
原帖:
我仍然没有找到真正解决我的问题的方法,尽管解决方法——有点破解——对于我的目的来说已经足够好了。 我在其他网站上找到了这个建议(如果我能再次找到它,我会发布一个链接)。
我创建了一个具有两个功能的 VBS 文件:一个创建快捷方式,另一个根据需要创建目录结构。 当文件执行时,它会根据开发人员认为合适的次数调用 MakeShortcut。
第二个 VBS 文件的工作方式相同,但删除了快捷方式。
我将第一个文件称为安装文件夹中自定义操作的一部分(右键单击安装项目、查看、自定义操作)。 我在卸载文件夹中调用第二个。
问题是这两个 VBS 文件以及程序的 rest 都安装到了目标目录中。 可能有办法摆脱它们,但我真的不在乎它们留在那里。 同样,这有点像 hack,并不像我希望的那样优雅,但它运行良好,直到我找到更好的解决方案。
这是两个文件,以防有人想使用它们:
'创建快捷方式.VBS
MakeShortcut "%AllUsersProfile%\Start Menu\Programs\My Prog Folder", _
"My Prog", _
"%ProgramFiles%\My prog\prog.exe"
Function MakeShortcut (location, text, target)
Dim objShortcut
Dim objShell
Dim expLocation
Set objShell = CreateObject("WScript.Shell")
expLocation = objShell.ExpandEnvironmentStrings(location)
expTarget = objShell.ExpandEnvironmentStrings(target)
MakeDirectory(expLocation)
set objShortcut = objShell.CreateShortcut(expLocation & "\" & text & ".lnk")
objShortcut.TargetPath = expTarget
objShortcut.Save
End Function
Function MakeDirectory (newPath)
Dim objFSO
Dim arrPath
Dim length
Dim count
Dim path
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FolderExists(newPath) Then
Exit Function
End If
path = ""
count = 0
arrPath = split(newPath, "\")
length = ubound(arrPath)
While count <= length
path = path + arrPath(count) + "\"
count = count + 1
If Not objFSO.FolderExists(path) Then
objFSO.CreateFolder(path)
End If
Wend
End Function
删除快捷方式.VBS
DeleteShortcut "%AllUsersProfile%\Start Menu\Programs\My Prog Folder", _
"My Prog.lnk", _
True
Function DeleteShortcut (location, shortcut, delLoc)
Dim objShortcut
Dim objShell
Dim expLocation
Set objShell = CreateObject("WScript.Shell")
Set objFSO = CreateObject("Scripting.FileSystemObject")
expLocation = objShell.ExpandEnvironmentStrings(location)
DeleteDirectory(expLocation)
If objFSO.FileExists(expLocation) Then
objFSO.DeleteFile expLocation & "\" & shortcut
End If
If delLoc = True Then
DeleteDirectory location
End If
End Function
Function DeleteDirectory (path)
Dim objFSO
Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FolderExists(path) Then
objFSO.DeleteFolder path, True
End If
End Function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.