Jump to content

Recommended Posts

Posted

Duh!!!! They obviously compile/build to exe's. Thank you so much for all of your help, this absolutely fixes my problem, and I'll probably end up taking out the checkbox function because I don't ever want them to have to option, I want it to run automatically at startup every time, for every program, but I will definitely use your functions! Thank you so much again! 

  • Moderators
Posted

@ajr73333 There have been a couple of folks that have played around with the ability to run a script with elevation and then lower on a per-process level. This one comes to mind, though it is several years old:

 

Beyond that, if it no longer works or looks like more than you want to delve into, the method suggested above is the easiest path; one script for Admin tasks, one for normal, and a controlling script to manage the order.

"Profanity is the last vestige of the feeble mind. For the man who cannot express himself forcibly through intellect must do so through shock and awe" - Spencer W. Kimball

How to get your question answered on this forum!

Posted
22 minutes ago, JLogan3o13 said:

@ajr73333 There have been a couple of folks that have played around with the ability to run a script with elevation and then lower on a per-process level. This one comes to mind, though it is several years old:

 

Beyond that, if it no longer works or looks like more than you want to delve into, the method suggested above is the easiest path; one script for Admin tasks, one for normal, and a controlling script to manage the order.

Interesting, so he manipulates Reg entries as he starts the processes to drop it back down. That's good to know, however that still won't work for me because as I stated earlier, some of the programs are on SAN's, or remote shares/servers, therefore trying to run those programs using the _RunWithReducesPrivileges would not work because it would have to modify the Reg on the servers holding the programs, which is not the local computer. That would work nicely if all of the programs were local, but unfortunately, they're not. 

Thank you very much though, I have already downloaded and saved it for future reference. 

  • Developers
Posted

The below functions are part of AutoIt3Wrapper and are used to ensure the command is performed with #RequireAdmin.
The first one simply creates a temp script with the AutoIt3 Commandline in it and then runs this commnd. I use it to reshell AutoIt3Wrapper with a commandline parameter for a function that requires admin rights. 
The second one is made to shell commands which responds to STDOUT/STDERR en the said output is returned at the end of the Func. 

Hope that explains it a little better. :)

Jos 

Func RunReqAdmin($Autoit3Commands, $prompt = 0)
    Local $temp_Script = _TempFile($TempDir, "~", ".au3")
    Local $temp_check = _TempFile($TempDir, "~", ".chk")
    FileWriteLine($temp_check, 'TempFile')
    FileWriteLine($temp_Script, '#NoTrayIcon')
    If Not IsAdmin() Then
        FileWriteLine($temp_Script, '#RequireAdmin')
        If $prompt = 1 Then MsgBox(262144, "Need Admin mode", "Admin mode is needed for this update. Answer the following prompts to allow the update.")
    EndIf
    FileWriteLine($temp_Script, $Autoit3Commands)
    FileWriteLine($temp_Script, "FileDelete('" & $temp_check & "')")
    RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $temp_Script & '"')
    ; Wait for the script to finish
    While FileExists($temp_check)
        Sleep(50)
    WEnd
    FileDelete($temp_Script & "*.*")
