AppTux Posted March 21, 2011 Posted March 21, 2011 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:expandcollapse popup#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 ;==>_ShellExecuteAsYes, 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.
wraithdu Posted March 22, 2011 Posted March 22, 2011 (edited) 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 March 22, 2011 by wraithdu
AppTux Posted March 22, 2011 Author Posted March 22, 2011 (edited) 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 March 22, 2011 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.
wraithdu Posted March 22, 2011 Posted March 22, 2011 (edited) Still way off unfortunately. The edited code definitely won't run correctly. I was bored so, here you go: expandcollapse popup#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 March 22, 2011 by wraithdu
AppTux Posted March 22, 2011 Author Posted March 22, 2011 (edited) 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 March 22, 2011 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.
wraithdu Posted March 22, 2011 Posted March 22, 2011 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)
AppTux Posted March 23, 2011 Author Posted March 23, 2011 @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.
wraithdu Posted March 23, 2011 Posted March 23, 2011 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.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now