Jump to content

_ShellExecuteAs


AppTux
 Share

Recommended Posts

This UDF is still in beta, because by example Notepad is still not working. It's really strange because if I just right-click on Notepad.exe and select run as..., it's working. I don't know if it's also on other programs, your and my task to find other programs what are not working. :)

It's experimental, I looked on the forums (), and I haven't found yet another function, so I decided to write a one by myself.

If you find other bugs or programs what are not working, there could be made a kind of 'blacklist' with programs what are not working.

Code:

#include-once
#include <File.au3>

Func _ShellExecuteAs($username, $domain, $password, $logon_flag, $torun, $workingdir = @SystemDir, $show_flag = "", $opt_flag = "")
    Dim $szDrive, $szDir, $szFName, $szExt

    If $username = "" Then Return 0 ;No username given, return 0
    If $domain = "" Then $domain = @ComputerName
    If $logon_flag = "" Then Return 0 ;No logon flag given, return 0
    If $torun = "" Then Return 0 ;No run value given, return 0
    If $show_flag = "" Then $no_show_flag = 1
    If $opt_flag = "" Then $no_opt_flag = 1
    If BitAND($no_opt_flag = 1, $no_show_flag = 1) Then $no_show_opt_flag = 1

    $fileinfo = _PathSplit($torun, $szDrive, $szDir, $szFName, $szExt)
    $extension = $fileinfo[4]

    $Standard = RegRead("HKEY_CLASSES_ROOT\" & $extension, "")

    If $Standard = "" Then SetError(1)

    $ShellCommand = RegRead("HKEY_CLASSES_ROOT\" & $Standard & "\shell\open\command", "")

    If $ShellCommand = "" Then SetError(2)

    $ShellCommand = StringReplace($ShellCommand, "%1", $torun);Set parameters to $toRun
    $ShellCommand = StringReplace($ShellCommand, "%L", $torun);Set parameters to $toRun
    $ShellCommand = StringReplace($ShellCommand, "%SystemRoot%", @WindowsDir);Set the %SystemRoot%

    If $no_show_flag = 1 Then
        $runas = RunAs($username, $domain, $password, $logon_flag, $ShellCommand, $workingdir, "", $opt_flag)
    ElseIf $no_opt_flag = 1 Then
        $runas = RunAs($username, $domain, $password, $logon_flag, $ShellCommand, $workingdir, $show_flag)
    ElseIf $no_show_opt_flag = 1 Then
        $runas = RunAs($username, $domain, $password, $logon_flag, $ShellCommand, $workingdir)
    Else
        $runas = RunAs($username, $domain, $password, $logon_flag, $ShellCommand, $workingdir, $show_flag, $opt_flag)
    EndIf
    If @error Then
        Return -1
    EndIf
    Return $runas ;Return Id of Process.
EndFunc   ;==>_ShellExecuteAs

Yes, it's a really strange code, but it works! :) (as far I know)

PowerSlide2UnlockiPhone look-a-like program you can use to lock your pc, you can't access your desktop again until the password is entered and the slider slided to the right. (really proud of it)-- After a time AutoIt and Windows, I switched to Mac. Don't expect me to answer anymore.
Link to comment
Share on other sites

This is actually really poorly written.

1) You're error checking what should be numeric parameters ($logon_flag for instance) to "", which is a string. Well, when you convert "" to a number (which is what happens in your test), guess what you get? Yep, 0.

2) Your error checking in general is kinda nonsense. If you want to error check for real, then make them meaningful, like checking if your flags are within the allowed range. Or skip it altogether, and let RunAs do the error checking for you. Which brings me to #3...

3) If there's an error from RunAs, you should return that error, not -1. So 'If @error Then Return SetError(@error, 0, 0)'.

4) You missed a replacement for EXEs. The default command is '"%1" %*'. So add the following to your replacements:

$ShellCommand = StringReplace($ShellCommand, "%*", "") ;remove params for EXEs, params set above

Parameters passed to the target will be part of the main commandline, so just ditch the %*.

5) Multiple cases for RunAs? Properly check and set parameters inside the function to set them to the proper defaults, than make one call to RunAs.

Edited by wraithdu
Link to comment
Share on other sites

Thanks for your reply,

Yes, it's poorly written, it has a lot of bugs and other, I haven't said it was a beta if it was working all. :)

I just go off the list you wrote:

1) Error checking is not my strongest point. This is just my first UDF and I still have to learn a lot about it. I'll modify.

2) Almost same, I don't have skills enough to handle all errors.

3) I'll modify.

4) Same

5) Same

I'll modify the code as fast I can. :)

Edit: modified, look below:

#include-once
#include <File.au3>