EndFunc   ;==>RunReqAdmin
;
Func RunReqAdminDosCommand($Autoit3Commands, $prompt = 0, $outfile = "")
    Local $temp_Script = _TempFile($TempDir, "~", ".au3")
    FileDelete($outfile)
    FileWriteLine($outfile, '! Cancelled execution.')
    FileWriteLine($temp_Script, '#NoTrayIcon')
    If Not IsAdmin() Then
        FileWriteLine($temp_Script, '#RequireAdmin')
        If $prompt = 1 Then MsgBox(262144, "Need Admin mode", "Admin mode is needed for this update. Answer the following prompts to allow the update.")
    EndIf

    __ConsoleWrite(">Running AdminLevel:" & $Autoit3Commands & @CRLF)
    FileWriteLine($temp_Script, "AutoItWinSetTitle ('AutoIt3Wrapper_RunningCommand')")
    FileWriteLine($temp_Script, "$Pid = Run('" & @ComSpec & ' /C ' & $Autoit3Commands & "', ''," & @SW_HIDE & ", 2)")
    FileWriteLine($temp_Script, "$Handle = _ProcessExitCode($Pid)")
    FileWriteLine($temp_Script, "$ConOut = ShowStdOutErr($Pid)")
    FileWriteLine($temp_Script, "$ExitCode = _ProcessExitCode($Pid, $Handle)")
    FileWriteLine($temp_Script, "_ProcessCloseHandle($Handle)")
    FileWriteLine($temp_Script, 'FileDelete("' & $outfile & '")')
    If $outfile <> "" Then
        FileWriteLine($temp_Script, 'FileWrite("' & $outfile & '",$ConOut)')
    EndIf
    FileWriteLine($temp_Script, "Exit $ExitCode")
    FileWriteLine($temp_Script, "Func _ProcessCloseHandle($h_Process)")
    FileWriteLine($temp_Script, "   ; Close the process handle of a PID")
    FileWriteLine($temp_Script, "   DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $h_Process)")
    FileWriteLine($temp_Script, "   If Not @error Then Return 1")
    FileWriteLine($temp_Script, "   Return 0")
    FileWriteLine($temp_Script, "EndFunc   ;==>_ProcessCloseHandle")
    FileWriteLine($temp_Script, "Func _ProcessExitCode($i_Pid, $h_Process = 0)")
    FileWriteLine($temp_Script, "   ; 0 = Return Process Handle of PID else use Handle to Return Exitcode of a PID")
    FileWriteLine($temp_Script, "   Local $v_Placeholder")
    FileWriteLine($temp_Script, "   If Not IsArray($h_Process) Then")
    FileWriteLine($temp_Script, "       ; Return the process handle of a PID")
    FileWriteLine($temp_Script, "       $h_Process = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $i_Pid)")
    FileWriteLine($temp_Script, "       If Not @error Then Return $h_Process")
    FileWriteLine($temp_Script, "   Else")
    FileWriteLine($temp_Script, "       ; Return Process Exitcode of PID")
    FileWriteLine($temp_Script, "       $h_Process = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $h_Process[0], 'int*', $v_Placeholder)")
    FileWriteLine($temp_Script, "       If Not @error Then Return $h_Process[2]")
    FileWriteLine($temp_Script, "   EndIf")
    FileWriteLine($temp_Script, "   Return 0")
    FileWriteLine($temp_Script, "EndFunc   ;==>_ProcessExitCode")
    FileWriteLine($temp_Script, "Func ShowStdOutErr($l_Handle, $ShowConsole = 1, $Replace = '', $ReplaceWith = '')")
    FileWriteLine($temp_Script, "   Local $Line = 'x', $Line2 = 'x', $tot_out, $err1 = 0, $err2 = 0, $cnt1 = 0, $cnt2 = 0")
    FileWriteLine($temp_Script, "   Do")
    FileWriteLine($temp_Script, "       Sleep(10)")
    FileWriteLine($temp_Script, "       $Line = StdoutRead($l_Handle)")
    FileWriteLine($temp_Script, "       $err1 = @error")
    FileWriteLine($temp_Script, "       If $Replace <> '' Then $Line = StringReplace($Line, $Replace, $ReplaceWith)")
    FileWriteLine($temp_Script, "       $tot_out &= $Line")
    FileWriteLine($temp_Script, "       If $ShowConsole Then ConsoleWrite($Line)")
    FileWriteLine($temp_Script, "       $Line2 = StderrRead($l_Handle)")
    FileWriteLine($temp_Script, "       $err2 = @error")
    FileWriteLine($temp_Script, "       If $Replace <> '' Then $Line2 = StringReplace($Line2, $Replace, $ReplaceWith)")
    FileWriteLine($temp_Script, "       $tot_out &= $Line2")
    FileWriteLine($temp_Script, "       If $ShowConsole Then ConsoleWrite($Line2)")
    FileWriteLine($temp_Script, "       ; end the loop also when AutoIt3 has ended but a sub process was shelled with Run() that is still active")
    FileWriteLine($temp_Script, "       ; only do this every 50 cycles to avoid cpu hunger")
    FileWriteLine($temp_Script, "       If $cnt1 = 50 Then")
    FileWriteLine($temp_Script, "           $cnt1 = 0")
    FileWriteLine($temp_Script, "           ; loop another 50 times just to ensure the buffers emptied.")
    FileWriteLine($temp_Script, "           If Not ProcessExists($l_Handle) Then")
    FileWriteLine($temp_Script, "               If $cnt2 > 2 Then ExitLoop")
    FileWriteLine($temp_Script, "               $cnt2 += 1")
    FileWriteLine($temp_Script, "           EndIf")
    FileWriteLine($temp_Script, "       EndIf")
    FileWriteLine($temp_Script, "       $cnt1 += 1")
    FileWriteLine($temp_Script, "   Until ($err1 And $err2)")
    FileWriteLine($temp_Script, "   Return $tot_out")
    FileWriteLine($temp_Script, "EndFunc   ;==>ShowStdOutErr")
    Local $rc = RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $temp_Script & '"')
    Sleep(500)
    ; Wait for the script to finish
    While WinExists("AutoIt3Wrapper_RunningCommand")
        Sleep(50)
    WEnd
    __DelTempFile($temp_Script)
    $rc = FileRead($TempConsOut)
    __DelTempFile($TempConsOut)
    Return $rc
EndFunc   ;==>RunReqAdminDosCommand

 

 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

  • 4 years later...
