Archive: Vista + Auto launch app - Part 2


Vista + Auto launch app - Part 2
This is a followup to see if anyone has found a clean solution to have an NSIS installer running as administrator launch an .exe as a non-admin user.

The previous thread was here: Vista + Run App On Install

It also linked to a helpful MSDN forum, here: How to CreateProcess NOT as administrator

Both threads seem to conclude that there wasn't a clean solution. The best solution (but still really ugly), is to make a wrapper NSIS installer. That wrapper first launches as a normal user and installs the main installer, then launches that main installer (which will request and install as administrator), and when the main installer is finished, the wrapper launches your application.

Ya, I could do that, but it feels like such an ugly hack. I'd really like to avoid making two NSIS installers to make it act like one should. Has anyone found any cleaner method?


I created a plugin for this, it's still a work in progress but you can check it out: http://forums.winamp.com/showthread....hreadid=265780


Anders,

Thanks for the plugin. I'm grateful that others are putting in the effort to give us a cleaner solution. I've been playing with it, and looking over the demos.

However, I'm baffled on how to make it work in my situation. I hate to ask for step by step help, but I just can't wrap my head around what's going on with the plugin, so I don't know where to begin.

Again, the scenario I'm seeing is this:
1) An installer will almost certainly be run in Vista as Administrator.
2) It will auto launch our app.
3) I need the app auto launched so it's not administrator.

What do I need to do with the plugin to accomplish steps 2 and 3?

Edit: Nevermind for now. I wasn't checking my end correctly. I'm really optimistic now...hoepfully the rest of my tests will do well.


Nevermind, I can't figure it out.

All of the demos are set to RequestExecutionLevel user.

But in my installer, I need admin access to write to the Program Files folder. Then I need to launch the application as the normal user. So I'm still stuck :(


You can also use VistaElevator. Download the compiled executables and copy over VE32.dll. Then use the System plug-in to call it.

StrCpy $R0 "$INSTDIR\program.exe" # program path
StrCpy $R1 "parmaters" # parameters
StrCpy $R2 "$INSTDIR" # working directory

InitPluginsDir

StrCpy $0 $PLUGINSDIR\ve32.dll
StrCpy $1 ?RunNonElevated@@YAHPAUHWND__@@PB_W11@Z

File /oname=$0 ve32.dll

System::Call 'kernel32::LoadLibrary(tr0)i.s'
System::Call 'kernel32::GetProcAddress(is,tr1)i.r1'
System::Call '::$1(i $HWNDPARENT, wR0, wR1, wR2)'

RequestExecutionLevel is set to user so the "outer" instance will run as the current user, this is the whole point of the plugin


Yay!

I got it to work. It seems I was just not understanding how it worked. So here's what I can figure out so far. If I'm wrong, please correct me. :)

1) Set RequestExecutionLevel to be user. The UAC plugin will eventually make two processes, one as a user, and one it will elevate itself to admin.
2) Just copy the .onInit function as found in most of the examples given in the plugin. That I believe elevates the visible window as be administrator, as well as checking early if it can even get adminstrator rights before continuing.
3) Anything you want done as user mode you do with the UAC plugin. For example, if I do the previous steps, UAC::Exec launches an application with user privileges.
4) Make sure the UAC plugin is unloaded before the application closes.

One problem I did notice is that my Installer Window ended up going behind the topmost window. For example, if I had an explorer window open, and I double clicked on my NSIS .exe, the Vista UAC dialog would come up of course, and then afterwards, the Intaller Window would appear *behind* the explorer window. Is there anything I can do about that?


you can try calling SetForegroundWindow $HWNDPARENT with the system plugin in .OnGuiInit, but generally, the OS tries to stop other apps stealing focus.


Anders,

I really appreciate your help. This plugin will probably be good enough for us to use.

Though I am trying to figure how to get the window up front. I'm going to start another thread on that. It's weird, if I have, say, 5 windows open, the NSIS window doesn't go to the back of all 5, just behind the active window. And my SetForegroundWindow doesn't seem to be working either. Anyways, thanks again for the plugin.


Make installer window topmost
in function .onGUIInit add:



System::Call "*${stRECT} .r1"
System::Call "User32::GetWindowRect(i, i) i ($HWNDPARENT, r1) .r2"
System::Call "*$1${stRECT} (.r2, .r3, .r4, .r5)"
IntOp $6 $4 - $2 ; $2 now contains the width
IntOp $7 $5 - $3 ; $3 now contains the height

System::Call 'user32::GetSystemMetrics(i 0) i .r0'
System::Call 'user32::GetSystemMetrics(i 1) i .r1'

IntOp $2 $0 - $6
IntOp $3 $1 - $7
IntOp $4 $2 / 2
IntOp $5 $3 / 2

System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) b ($HWNDPARENT, -1, $4, $5, 0, 0, 0x201)"


I hope this helps you.

Thanks,

Thanks!

I haven't been able to test this. I mainly needed it to work around something in the UAC plugin. But Anders made a change in the plugin so I no longer have to worry about it.

But hopefully your code will come in handy for anyone else needing this.


RunNonElevated on Vista does not work properly
Hi Kichik,

You suggested earlier in this thread (05-04-2007 12:44 PM) a certain way how to launch an application in vista from the installer.

You wrote "You can also use VistaElevator. Download the compiled executables and copy over VE32.dll..."

I have tried this by including VE32.dll and calling the function RunNonElevated in order to start my application out of the installer.
It works fine with a Vista administrator user account and the application starts with a “medium” integrity level (process explorer) as expected.
But when i try to run the same installer with a Vista standard user account the application won’t be started at all.

Do you or anybody else have any experience with this behavior and might also know what the problem is?


Thank you very much for your help.


It probably uses the task scheduler or something hacky like that