Func _ShellExecuteAs($torun, $username, $domain, $password, $logon_flag, $workingdir = @SystemDir, $show_flag = 0, $opt_flag = 0)
    Dim $szDrive, $szDir, $szFName, $szExt

    If $username = "" Then Return 0 ;No username given, return 0
    If $domain = "" Then Return 0;No domain given, return 0
    If $logon_flag = "" Then Return 0 ;No logon flag given, return 0
    If $torun = "" Then Return 0 ;No run value given, return 0

    $fileinfo = _PathSplit($torun, $szDrive, $szDir, $szFName, $szExt)
    $extension = $fileinfo[4]

    $Standard = RegRead("HKEY_CLASSES_ROOT\" & $extension, "")

    If $Standard = "" Then SetError(1)

    $ShellCommand = RegRead("HKEY_CLASSES_ROOT\" & $Standard & "\shell\open\command", "")

    If $ShellCommand = "" Then SetError(2)

    $ShellCommand = StringReplace($ShellCommand, "%1", $torun);Set parameters to $toRun
    $ShellCommand = StringReplace($ShellCommand, "%L", $torun);Set parameters to $toRun
    $ShellCommand = StringReplace($ShellCommand, "%SystemRoot%", @WindowsDir);Set the %SystemRoot%

    $runas = RunAs($username, $domain, $password, $logon_flag, $torun, $workingdir, $show_flag, $opt_flag)

    If @error Then Return SetError(@error, 0, 0)
    Return $runas ;Return Id of Process.
EndFunc   ;==>_ShellExecuteAs

With your comments I modified the code.

Edited by AppTux
PowerSlide2UnlockiPhone look-a-like program you can use to lock your pc, you can't access your desktop again until the password is entered and the slider slided to the right. (really proud of it)-- After a time AutoIt and Windows, I switched to Mac. Don't expect me to answer anymore.
Link to comment
Share on other sites

Still way off unfortunately. The edited code definitely won't run correctly. I was bored so, here you go:

#include-once
;~ #include <File.au3>
#include <WinAPI.au3>

; set the default params same as RunAs
; the default params for the flags are numeric, so don't use an empty string
Func _ShellExecuteAs($username, $domain, $password, $logon_flag, $torun, $workingdir = @SystemDir, $show_flag = @SW_HIDE, $opt_flag = 0)
    ; declare variables local inside a function
;~  Local $szDrive, $szDir, $szFName, $szExt
    ;
    ; i removed your error checking as it seems silly since we're just going to return the error from RunAs later
    ;
    ; seems a bit overkill to use this function to pull just the extension, but that's your choice
    ; however be aware that the params except for the first are ByRef, so the result is returned in the param
;~  _PathSplit($torun, $szDrive, $szDir, $szFName, $szExt)
    ; another option...
    Local $szExt = StringTrimLeft($torun, StringInStr($torun, ".", 1, -1) - 1)
    ; no extension will return the full string so...
    Local $Standard = ""
    If ($szExt <> $torun) And ($szExt <> "") Then $Standard = RegRead("HKCR\" & $szExt, "")
    ; you want to return at this point
    ; set all values of SetError to both return @error = 1, and an actual return value of 0
    ; if you test it, SetError(1) will actually return a value of 1
;~  If $Standard = "" Then Return SetError(1, 0, 0)
    ;
    ; however in windows, and file without an extension is legal, so we can't assume it's an error
    ;
    Local $ShellCommand
    If $Standard <> "" Then
        ; move replacements here
        ; this RegRead is also not technically correct, the ShellExecute process is far more complicated
        ; and can still work fine if the 'open' verb does not exist
        ; i'll leave that to you
        $ShellCommand = RegRead("HKCR\" & $Standard & "\shell\open\command", "")
        $ShellCommand = StringReplace($ShellCommand, "%1", $torun) ;Set parameters to $toRun
        $ShellCommand = StringReplace($ShellCommand, "%L", $torun) ;Set parameters to $toRun
        $ShellCommand = StringReplace($ShellCommand, "%*", "") ; for EXEs
;~      $ShellCommand = StringReplace($ShellCommand, "%SystemRoot%", @WindowsDir) ;Set the %SystemRoot%
        ; this might be better...
        $ShellCommand = _WinAPI_ExpandEnvironmentStrings($ShellCommand)
    Else
        ; pass command as-is, and let autoit sort it out
        $ShellCommand = $torun
    EndIf
    ; ok to check this now
    If $ShellCommand = "" Then Return SetError(1, 0, 0)
    ; run it
    Local $ret = RunAs($username, $domain, $password, $logon_flag, $ShellCommand, $workingdir, $show_flag, $opt_flag)
    ;Return Id of Process.
    ; pass on the @error info as well
    ; RunAs does not set @extended, so just use 0
    Return SetError(@error, 0, $ret)
EndFunc   ;==>_ShellExecuteAs

Edit: small edits

Edited by wraithdu
Link to comment
Share on other sites

Whoa, I didn't expected it could be so much shorter! :)

I think the credits would go to you... :)

Notepad.exe still doesn't work, but others works.

You saved me a lot of work, because I'm working on a Run program, and I wanted a function you can run programs as another user, and this is helping me a lot I think.

Edited by AppTux
PowerSlide2UnlockiPhone look-a-like program you can use to lock your pc, you can't access your desktop again until the password is entered and the slider slided to the right. (really proud of it)-- After a time AutoIt and Windows, I switched to Mac. Don't expect me to answer anymore.
Link to comment
Share on other sites

Strange, notepad works for me as 'notepad.exe', 'notepad', 'C:\Windows\notepad.exe', '%SystemRoot%\notepad.exe'... can't you do a bit of error checking and find out why notepad isn't working for you?

Are you sure you're not just creating hidden notepad windows?

_ShellExecuteAs("user", "", "****", 0, "notepad.exe", "", @SW_SHOW)
Link to comment
Share on other sites

@wraithdu,

Never thought of that! :)

Maybe can I just modify the default $show_flag to @SW_SHOW. I think that'll work better :)

PowerSlide2UnlockiPhone look-a-like program you can use to lock your pc, you can't access your desktop again until the password is entered and the slider slided to the right. (really proud of it)-- After a time AutoIt and Windows, I switched to Mac. Don't expect me to answer anymore.
Link to comment
Share on other sites

You can modify your own function however you want, but you need to make sure and document it, especially if you're deviating from the standard parameters of RunAs. Now I realize that ShellExecute behaves differently from RunAs... so use your best judgement.

But remember my comment (in code) about Windows ShellExecute behavior... it works differently if there is no 'open' verb for the file type, and 'open' can still be overridden by user chosen defaults, etc. You'd be best served doing a bit of research on that to make your function behaves more like Windows standard behavior.

Link to comment
Share on other sites

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
 Share

  • Recently Browsing   0 members

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