Posted
On 6/12/2018 at 3:45 AM, Jos said:

The below functions are part of AutoIt3Wrapper and are used to ensure the command is performed with #RequireAdmin.
The first one simply creates a temp script with the AutoIt3 Commandline in it and then runs this commnd. I use it to reshell AutoIt3Wrapper with a commandline parameter for a function that requires admin rights. 
The second one is made to shell commands which responds to STDOUT/STDERR en the said output is returned at the end of the Func. 

Hope that explains it a little better. :)

Jos 

Func RunReqAdmin($Autoit3Commands, $prompt = 0)
    Local $temp_Script = _TempFile($TempDir, "~", ".au3")
    Local $temp_check = _TempFile($TempDir, "~", ".chk")
    FileWriteLine($temp_check, 'TempFile')
    FileWriteLine($temp_Script, '#NoTrayIcon')
    If Not IsAdmin() Then
        FileWriteLine($temp_Script, '#RequireAdmin')
        If $prompt = 1 Then MsgBox(262144, "Need Admin mode", "Admin mode is needed for this update. Answer the following prompts to allow the update.")
    EndIf
    FileWriteLine($temp_Script, $Autoit3Commands)
    FileWriteLine($temp_Script, "FileDelete('" & $temp_check & "')")
    RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $temp_Script & '"')
    ; Wait for the script to finish
    While FileExists($temp_check)
        Sleep(50)
    WEnd
    FileDelete($temp_Script & "*.*")
EndFunc   ;==>RunReqAdmin
;
Func RunReqAdminDosCommand($Autoit3Commands, $prompt = 0, $outfile = "")
    Local $temp_Script = _TempFile($TempDir, "~", ".au3")
    FileDelete($outfile)
    FileWriteLine($outfile, '! Cancelled execution.')
    FileWriteLine($temp_Script, '#NoTrayIcon')
    If Not IsAdmin() Then
        FileWriteLine($temp_Script, '#RequireAdmin')
        If $prompt = 1 Then MsgBox(262144, "Need Admin mode", "Admin mode is needed for this update. Answer the following prompts to allow the update.")
    EndIf

    __ConsoleWrite(">Running AdminLevel:" & $Autoit3Commands & @CRLF)
    FileWriteLine($temp_Script, "AutoItWinSetTitle ('AutoIt3Wrapper_RunningCommand')")
    FileWriteLine($temp_Script, "$Pid = Run('" & @ComSpec & ' /C ' & $Autoit3Commands & "', ''," & @SW_HIDE & ", 2)")
    FileWriteLine($temp_Script, "$Handle = _ProcessExitCode($Pid)")
    FileWriteLine($temp_Script, "$ConOut = ShowStdOutErr($Pid)")
    FileWriteLine($temp_Script, "$ExitCode = _ProcessExitCode($Pid, $Handle)")
    FileWriteLine($temp_Script, "_ProcessCloseHandle($Handle)")
    FileWriteLine($temp_Script, 'FileDelete("' & $outfile & '")')
    If $outfile <> "" Then
        FileWriteLine($temp_Script, 'FileWrite("' & $outfile & '",$ConOut)')
    EndIf
    FileWriteLine($temp_Script, "Exit $ExitCode")
    FileWriteLine($temp_Script, "Func _ProcessCloseHandle($h_Process)")
    FileWriteLine($temp_Script, "   ; Close the process handle of a PID")
    FileWriteLine($temp_Script, "   DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $h_Process)")
    FileWriteLine($temp_Script, "   If Not @error Then Return 1")
    FileWriteLine($temp_Script, "   Return 0")
    FileWriteLine($temp_Script, "EndFunc   ;==>_ProcessCloseHandle")
    FileWriteLine($temp_Script, "Func _ProcessExitCode($i_Pid, $h_Process = 0)")
    FileWriteLine($temp_Script, "   ; 0 = Return Process Handle of PID else use Handle to Return Exitcode of a PID")
    FileWriteLine($temp_Script, "   Local $v_Placeholder")
    FileWriteLine($temp_Script, "   If Not IsArray($h_Process) Then")
    FileWriteLine($temp_Script, "       ; Return the process handle of a PID")
    FileWriteLine($temp_Script, "       $h_Process = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $i_Pid)")
    FileWriteLine($temp_Script, "       If Not @error Then Return $h_Process")
    FileWriteLine($temp_Script, "   Else")
    FileWriteLine($temp_Script, "       ; Return Process Exitcode of PID")
    FileWriteLine($temp_Script, "       $h_Process = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $h_Process[0], 'int*', $v_Placeholder)")
    FileWriteLine($temp_Script, "       If Not @error Then Return $h_Process[2]")
    FileWriteLine($temp_Script, "   EndIf")
    FileWriteLine($temp_Script, "   Return 0")
    FileWriteLine($temp_Script, "EndFunc   ;==>_ProcessExitCode")
    FileWriteLine($temp_Script, "Func ShowStdOutErr($l_Handle, $ShowConsole = 1, $Replace = '', $ReplaceWith = '')")
    FileWriteLine($temp_Script, "   Local $Line = 'x', $Line2 = 'x', $tot_out, $err1 = 0, $err2 = 0, $cnt1 = 0, $cnt2 = 0")
    FileWriteLine($temp_Script, "   Do")
    FileWriteLine($temp_Script, "       Sleep(10)")
    FileWriteLine($temp_Script, "       $Line = StdoutRead($l_Handle)")
    FileWriteLine($temp_Script, "       $err1 = @error")
    FileWriteLine($temp_Script, "       If $Replace <> '' Then $Line = StringReplace($Line, $Replace, $ReplaceWith)")
    FileWriteLine($temp_Script, "       $tot_out &= $Line")
    FileWriteLine($temp_Script, "       If $ShowConsole Then ConsoleWrite($Line)")
    FileWriteLine($temp_Script, "       $Line2 = StderrRead($l_Handle)")
    FileWriteLine($temp_Script, "       $err2 = @error")
    FileWriteLine($temp_Script, "       If $Replace <> '' Then $Line2 = StringReplace($Line2, $Replace, $ReplaceWith)")
    FileWriteLine($temp_Script, "       $tot_out &= $Line2")
    FileWriteLine($temp_Script, "       If $ShowConsole Then ConsoleWrite($Line2)")
    FileWriteLine($temp_Script, "       ; end the loop also when AutoIt3 has ended but a sub process was shelled with Run() that is still active")
    FileWriteLine($temp_Script, "       ; only do this every 50 cycles to avoid cpu hunger")
    FileWriteLine($temp_Script, "       If $cnt1 = 50 Then")
    FileWriteLine($temp_Script, "           $cnt1 = 0")
    FileWriteLine($temp_Script, "           ; loop another 50 times just to ensure the buffers emptied.")
    FileWriteLine($temp_Script, "           If Not ProcessExists($l_Handle) Then")
    FileWriteLine($temp_Script, "               If $cnt2 > 2 Then ExitLoop")
    FileWriteLine($temp_Script, "               $cnt2 += 1")
    FileWriteLine($temp_Script, "           EndIf")
    FileWriteLine($temp_Script, "       EndIf")
    FileWriteLine($temp_Script, "       $cnt1 += 1")
    FileWriteLine($temp_Script, "   Until ($err1 And $err2)")
    FileWriteLine($temp_Script, "   Return $tot_out")
    FileWriteLine($temp_Script, "EndFunc   ;==>ShowStdOutErr")
    Local $rc = RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $temp_Script & '"')
    Sleep(500)
    ; Wait for the script to finish
    While WinExists("AutoIt3Wrapper_RunningCommand")
        Sleep(50)
    WEnd
    __DelTempFile($temp_Script)
    $rc = FileRead($TempConsOut)
    __DelTempFile($TempConsOut)
    Return $rc
