How to set “Run as administrator” flag on shortcut

2019-03-31 22:34发布

问题:

I have a Setup and Deployment project in Visual Studio 2010.

I would like the installer to create two shortcuts to the executable of another project in my solution. One normal shortcut that simply runs the application using current credentials and another which has the Run as administrator flag set, thereby ensuring that the user is asked for credentials with administrative rights when clicking the shortcut.

Running the application with administrative rights enables certain features that are otherwise not available.

Setting this flag doesn't seem to be possible at first glance. Can this be done directly in Visual Studio? If not, are there any other options?

Edit: If not, is it possible to modify the shortcut programmatically using a custom installer class?

回答1:

This is not supported by Windows Installer. Elevation is usually handled by the application through its manifest.

A solution is to create a wrapper (VBScript or EXE) which uses ShellExecute with runas verb to launch your application as an Administrator. Your shortcut can then point to this wrapper instead of the actual application.



回答2:

I know this is quite an old question, but I needed to find an answer and I thought I could help other searchers. I wrote a small function to perform this task in VBScript (pasted below). It is easily adapted to VB.net / VB6.

Return codes from function:
0 - success, changed the shortcut.
99 - shortcut flag already set to run as administrator.
114017 - file not found
114038 - Data file format not valid (specifically the file is way too small)
All other non-zero = unexpected errors.


As mentioned by Chada in a later post, this script will not work on msi Advertised shortcuts. If you use this method to manipulate the bits in the shortcut, it must be a standard, non-advertised shortcut.

References: MS Shortcut LNK format: http://msdn.microsoft.com/en-us/library/dd871305
Some inspiration: Read and write binary file in VBscript

Please note that the function does not check for a valid LNK shortcut. In fact you can feed it ANY file and it will alter Hex byte 15h in the file to set bit 32 to on.

If copies the original shortcut to %TEMP% before amending it.

Daz.

'# 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


回答3:

This is largely due to the fact that Windows Installer uses 'Advertised shortcuts' for the Windows Installer packages.

There is no way inherently to disable this in Visual Studio, but it is possible to modify the MSI that is produced to make sure that it does not use advertised shortcuts (or uses only one). There are 2 ways of going about this:

  • If your application uses a single exe or two - Use ORCA to edit the MSI. Under the shortcuts table, change the Target Entry to "[TARGETDIR]\MyExeName.exe" - where MyExeName is the name of your exe - this ensures that that particular shortcut is not advertised.
  • Add DISABLEADVTSHORTCUTS=1 to the the property Table of the MSI using ORCA or a post build event (using the WiRunSQL.vbs script). If you need more info on this let me know. This disables all advertised shortcuts.

it may be better to use the first approach, create 2 shortcuts and modify only one in ORCA so that you can right click and run as admin.

Hope this helps



回答4:

Sorry for the confusion - I now understand what you are after.

There are indeed ways to set the shortcut flag but none that I know of straight in Visual Studio. I have found a number of functions written in C++ that set the SLDF_RUNAS_USER flag on a shortcut.

Some links to such functions include:

  • http://blogs.msdn.com/b/oldnewthing/archive/2007/12/19/6801084.aspx
  • http://social.msdn.microsoft.com/Forums/en-US/windowssecurity/thread/a55aa70e-ae4d-4bf6-b179-2e3df3668989/

Another interesting discussion on the same topic was carried out at NSIS forums, the thread may be of help. There is a function listed that can be built as well as mention of a registry location which stores such shortcut settings (this seems to be the easiest way to go, if it works) - I am unable to test the registry method at the moment, but can do a bit later to see if it works.

This thread can be found here: http://forums.winamp.com/showthread.php?t=278764

If you are quite keen to do this programatically, then maybe you could adapt one of the functions above to be run as a post-install task? This would set the flag of the shortcut after your install but this once again needs to be done on Non-Advertised shortcuts so the MSI would have to be fixed as I mentioned earlier.

I'll keep looking and test out the registry setting method to see if it works and report back.

Chada



回答5:

I needed to make my application to be prompted for Administator's Rights when running from Start Menu or Program Files.

I achieved this behavior after setting in \bin\Debug\my_app.exe 'Run this program as administator' checkbox to true. ( located in Properties\Compatibility section ).

While installing project, this file was copied to the Program Files (and therefore the shortcut in the Start Menu) with needed behavior.

Thanks, Pavlo