Archive: Create a shortcut link which has "Run as administrator" option enabled on Vista


Create a shortcut link which has "Run as administrator" option enabled on Vista
Hi,

During an installation process I need to create a link in the start menu and in case we are on Windows Vista I need this link to have "Run as administrator" option checked.

The link is to Windows component (rundll.exe), so I can't achieve this by adding a manifest to an exe.

Is this possible with NSIS?

Thanks.


Createshortcut does not support this. You could create a small wrapper program with a manifest that exec's rundll32 (you could create the app in nsis even)


I use rundll.exe to execute the function in my dll. So theoretically I could provide a standalone exe for that. However I put that inside a dll long time ago (before Vista) because I wanted to make things simpler.

Anyway I noticed that on Windows Vista it's the 21st byte of the .lnk file that marks whether the shortcut is launched with elevated rights or not. I could simply modify that byte after .lnk is created (in case we are installing on Vista), but that would be an ugly hack.


http://forums.winamp.com/showthread....hreadid=274267 is about a similar problem, we almost found a solution, but I guess kichik could not get it working in the end, maybe you can...

More of the same:
http://forums.winamp.com/showthread....hreadid=277988
http://forums.winamp.com/showthread....hreadid=271953


I have found an official way to modify link's attributes.

Here is the final function I used (it allows setting attributes only, for clearing attributes it would need to be modified a bit):


HRESULT SetLinkAttributes(wchar_t* path, DWORD myflags)
{
HRESULT result;
IShellLink* link;
IPersistFile* file;
IShellLinkDataList* pdl;
DWORD flags=0;

CoInitializeEx(NULL,COINIT_APARTMENTTHREADED);

result = CoCreateInstance(CLSID_ShellLink,NULL,CLSCTX_INPROC_SERVER,IID_IShellLink,(void**)(&link)); // Create IShellLink object
if(result==S_OK){
result = link->QueryInterface(IID_IPersistFile,(void**)(&file)); // retreive the IPersistFile
if(result==S_OK){
result = file->Load(path,STGM_READ); // load the link data from the file
if(result==S_OK){
result = link->QueryInterface(IID_IShellLinkDataList,(void**)(&pdl)); // look for IShellLinkDataList interface
if(result==S_OK){
result = pdl->GetFlags(&flags);
if(result==S_OK){
if((myflags & flags)!=myflags){ // only set myflags if they are not already set
result=pdl->SetFlags(myflags|flags);
if(result==S_OK){
result=file->Save(NULL,true);
if(result==S_OK){
result=file->SaveCompleted(NULL);
}
}
}
}
pdl->Release();
}
}
file->Release();
link->Release();
}
CoUninitialize();
}
return result;
}

void CALLBACK DllSetConfigLinkAttributes(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) //set that "Run as administrator" attribute
{
wchar_t path[_MAX_PATH];

if(LOBYTE(LOWORD(GetVersion()))<6) // we want to change it only on Windows Vista or later
return;

if(SHGetSpecialFolderPath(NULL,path,CSIDL_PROGRAMS,FALSE)){
wcscat(path, L"\\My Folder in Start Menu\\My Link File to Change Attributes to.lnk");
if(SetLinkAttributes(path,SLDF_RUNAS_USER)==S_OK)
;//success
else
;//failure
}
}



It was beyond me to write it in NSIS script so I put it into the dll, and called via rundll32 upon sucessful install.

OK, I am not sure if there is something is wrong with this method, but I came across this and have not seen a reference to it anywhere on NSIS forum. I think it is way easier than anything else proposed here and seems to work great.

Basically the "Run As Administrator" is simply a registry value stored in "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\layers" , so you can use:


WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\layers" \
"$MY_SHORCUT_OR_EXE" "RUNASADMIN"


Obviously replace $MY_SHORCUT_OR_EXE with your executable or shortcut. You can replace HKLM with HKCU for user specific setting instead of all users.


I figured I'd share.

-HH

Could a senior member/mod etc.. "anders" "joost" "afro" "kichik" "redwine" please confirm the validity of this example:

WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\layers" \
"$MY_SHORCUT_OR_EXE" "RUNASADMIN"

as the person submitting it has mentioned not knowing whether there is something wrong with it and not finding any other reference to it in the forums , no offence hichhicker but rather safe than sorry as my knowledge of reg writing is not much and this look very useful to me

thanks


Originally posted by tictox
no offence hichhicker but rather safe than sorry as my knowledge of reg writing is not much and this look very useful to me