EndFunc   ;==>RunReqAdminDosCommand

 

 

Is this still best practice in 2023 to launch elevated non-autoit application from non-elevated autoit script?

Posted (edited)

I guess for the same reason why there is this present:

FileWriteLine($temp_Script, "       $Line2 = StderrRead($l_Handle)")
    FileWriteLine($temp_Script, "       $err2 = @error")
    FileWriteLine($temp_Script, "       If $Replace <> '' Then $Line2 = StringReplace($Line2, $Replace, $ReplaceWith)")
    FileWriteLine($temp_Script, "       $tot_out &= $Line2")
    FileWriteLine($temp_Script, "       If $ShowConsole Then ConsoleWrite($Line2)")

Also I'm a bit confused by this part:

Local $rc = RunWait('"' & @AutoItExe & '" /AutoIt3ExecuteScript "' & $temp_Script & '"')
    Sleep(500)
    ; Wait for the script to finish
    While WinExists("AutoIt3Wrapper_RunningCommand")
        Sleep(50)
    WEnd

Wouldn't RunWait stop execution of the script until running application finished? (aka, redundant sleep and loop)

 

[EDIT]

after further testing it seems runwait() doesn't wait for the application finish execution when it runs as elevated (?). Also this method doesn't capture exitcode of the script...

Edited by VAN0
  • Developers
Posted (edited)

Correct, the process is restarted since it requires elevated rights, so runwait() will end immediately after the prompt was answered.

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Posted

If some tasks have to be executed UAC elevated, and others not, then the approach to start the "master script" uac elevated and then to reduce rights, when needed will result in just one UAC elevation login box, the rest then can run without any further UAC questions beeing asked.

Earth is flat, pigs can fly, and Nuclear Power is SAFE!

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...