普通用户运行时 .NET 应用程序的 MSI 快捷方式

发布于 2024-07-14 22:55:09 字数 343 浏览 9 评论 0原文

我有一个使用 Visual Studio 2005 中内置 MSI 生成器的 C# 应用程序。

使用 MSI(通过 CD)将应用程序部署到目标计算机上后,我启动桌面快捷方式(作为特权用户),程序按预期运行。 但是,如果我注销然后以非特权用户身份重新登录并尝试运行该应用程序,计算机就会开始查找 MSI,因为它想要修复/配置它。 当然这会失败,因为它无法再次找到 MSI。

但是,我可以浏览到程序文件中的应用程序文件夹,并将快捷方式复制到桌面并运行得很好。

我该如何解决这个问题? 我改变了一些设置试图解决这个问题,但没有运气。

编辑:我设置了InstallAllUsers=True。

I have a C# application that uses the built-in MSI builder in Visual Studio 2005.

After deploying the application using the MSI (via CD) onto the target computer, I launch the Desktop shortcut (as privileged user) and the program runs as expected. But, if I log out and then back in as an unprivileged user and try to run the application, the computer starts looking for the MSI because it wants to fix/configure it. Of course this fails because it can't find the MSI again.

I can, however, browse to the application's folder in Program Files and copy a shortcut to the desktop and run that perfectly fine.

How dow I get around this? I've changed a number of settings trying to get around this without luck.

EDIT: I have InstallAllUsers=True set.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心安伴我暖 2024-07-21 22:55:09

正如此处所述,Visual Studio只能创建使用 MSI 文件来检查所有文件和注册表值是否存在的“广告快捷方式”。

在同一链接中,您可以找到解决方案:编辑 MSI 数据库以在属性表中添加值。
我测试过,你只需添加“DISABLEADVTSHORTCUTS”,值为“1”。

要添加它,您可以使用 ORCA 工具,该工具是 Windows 安装程序 SDK
这是手动方式...我想你不会喜欢它。

因此,我进一步查看,发现您可以使用 Window Installer SDK 提供的命令行和 VBS 脚本来完成此操作:

Cscript WiRunSQL.vbs Test.msi "INSERT INTO `Property` (`Property`.`Property`,`Property`.`Value`) VALUES ('DISABLEADVTSHORTCUTS',1)"

现在您只需为安装项目设置一个构建后事件(它与“常规”项目有点不同) ,请参阅此处)以执行此脚本。

它对我来说非常有效!

其他资源:
MSI 属性表参考
使用命令行编辑 MSI

As explained here, the Visual Studio can only create "advertised shortcuts" that uses the MSI file to check that all the files and registry values are present.

In the same link you can find the solution : edit the MSI database to add a value in the Property table.
I tested it, you just have to add "DISABLEADVTSHORTCUTS" with the value "1".

To add it, you can use the ORCA tool which is part of the Windows Installer SDK.
This is the manual way... And I suppose you won't like it.

So I looked further and found that you can do that with a command line and a VBS script provided by the Window Installer SDK :

Cscript WiRunSQL.vbs Test.msi "INSERT INTO `Property` (`Property`.`Property`,`Property`.`Value`) VALUES ('DISABLEADVTSHORTCUTS',1)"

