Jump to content

Recommended Posts

Posted

Valik: All x64 chips have DEP I believe.

P: DEP is not turned by default for all processes because it breaks far too many programs that aren't coded for it.

As it's coming from an external control and we want to ensure that we can happily run most controls, we might have to do what windows does and leave it off for compatibility sake. I'd forgotten that we sometimes execute other controls that may not work. I'm happy that "our" code is DEP compliant though :P

I attached a simple script that demonstrates the problem. To run the script though, you will need to download the control from ELPhotoX.com. It DOES have a free trial.

I get the impression, though, that this issue is going to be resolved by turning DEP off. Understandable, but its unfortunate, in my opinion, that MS does ship Vista with DEP enabled for all programs. We, the users, would benefit if all code was held to the same high standards as AutoIt.

DEP_Test.au3

By the way, I only installed the beta to keep up with the changes. I expect many, like myself, appreciate the log entries that document what has changed.

I did inform the developer that the control does not appear to be DEP compliant...

Thank you again for your help!

Sincerely,

Paul

  • Replies 641
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

  • Administrators
Posted

I don't suppose anyone has time to turn that example repro into VBscript do they? On my Vista Ultimate x64 box the x86 version of wscript is also marked for permanent DEP - so it would be interesting to see if that generates the same error.

Edit: oh, the script has gui code in it - there's probably no direct translation in that case

Posted

Jon, should be trivial to create a C++ example with MFC to embed the control. It's 95% wizard generated stuff anyway.

Posted

Jon, toss out a new release when you get a chance. livewire found a bug with the Run functions and it's rather serious (and stupid) - in short the kind of thing I expected. Fix is already committed.

  • Administrators
Posted

http://www.autoitscript.com/autoit3/files/beta/autoit

3.2.13.7 (6th August, 2008) (Beta)

AutoIt:

- Fixed: Really stupid mistake with Run functions.

- Added #481: 11 pixel margin around the text in SplashTextOn() (Meets Vista UI guidelines).

- Added #468: Added @MSec macro for obtaining the current milliseconds for the current second.

- Added #277: @CPUArch macro to return the capability of the processor.

- Changed: Tweaked DEP and Image randomization linker options.

AutoItX:

- Changed: Converted to full unicode - ANSI DLL prototypes removed. (For now, depends on demand for adding in).

Posted (edited)

Just installed 13.7

Under Vista, RunWait does NOT wait for process to terminate. It returns control immediately with RC =0

Can someone else confirm this?

Edited by pdaughe
Posted

Just installed 13.7

Under Vista, RunWait does NOT wait for process to terminate. It returns control immediately with RC =0

Can someone else confirm this?

Perhaps the process is silently triggering another process and returning. Use something like Notepad to test.

Posted (edited)

Perhaps the process is silently triggering another process and returning. Use something like Notepad to test.

Reasonable suspicion on your part I suppose, but in this case I wrote the process!

Same code: On WinXP RunWait indeed waits; on Vista, it returns immediately. The inclusion or omission of a working directory on the RunWait command makes no difference.

By the way, for the developers, this problem WAS indeed present in the 13.3 beta; I installed the 13.7 beta in hopes of resolving it.

Sincerely,

Paul

Edit: Additional Information

The RUN command on Vista does not return the PID of the process that was launched. It does return what would be considered to be a valid PID (i.e. not negative or zero, or some outlandishly large number) however, even with "Showing Processes from All Users", I did not see a process that had the returned PID. For sure, the PID of the process that was launched was different than that returned by the RUN command.

Granted, I am looking at only one RUN command in the application, but the same code (compiled exe) runs correctly under XP.

Edited by pdaughe
Posted (edited)

Geesh, we have technical jobs!

I woke up this morning and just KNEW what the problem was (you're gonn'a love this one -- not).

I put together two simple programs to demonstrate:

