如何在MSI安装程序创建的快捷方式上设置“以管理员身份运行”标志

时间:2011-07-11 15:23:32

标签: visual-studio-2010 windows-installer setup-project shortcut setup-deployment

我在Visual Studio 2010中有一个安装和部署项目。

我希望安装程序在我的解决方案中为另一个项目的可执行文件创建两个快捷方式。一个普通的快捷方式,只使用当前凭据运行应用程序,另一个通过设置以管理员身份运行标志,从而确保在单击快捷方式时要求用户提供具有管理权限的凭据。

Set "Run as administrator flag" on shortcut

运行具有管理权限的应用程序可启用某些不可用的功能。

乍一看似乎无法设置此标志。可以直接在Visual Studio中完成吗?如果没有,还有其他选择吗?

编辑:如果没有,是否可以使用自定义安装程序类以编程方式修改快捷方式?

5 个答案:

答案 0 :(得分:6)

我知道这是一个很老的问题,但我需要找到答案,我想我可以帮助其他搜索者。我写了一个小函数来在VBScript中执行此任务(粘贴在下面)。它很容易适应VB.net / VB6。

从函数返回代码:
0 - 成功,改变了捷径 99 - 已设置为管理员运行的快捷方式标志 114017 - 找不到文件
114038 - 数据文件格式无效(特别是文件太小)
所有其他非零=意外错误。

如Chada在后面的文章中所述,此脚本不适用于msi广告快捷方式。如果使用此方法操作快捷方式中的位,则它必须是标准的,未通告的快捷方式。

参考文献: MS快捷方式LNK格式:http://msdn.microsoft.com/en-us/library/dd871305
一些灵感:Read and write binary file in VBscript

请注意,该功能不会检查有效的LNK快捷方式。实际上你可以输入任何文件,它会改变文件中的十六进制字节15h,将第32位设置为开启。

如果在修改之前将原始快捷方式复制到%TEMP%。

哈根达斯。

'# D.Collins - 12:58 03/09/2012
'# Sets a shortcut to have the RunAs flag set.  Drag an LNK file onto this script to test

Option Explicit

Dim oArgs, ret

Set oArgs = WScript.Arguments

If oArgs.Count > 0 Then
    ret = fSetRunAsOnLNK(oArgs(0))
    MsgBox "Done, return = " & ret
Else
    MsgBox "No Args"
End If

Function fSetRunAsOnLNK(sInputLNK)
    Dim fso, wshShell, oFile, iSize, aInput(), ts, i
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set wshShell = CreateObject("WScript.Shell")
    If Not fso.FileExists(sInputLNK) Then fSetRunAsOnLNK = 114017 : Exit Function
    Set oFile = fso.GetFile(sInputLNK)
    iSize = oFile.Size
    ReDim aInput(iSize)
    Set ts = oFile.OpenAsTextStream()
    i = 0
    Do While Not ts.AtEndOfStream
        aInput(i) = ts.Read(1)
        i = i + 1
    Loop
    ts.Close
    If UBound(aInput) < 50 Then fSetRunAsOnLNK = 114038 : Exit Function
    If (Asc(aInput(21)) And 32) = 0 Then 
        aInput(21) = Chr(Asc(aInput(21)) + 32)
    Else
        fSetRunAsOnLNK = 99 : Exit Function
    End If
    fso.CopyFile sInputLNK, wshShell.ExpandEnvironmentStrings("%temp%\" & oFile.Name & "." & Hour(Now()) & "-" & Minute(Now()) & "-" & Second(Now()))
    On Error Resume Next
    Set ts = fso.CreateTextFile(sInputLNK, True)
    If Err.Number <> 0 Then fSetRunAsOnLNK = Err.number : Exit Function
    ts.Write(Join(aInput, ""))
    If Err.Number <> 0 Then fSetRunAsOnLNK = Err.number : Exit Function
    ts.Close
    fSetRunAsOnLNK = 0
End Function

答案 1 :(得分:5)

这主要是因为Windows Installer对Windows Installer程序包使用了“广告快捷方式”。

在Visual Studio中无法固有地禁用此功能,但可以修改生成的MSI以确保它不使用通告的快捷方式(或仅使用一个)。有两种方法可以解决这个问题:

  • 如果您的应用程序使用单个exe或两个 - 使用ORCA编辑MSI。在快捷方式表下,将目标条目更改为“[TARGETDIR] \ MyExeName.exe” - 其中MyExeName是您的exe的名称 - 这可确保不会公布该特定快捷方式。
  • 使用ORCA或post build事件(使用WiRunSQL.vbs脚本)将DISABLEADVTSHORTCUTS = 1添加到MSI的属性表中。如果您需要更多信息,请告诉我。这会禁用所有广告的快捷方式。

最好使用第一种方法,创建2个快捷方式,并在ORCA中只修改一个,这样您就可以右键单击并以管理员身份运行。

希望这有帮助

答案 2 :(得分:3)

Windows Installer不支持此功能。高程通常由应用程序通过其manifest来处理。

解决方案是创建一个包装器(VBScript或EXE),使用ShellExecute runas 动词以管理员身份启动应用程序。然后,您的快捷方式可以指向此包装器而不是实际的应用程序。

答案 3 :(得分:1)

对于这种困惑感到抱歉 - 我现在明白你的所作所为。

确实有一些方法可以设置快捷方式标志,但在Visual Studio中我没有直接设置。我发现了许多用C ++编写的函数,它们在快捷方式上设置了SLDF_RUNAS_USER标志。

此类功能的一些链接包括:

关于同一主题的另一个有趣讨论是在NSIS论坛上进行的,该主题可能有所帮助。有一个列出的功能可以构建,并提到存储这样的快捷方式设置的注册表位置(这似乎是最简单的方法,如果它的工作) - 我目前无法测试注册表方法,但可以稍后再看它是否有效。

可在此处找到此主题:http://forums.winamp.com/showthread.php?t=278764

如果您非常希望以编程方式执行此操作,那么您可以调整上述某个函数作为安装后任务运行吗?这将在安装后设置快捷方式的标志,但这又需要在非广告快捷方式上完成,因此必须修复MSI,如前所述。

我会继续查看并测试注册表设置方法,看它是否有效并报告回来。

查达

答案 4 :(得分:1)

从“开始”菜单或“程序文件”运行时,我需要提示我的应用程序提示管理员权限。

我在\ bin \ Debug \ my_app.exe'运行此程序作为管理员'复选框设置为true后实现了此行为。 (位于“属性\兼容性”部分)。

安装项目时,此文件已复制到程序文件(因此也就是“开始”菜单中的快捷方式),并具有所需的行为。

谢谢, 帕夫洛