thanks [/B]
None taken. I am curious myself how come this never came up here. I am no expert on Vista, (having ran it for the first time yesterday)I am updating my "roll-your-own" OpenVPN package to support Vista and ran into this need. It works for me, auto-prompting to up privileges every time I run whatever I put into the reg. The only issue I still have is the running apps with "run-as-admin" automatically at login. For some reason instead of prompting the user, it just blocks it forcing the user to run it manually :-(

-HH

Thanks , can i ask a few more questions to clear things up?

How would this effect the shortcuts/exe's functionality in xp?


you mention $MY_SHORCUT_OR_EXE .. does this mean if you have an exe in programfiles and a shortcut to that on the desktop and start menu you only have to do it once for the exe and all shortcuts to that would be fixed or do i have to do it once for all shortcuts and for the exe .. exact details are crucial to not having to fart arse around guessing how it works

when you refer to

qoute:

"The only issue I still have is the running apps with "run-as-admin" automatically at login."

Are you refering to apps launched via a shortcut added to $SMSTARTUP ?? when windows bootsup?

This is looking promising so far..

Thanks Hichhiker


Originally posted by tictox
[B]Thanks , can i ask a few more questions to clear things up?

How would this effect the shortcuts/exe's functionality in xp?


you mention $MY_SHORCUT_OR_EXE .. does this mean if you have an exe in programfiles and a shortcut to that on the desktop and start menu you only have to do it once for the exe and all shortcuts to that would be fixed or do i have to do it once for all shortcuts and for the exe .. exact details are crucial to not having to fart arse around guessing how it works
I experimented with this and it seems like if exe is set to run as admin, shortcuts automatically inherit it. I started off working on shortcuts, but it seems like doing exe is enough


when you refer to

qoute:

"The only issue I still have is the running apps with "run-as-admin" automatically at login."

Are you refering to apps launched via a shortcut added to $SMSTARTUP ?? when windows bootsup?
My NSIS script does this:

 
!insertmacro WriteRegStringIfUndef HKLM "SOFTWARE\Microsoft\Windows\CurrentVersion\Run" \
"openvpn-gui" "$INSTDIR\bin\openvpn-gui.exe"
WriteRegStr HKLM "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\layers" \
"$INSTDIR\bin\openvpn-gui.exe" "RUNASADMIN"


Which under XP start openvpn-gui when user logs in. Under Vista after reboot I get a message in system tray - "Windows has blocked some startup programs". I tried putting the shortcut in the startup folder - same thing. Looks like you cannot run "run as admin" programs automatically on login - which sucks.

-HH

Thanks
myself also had a same problem. after doing the above it is working fine in vista. But i can't find layers in specified path in Xp.
HKLM "Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\layers"

how can i get this one?

pls help me.


The ShellLink plug-in can be used to set a shortcut to Run As Administrator:
http://nsis.sourceforge.net/ShellLink_plug-in

A forum search found a topic called "CreateShortcut to run as administrator":
http://forums.winamp.com/showthread.php?t=319628


that is the correct path for XP, but why use a ugly hack when you can just use http://nsis.sourceforge.net/IShellLink_Set_RunAs_flag


The ShellLink plug-in also sets the SLDF_RUNAS_USER flag (I added it).

Stu


Please help
---------
EDIT:
Sorry, I figure it out. I must be having a slow day to not realize the last 2 lines in the example where explaining how to check if the command was successful.

Thank you anyway.
---------





Hi,

I am still relatively new to NSIS, so I am not sure I understand how to use plugins.

I downloaded the ShellLink Plug In from: http://nsis.sourceforge.net/ShellLink_plug-in

I unzipped it and copied the ShellLink.dll file to Program Files\NSIS\Plugins.

Trying to follow the example on the plugin page, I then modified a part of my script from:

...
CreateDirectory "$STARTMENU\Programs\${PRODUCT_PUBLISHER}"
CreateShortCut "$STARTMENU\Programs\${PRODUCT_PUBLISHER}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe"
...

to

...
CreateDirectory "$STARTMENU\Programs\${PRODUCT_PUBLISHER}"
CreateShortCut "$STARTMENU\Programs\${PRODUCT_PUBLISHER}\${PRODUCT_NAME}.lnk" "$INSTDIR\${PRODUCT_NAME}.exe"

ShellLink::SetRunAsAdministrator "$STARTMENU\Programs\${PRODUCT_PUBLISHER}\${PRODUCT_NAME}.lnk"
Pop $0

$0=0 -no errors
$0=-1 -error
...

That causes the following error when I try to compile my script:


Plugin Command: SetRunAsAdministrator $STARTMENU\Programs\Sharp Software\Auto Sales Manager WPF Server.lnk
Pop: $0
Invalid command: $0=0
Error in script "C:\Sharp Software\Auto Sales Manager\trunk\build\scripts\Auto Sales Manager WPF Server.nsi" on line 82 -- aborting creation process


Any help getting this to work would be greatly appreciated.


Use only this :
ShellLink::SetRunAsAdministrator "$STARTMENU\Programs\${PRODUCT_PUBLISHER}\${PRODUCT_NAME}.lnk"

This command is only if you want to test if command was succesfull (command store variable $0) :
Pop $0

$0=0 ; no errors
$0=-1 ; error

You can use IF command to test this variable (see NSIS doc)


Originally posted by kaiten
This command is only if you want to test if command was succesfull (command store variable $0) :
Pop $0
Err... No. You must always pop the return value, whether you want to use it or not, otherwise you're corrupting your stack.

Adding the run as administrator on a shortcut works great. Is it possible to add that property to the actual exe? I have an application that runs automatically when a file with a special extension is opened and I need it to run as admin.


Originally posted by hobbes487
Adding the run as administrator on a shortcut works great. Is it possible to add that property to the actual exe? I have an application that runs automatically when a file with a special extension is opened and I need it to run as admin.
Normally I'd say 'add a manifest', but I have no idea if that works for file associations. I think you can put "runas.exe /user:Administrator yourexe.exe %1" (or something similar) as the opening application, and it will throw a window asking for the admin password. But it's probably much better to make your exe take care of this problem itself: make it so it launches another instance of itself as admin, if it's being run as user.

Step 1: Add "Vista" manifest to your app requesting admin rights
Step 2: Your app should call IsUserAnAdmin() when it starts up, if false, ShellExecute yourself again with the runas verb