Local $ExitCode = RunWait (@ScriptDir & "\" & "RequireAdmin.exe")

MsgBox (0, "RunVistaUAC", "RequireAdmin has now completed")

#RequireAdmin
MsgBox (0, "RequireAdmin Is Running", "UAC is NOT the solution")

This works fine on XP.

The problem, of course, is that RequireAdmin.exe get intercepted by a UAC prompt on Vista. I didn't verify it, but the returned $Pid from a RUN command used in a similar fashion I bet is somehow associated with the UAC prompt.

It's so tempting to turn this thread into a bashing on UAC, but I refrain :P

P.S. I was just thinking -- effective communication can be so challenging. I apologize for my original post on this problem. It shouldn't have said: RunWait command doesn't work on Vista. It should have said: "There appears to be a situation where the RunWait command doesn't work on Vista". I can see where stating "RunWait doesn't work..." could be offensive to a developer who's poured his heart and soul into development and testing. Then I think when WeaponX suggests testing with notebook: "but I know RunWait works in other cases and I know the developers tested it on Vista...." How a problem is communicated does make a difference (for those of you not married or have no children, this especially applies to relationships!!) -- I've been at this a long time and still make mistakes!

Edited by pdaughe
  • Administrators
Posted

If you check the error code from the RunWait command it will probably be something like "requires elevation". In which case you can try and run it elevated by uusing ShellExecute and the "runas" verb. The API unctions that Run/RunWait uses (createprocess) do not allow elevation on Vista - you must use ShellExecute.

Posted

Your script is pretty much what I expected. #RequireAdmin does launch a new instance of the script so that it can trigger the UAC prompt. Thus, the PID does change (why you can't find the PID in the list when you use Run()) and the original script (non-elevated) does return immediately which is why you get an immediate exit code of 0.

The solution is to either elevate the caller, have the caller detect if it's admin and use ShellExecuteWait() with "runas" to elevate the callee, or implement #RequireAdmin yourself in the callee by using IsAdmin() and ShellExecuteWait(). In short you need to be in explicit control of how the child process is created (elevated or not).

Posted

Jon,

RunWait returns zero (0) and @error = zero (0).

I'm not sure what you mean when you say Run/RunWait do not allow elevation on Vista; all I know is that the launched process DOES run with elevated privileges after I respond to the UAC prompt. In fact, the other way around seems to be the problem: launching a non-elevated process from an elevated one, which is what you may have been thinking.

Valik,

You always give good explanations -- I understand why Run/RunWait are behaving the way they do in this situation. As for me, I can work around it -- the implied dependency on the process NAME is acceptable (I have to use the NAME in the ProcessWaitCLose). It would probably be helpful to others if this consideration is documented under Run/RunWait.

To understand why I can't run the calling process with elevated privileges, you would have to glance at this post:

Vista UAC

I don't claim to understand the technical details of "why" Vista implemented it this way; I just know that I experience what many others have with Vista.

At the time the article referred to in the above post was written, the installers (e.g. Inno) did NOT provide a way to launch the installed application with NON-elevated privileges (i.e. pre-UAC credentials), which they do now, and may explain why no one responded to my post.

However, not all the bases are covered at product installation time. It would be great if AutoIt provided the ability to launch a non-elevated process from an elevated one. My experience suggests the opposite IS true: that is, I CAN launch an elevated process from a non-elevated one, but Jon's comments do concern me (am I just "getting away with it"). Perhaps I misunderstood, but I would appreciate any clarification on this subject that you could provide.

In my particular circumstance, I cannot run the calling process with elevated privileges, and ShellExecuteWait with "runas" doesn't provide a general solution due to the password requirement, correct?

Consider the "update process". In Vista, one obviously wants to separate the "Check for Update" process from the actual process which does the updates (which will require elevated privileges and thus a UAC prompt).

Now, suppose the update process has the responsibility to close application processes and restart those processes. The processes should not be launched with elevated privileges, hence the process cannot run with elevated privileges.

I know you can imagine many other scenarios. Microsoft's recommendation for situations like this is indeed to use separate processes. What I can't believe is that Microsoft did not provide a way for an elevated process to launch a non-elevated one, at least not with the initial introduction of Vista. You may know if they do now....

The bottom line is that once I figured out what was going on, the solution was simple: Wait for the process to complete using the process NAME and ProcessWaitClose. It's just important to understand that RUN is going to return an irrelevant PID and RunWait is NOT going to wait.

If I'm not getting this right, please bat me along side the head!

Sincerely,

Paul

Posted

Can you post an example script that shows a non-elevated AutoIt script that uses RunWait and then shows the UAC dialog? That's not possible AFAIK. CreateProcess doesn't have the code to do that so something else must be going on.

Jon,

It must be this communication thing -- if I understand your request correctly, that's EXACTLY what the two scripts I posted in post #591 show.

The first script runs with normal user credentials (no #RequireAdmin compiler directive). It runs the second script using RunWait.

The second script, RequireAdmin.exe, does indeed get successfully launched, but only after I reply to the UAC prompt and give it permission.

1. I run the first script.

2. UAC then prompts for permission.

3. RequireAdmin.exe then displays its message box.

The problem, of course, is that the first script doesn't wait for the second one, RequireAdmin.exe, to complete.

A ProcessWaitClose ("RequireAdmin.exe") in the first script resolves the problem.

If I put this code at the beginning of each script to verify:

If IsAdmin () Then
   MsgBox (0, @ScriptName, "Running with elevated privileges")
Else
   MsgBox (0, @ScriptName, "Running with standard user privileges")
EndIf

the first script verifies it is running with standard user privileges, while the second script runs with elevated privileges.

  • Administrators
Posted

Oh so the second script has a #requireadmin at the top? That makes sense now. It's important to understand what's going on here.

1. Run/RunWait use the CreateProcess API to launch (it has the options needed for lots of options like STDIO, ShellExecute is really lacking here)

2. CreateProcess CANNOT cause the UAC dialog to show. If you try and use it to run an app that is manifested with the "requireAdministrator" flag it will return an error saying that elevation was requested and denied. No UAC. Game over.

3. UAC elevation can only happen on process launch boundaries. You cannot change a currently running process to elevated mode.

What the AutoIt #requireadmin directive does is this:

1. Checks if the current process is running as admin, if so, does nothing

2. If not, it reruns itself using the same command line parameters but with the runas verb - this allows a UAC prompt to appear.

3. The original non-elevated process is allowed to die.

I did consider keeping the original process around but decided that it would too easy when launching a number of #requireadmin scripts that there would be lots of redundant processes hanging around.

The RunWait command is not causing the UAC prompt, that is done by the 2nd script automatically rerunning itself using ShellExecute to force UAC to show. Weird eh?

Therefore the autoit way to work around these problems is as Valik said. The calling process should do an IsAdmin check and then maually run the script using ShellExecute and runas. Yes it's annoying, yes it's different on XP and Vista, yes that's life in Vista-land :P Our own build scripts and tests have a similar XP/Vista/RunAs/ShellExecute section to do exactly what you mention.

  • Administrators
Posted

In your setup scenario I'd keep well away from weird hacks to try and force running an unelevated process from an elevated process (they may close undocumented tricks in newer SPs or versions of Windows) and try and work with it. Instead I'd have a master setup script that ran as unelevated, ran a sub-setup to do the elevated stuff and then when that finished and dropped back to unelevated to finish off (relaunch processes etc). If you look at what some .msi installs do under vista you may see a number of UAC prompts during installation as they mess about. I believe iTunes does it 3 or more times...

Posted

In your setup scenario I'd keep well away from weird hacks to try and force running an unelevated process from an elevated process (they may close undocumented tricks in newer SPs or versions of Windows) and try and work with it. Instead I'd have a master setup script that ran as unelevated, ran a sub-setup to do the elevated stuff and then when that finished and dropped back to unelevated to finish off (relaunch processes etc). If you look at what some .msi installs do under vista you may see a number of UAC prompts during installation as they mess about. I believe iTunes does it 3 or more times...

Good advice -- thank you! When I first ran into this problem (that of not be able to launch a non-elevated process from an elevated process) I did the research and discovered it was a VERY COMMON problem -- afterall, the install programs typically gave the user the option of launching the application after the installation was complete -- an obvious problem in Vista. Before the installers provided the capability to launch the application with the pre-UAC credentials, people had to use a "work around", like VistaLib32.dll. The installers may have solve the problem at installation time, but as you know and as I noted before, not all the implications of this are resolved at installation time (e.g. program updates). I decided to architect exactly the solution you recommend: perform those tasks which require privileged permissions in a separate process. It may be a little more work, but it's "clean" and it minimizes the number of UAC prompts incurred. It easy to tell the applications that were not tailored for higher level of security provided by Vista; they UAC-prompt the user like crazy. Microsoft isn't soley responsible for the UAC prompt mania....(although in my opinion, there was a better way).
Posted

Jon.

When you say:

AutoItX:

- Changed: Converted to full unicode - ANSI DLL prototypes removed. (For now, depends on demand for adding in).

Do you mean that the AutoItX3.dll can't be used anymore but only the Com implemtation?

Regards,

John.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...