Now you just have to set a post build event for your setup project (it's a little different from "regular" projects, see here) in order to execute this script.

It works very well for me !

Additional resources :
MSI property table reference
Edit MSI with command line

烟燃烟灭 2024-07-21 22:55:09

安装时通常会有一个选项,可以选择为“所有人”或“仅我”安装。 确保检查每个人。 您甚至可以在构建 msi 时将其设置为默认值。

作为补充说明,旧版本的 MS Office 也有同样的问题(也许仍然存在;我不需要检查最新版本 - 也许这意味着没有解决方案)。 早在我曾经在一家小型电脑店工作时,每当我们设置新版本时,我们总是会创建初始用户帐户,然后手动启动一次 Office,以便为我们的用户省去额外的步骤。

There's normally an option when you install to install for "everyone" or "just me". Make sure to check everyone. You can even set that as default when you build the msi.

As an additional note, older versions of MS Office had this same problem (maybe it still does; I haven't needed to check recent editions — and maybe that means there is no solution). Way back when I used to work for a small computer shop whenever we set up a new build we'd always create the initial user accounts and then manually start up office once to get that extra step out of the way for our users.

む无字情书 2024-07-21 22:55:09

基本上,桌面快捷方式是触发 Windows 安装程序弹性检查的特殊快捷方式 - 尝试恢复丢失的文件、文件夹和注册表项。

我很可能会说您丢失了一些每用户注册表项(HKCU 或 HKCR),因此 Windows Installer 会尝试查找 MSI 来重新创建它们。

Basically the desktop shortcut is a special shortcut that triggers windows installer resiliency check - trying to restore for missing files, folders and registry entries.

Most likely I'd say you've got some per-user registry entries (HKCU or HKCR) that are missing and so Windows Installer tries to find the MSI to recreate them.

魔法唧唧 2024-07-21 22:55:09

如果 MSI 将任何注册表项写入 HKCU,则当新用户首次运行该应用程序时,Windows Installer 会发现该用户不存在这些注册表项,并尝试创建它们。 为什么 Windows Installer 认为它需要原始 MSI 文件,这超出了我的范围(C:\Windows\Installer 中的存根应该足够了,但似乎还不够)。

无论如何,替换快捷方式都不是完整的快捷方式,因为其他操作(例如调用 COM 组件)可以调用与所宣传的快捷方式所调用的相同的自我修复过程。

If the MSI writes any registry entries to HKCU, then when a new user runs the app for the first time, Windows Installer sees that the entries aren't present for that user and tries to create them. Why Windows Installer thinks it needs the original MSI file for this is beyond me (the stub in C:\Windows\Installer should be sufficient, yet doesn't seem to be).

In any case, replacing the shortcut isn't a complete shortcut, since other operations, such as invoking COM components, can invoke the same self-healing process that the advertised shortcut invokes.

明明#如月 2024-07-21 22:55:09

编辑 2010 年 6 月: 我创建的 MSI 是在 Windows XP 上的 VS 2005 下进行的。 当我尝试在 Vista 下使用相同的 MSI 安装/卸载时,卸载不是很干净。 我尚未评估其程度或原因,但我不建议在未经进一步调查的情况下在 Vista 上使用此解决方案。

原始帖子:

我仍然没有找到真正的解决方案来解决我的问题,尽管解决方法(有点黑客攻击)对于我的目的来说已经足够好了。 我在其他网站上找到了该建议(如果我能再次找到它,我将发布一个链接)。

我创建了一个 VBS 文件,它有两个功能:一个创建快捷方式,另一个根据需要创建目录结构。 当文件执行时,它会根据开发人员认为合适的次数调用 MakeShortcut。

第二个 VBS 文件的工作方式相同,但删除了快捷方式。

我将第一个文件称为安装文件夹中自定义操作的一部分(右键单击安装项目,查看,自定义操作)。 我在卸载文件夹中调用第二个。

问题是两个 VBS 文件以及程序的其余部分都安装到目标目录中。 可能有办法摆脱它们,但我真的不在乎它们留在那里。 再说一次,这有点像黑客,并不像我希望的那么优雅,但它工作得很好,直到我找到更好的解决方案。

这是两个文件,以防有人想要使用它们:

'CREATE SHORTCUTS.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

DELETE SHORTCUTS.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

EDIT Jun 2010: The MSI I created was under VS 2005 on Windows XP. When I tried to use the same MSI to install/uninstall under Vista, the uninstall was not very clean. I have not assessed the extent or cause, but I don't recommend using this solution on Vista without further investigation.

ORIGINAL POST:

I've still not found a real solution to my problem although the workaround -- a bit of a hack -- works well enough for my purposes. I found the suggestion on some other site (I will post a link to it if I can ever find it again).

I created a VBS file that has two functions: one creates a shortcut and the other creates the directory structure as necessary. When the file executes, it calls MakeShortcut as many times as the developer sees fit.

The second VBS file works the same way but deletes the shortcuts.

I call the first file as part of a Custom Action (right click on Setup project, VIEW, CUSTOM ACTIONS) in the Install folder. I call the second in the Uninstall folder.

The problem is that the two VBS files get installed into the target directory as well as the rest of the program. There is probably a way to get rid of them but I really don’t care that they stay there. Again, this is a bit of a hack and not as elegant as I was hoping but it works well enough until I can find a better solution.

Here are the two files in case anyone wants to use them:

'CREATE SHORTCUTS.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

DELETE SHORTCUTS.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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文