How to set “Run as administrator” flag on shortcut created by MSI installer

三世轮回 提交于 2019-12-03 20:53:28

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.

Daz

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

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

Chada

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:

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

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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!