KaFu Posted January 18, 2011 Share Posted January 18, 2011 (edited) Hiho Forum,for a long time I just ignored the existence of UAC, in fact that's one of the first things to deactivate on a fresh Win7 install . But lately I received some complains about my programs regarding UAC, that's why I started to deal with it.Here's an example of how to elevate and de-elevate a compiled script. Sadly it needs the script to restart, but I've heard that someone's been working on a solution based on AutoItObject to do this in runtime .The example is based on the ShellExecute verb "runas" as pointed out by trancexx and the excellent by Ascend4nt. For your convenience I included the functions in the example below. The latest updates on this UDF will be available on his page.This script of course needs Vista+ and runs only compiled.Edit:Added a checkbox to "Auto-Elevate script on Start". Checking this box will add an "Application Compatibility Flag" to the registry at "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers", adding the executable URL as the Key with the "REG_SZ" value "RUNASADMIN". Before moving or deleting the script make sure that the checkbox is unchecked (the registry key is deleted) to not produce an orphaned RegKey.expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #region ;**** Directives created by AutoIt3Wrapper_GUI ****s #include <GUIButton.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> $sTitle = "UAC Elevate and DeElevate Example" If StringRegExp(@OSVersion, "_(XP|200(0|3))") Then MsgBox(16 + 262144, $sTitle, "Example only works for Vista+ OSs") Exit ElseIf Not @Compiled Then MsgBox(16 + 262144, $sTitle, "Example only works compiled") Exit EndIf $hGui = GUICreate($sTitle, 340, 90, Default,Default,Default, $WS_EX_TOPMOST) If IsAdmin() Then GUICtrlCreateLabel("Script is running in elevated mode (with admin rights)", 10, 10, 320, 20, $SS_CENTER) Else GUICtrlCreateLabel("Script is not running in elevated mode (with standard user rights)", 10, 10, 320, 20, $SS_CENTER) EndIf $c_Btn_Elevate = GUICtrlCreateButton("Elevate Script", 25, 30, 130, 30) If IsAdmin() Then GUICtrlSetState(-1, $GUI_DISABLE) _GUICtrlButton_SetShield(GUICtrlGetHandle($c_Btn_Elevate)) $c_Btn_DeElevate = GUICtrlCreateButton("Remove Elevation", 165, 30, 130, 30) If Not IsAdmin() Then GUICtrlSetState(-1, $GUI_DISABLE) $c_ChkB_Elavate_Always = GUICtrlCreateCheckbox("Auto-Elevate script on Start", 25, 65) GUICtrlSetTip(-1, "Checking this box will add an ""Application Compatibility Flag"" to the registry at" & @CRLF & @CRLF & _ "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" & @CRLF & @CRLF & _ ",adding the executable URL as the Key with the value RUNASADMIN." & @CRLF & @CRLF & _ "Before moving or deleting the script make sure that the checkbox is unchecked (the registry" & @CRLF & _ "key is deleted) to not produce an orphaned RegKey.", "Auto-Elevate", 1, 1) If Not IsAdmin() Then GUICtrlSetState(-1, $GUI_DISABLE) Else If RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers", @ScriptFullPath) = "RUNASADMIN" Then GUICtrlSetState(-1, $GUI_CHECKED) EndIf GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $c_Btn_Elevate If ShellExecute(@ScriptName, "", "", "runas") Then Exit Else MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong, you canceled the UAC prompt?") EndIf Case $c_Btn_DeElevate $iPID = _RunWithReducedPrivileges(@ScriptName, "", @ScriptDir) $iError = @error If ProcessExists($iPID) Then Exit Else MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong..." & @CRLF & "Error code: " & $iError) EndIf Case $c_ChkB_Elavate_Always $sRegString = "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Switch GUICtrlRead($c_ChkB_Elavate_Always) Case 1 If Not RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers", @ScriptFullPath, "REG_SZ", "RUNASADMIN") Then MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong, could not write AppCompatFlag to Registry.") GUICtrlSetState($c_ChkB_Elavate_Always, $GUI_UNCHECKED) Else MsgBox(16 + 262144, $sTitle, "RUNASADMIN added.") EndIf Case Else If Not RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers", @ScriptFullPath) Then MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong, could not write AppCompatFlag to Registry.") GUICtrlSetState($c_ChkB_Elavate_Always, $GUI_UNCHECKED) Else MsgBox(16 + 262144, $sTitle & " - Error", "RUNASADMIN removed.") EndIf EndSwitch EndSwitch WEnd Exit ; =============================================================================================================================== ; <_RunWithReducedPrivileges.au3> ; ; Function to run a program with reduced privileges. ; Useful when running in a higher privilege mode, but need to start a program with reduced privileges. ; - A common problem this fixes is drag-and-drop not working, and misc functions (sendmessage, etc) not working. ; ; Functions: ; _RunWithReducedPrivileges() ; runs a process with reduced privileges if currently running in a higher privilege mode ; ; INTERNAL Functions: ; _RWRPCleanup() ; Helper function for the above ; ; Reference: ; See 'Creating a process with Medium Integration Level from the process with High Integration Level in Vista' ; @ http://www.codeproject.com/KB/vista-security/createprocessexplorerleve.aspx ; See Elmue's comment 'Here the cleaned and bugfixed code' ; Also see: 'High elevation can be bad for your application: How to start a non-elevated process at the end of the installation' ; @ http://www.codeproject.com/KB/vista-security/RunNonElevated.aspx ; (Elmue has the same code here too in his response to FaxedHead's comment ('Another alternative to this method')) ; Another alternative using COM methods: ; 'Getting the shell to run an application for you - Part 2:How | BrandonLive' ; @ http://brandonlive.com/2008/04/27/getting-the-shell-to-run-an-application-for-you-part-2-how/ ; ; Author: Ascend4nt, based on code by Elmue's fixed version of Alexey Gavrilov's code ; =============================================================================================================================== ; =================================================================================================================== ; Func _RunWithReducedPrivileges($sPath,$sCmd='',$sFolder='',$iShowFlag=@SW_SHOWNORMAL,$bWait=False) ; ; Function to run a program with reduced privileges. ; Useful when running in a higher privilege mode, but need to start a program with reduced privileges. ; - A common problem this fixes is drag-and-drop not working, and misc functions (sendmessage, etc) not working. ; ; $sPath = Path to executable ; $sCmd = Command-line (optional) ; $sFolder = Folder to start in (optional) ; $iShowFlag = how the program should appear on startup. Default is @SW_SHOWNORMAL. ; All the regular @SW_SHOW* macros should work here ; $bWait = If True, waits for the process to finish before returning with an exit code ; If False, it returns without waiting for the process to finish, with the process ID # ; ; Returns: ; Success: If $bWait=True, the exit code of the Process. If $bWait=False, then the Process ID # of the process ; Failure: 0, with @error set: ; @error = 2 = DLLCall error. @extended contains the DLLCall error code (see AutoIt Help) ; @error = 3 = API returned failure. Call 'GetLastError' API function to get more info. ; ; Author: Ascend4nt, based on code by Elmue's fixed version of Alexey Gavrilov's code ; =================================================================================================================== Func _RunWithReducedPrivileges($sPath, $sCmd = '', $sFolder = '', $iShowFlag = @SW_SHOWNORMAL, $bWait = False) Local $aRet, $iErr, $iRet = 1, $hProcess, $hToken, $hDupToken, $stStartupInfo, $stProcInfo Local $sCmdType = "wstr", $sFolderType = "wstr" ;~ Run normally if not in an elevated state, or if pre-Vista O/S If Not IsAdmin() Or StringRegExp(@OSVersion, "_(XP|200(0|3))") Then ; XP, XPe, 2000, or 2003? If $bWait Then Return RunWait($sPath & ' ' & $sCmd, $sFolder) Return Run($sPath & ' ' & $sCmd, $sFolder) EndIf ;~ Check Parameters and adjust DLLCall types accordingly If Not IsString($sCmd) Or $sCmd = '' Then $sCmdType = "ptr" $sCmd = 0 EndIf If Not IsString($sFolder) Or $sFolder = '' Then $sFolderType = "ptr" $sFolder = 0 EndIf #cs ; STARTUPINFOW struct: cb,lpReserved,lpDesktop,lpTitle,dwX,dwY,dwXSize,dwYSize,dwXCountChars,dwYCountChars,dwFillAttribute, ; dwFlags,wShowWindow,cbReserved2,lpReserved2,hStdInput,hStdOutput,hStdError ; NOTE: This is for process creation info. Also, not sure if the Std I/O can be redirected..? #ce $stStartupInfo = DllStructCreate("dword;ptr[3];dword[7];dword;word;word;ptr;handle[3]") DllStructSetData($stStartupInfo, 1, DllStructGetSize($stStartupInfo)) DllStructSetData($stStartupInfo, 4, 1) ; STARTF_USESHOWWINDOW DllStructSetData($stStartupInfo, 5, $iShowFlag) ; PROCESS_INFORMATION struct: hProcess, hThread, dwProcessId, dwThreadId ; This is for *receiving* info $stProcInfo = DllStructCreate("handle;handle;dword;dword") ;~ Open a handle to the Process ; Explorer runs under a lower privilege, so it is the basis for our security info. ; Open the process with PROCESS_QUERY_INFORMATION (0x0400) access $aRet = DllCall("kernel32.dll", "handle", "OpenProcess", "dword", 0x0400, "bool", False, "dword", ProcessExists("explorer.exe")) If @error Then Return SetError(2, @error, 0) If Not $aRet[0] Then Return SetError(3, 0, 0) $hProcess = $aRet[0] ;~ Open a handle to the Process's token (for duplication) ; TOKEN_DUPLICATE = 0x0002 $aRet = DllCall("advapi32.dll", "bool", "OpenProcessToken", "handle", $hProcess, "dword", 2, "handle*", 0) If @error Then Return SetError(_RWRPCleanup($hProcess, 0, 0, 2, @error), @extended, 0) If $aRet[0] = 0 Then Return SetError(_RWRPCleanup($hProcess, 0, 0, 3), @extended, 0) $hToken = $aRet[3] ;~ Duplicate the token handle ; TOKEN_ALL_ACCESS = 0xF01FF, SecurityImpersonation = 2, TokenPrimary = 1, $aRet = DllCall("advapi32.dll", "bool", "DuplicateTokenEx", "handle", $hToken, "dword", 0xF01FF, "ptr", 0, "int", 2, "int", 1, "handle*", 0) If @error Then Return SetError(_RWRPCleanup($hProcess, $hToken, 0, 2, @error), @extended, 0) If Not $aRet[0] Then Return SetError(_RWRPCleanup($hProcess, $hToken, 0, 3), @extended, 0) $hDupToken = $aRet[6] ;~ Create the process using 'CreateProcessWithTokenW' (Vista+ O/S function) $aRet = DllCall("advapi32.dll", "bool", "CreateProcessWithTokenW", "handle", $hDupToken, "dword", 0, "wstr", $sPath, $sCmdType, $sCmd, _ "dword", 0, "ptr", 0, $sFolderType, $sFolder, "ptr", DllStructGetPtr($stStartupInfo), "ptr", DllStructGetPtr($stProcInfo)) $iErr = @error _RWRPCleanup($hProcess, $hToken, $hDupToken, 2, @error) If $iErr Then Return SetError(2, $iErr, 0) If Not $aRet[0] Then Return SetError(3, 0, 0) ;~ MsgBox(0,"Info","Process info data: Process handle:"&DllStructGetData($stProcInfo,1)&", Thread handle:"&DllStructGetData($stProcInfo,2)& _ ;~ ", Process ID:"&DllStructGetData($stProcInfo,3)&", Thread ID:"&DllStructGetData($stProcInfo,4)&@CRLF) $iRet = DllStructGetData($stProcInfo, 3) ; Process ID ;~ If called in 'RunWait' style, wait for the process to close If $bWait Then ProcessWaitClose($iRet) $iRet = @extended ; Exit code EndIf ;~ Close Thread and then Process handles (order here is important): _RWRPCleanup(0, DllStructGetData($stProcInfo, 2), DllStructGetData($stProcInfo, 1), 0) Return $iRet EndFunc ;==>_RunWithReducedPrivileges ; =================================================================================================================== ; Func _RWRPCleanup($hProcess,$hToken,$hDupToken,$iErr=0,$iExt=0) ; ; INTERNAL: Helper function for _RunWithReducedPrivileges() ; ; Author: Ascend4nt ; =================================================================================================================== Func _RWRPCleanup($hProcess, $hToken, $hDupToken, $iErr = 0, $iExt = 0) Local $aHandles[3] = [$hToken, $hDupToken, $hProcess] ; order is important For $i = 0 To 2 If $aHandles[$i] <> 0 Then DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $aHandles[$i]) Next Return SetExtended($iExt, $iErr) EndFunc ;==>_RWRPCleanupEnjoy and Best Regards Edited June 10, 2011 by KaFu OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
CarlMontgomery Posted January 20, 2011 Share Posted January 20, 2011 This is great! I just now had a script that needs to do this and like magic this appeared. Pity it has to restart the app but thats still workable. I just write the variables i'm currently using to a file and have the script look for the file on next start. Picks up right where it left off. Thanks KaFu Link to comment Share on other sites More sharing options...
wanghong Posted May 19, 2011 Share Posted May 19, 2011 Hello! I am here to run DeElevate wrong. Can you help me? Thank you. my system:Win7Sp1 X86 Ultimate Link to comment Share on other sites More sharing options...
KaFu Posted May 19, 2011 Author Share Posted May 19, 2011 The error-code 3 comes from the _RunWithReducedPrivileges UDF by Ascend4nt. "@error = 3 = API returned failure. Call 'GetLastError' API function to get more info." I added this line: If $iError Then $iError &= @CRLF & _WinAPI_GetLastError() & @CRLF & _WinAPI_GetLastErrorMessage() Check the extended error message and ask Ascend4nt in the _RunWithReducedPrivileges() post mentioned above ... expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_res_requestedExecutionLevel=asInvoker #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #Region ;**** Directives created by AutoIt3Wrapper_GUI ****s #include <GUIButton.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <Winapi.au3> $sTitle = "UAC Elevate and DeElevate Example" If StringRegExp(@OSVersion, "_(XP|200(0|3))") Then MsgBox(16 + 262144, $sTitle, "Example only works for Vista+ OSs") Exit ElseIf Not @Compiled Then MsgBox(16 + 262144, $sTitle, "Example only works compiled") Exit EndIf $hGui = GUICreate($sTitle, 340, 90, Default, Default, Default, $WS_EX_TOPMOST) If IsAdmin() Then GUICtrlCreateLabel("Script is running in elevated mode (with admin rights)", 10, 10, 320, 20, $SS_CENTER) Else GUICtrlCreateLabel("Script is not running in elevated mode (with standard user rights)", 10, 10, 320, 20, $SS_CENTER) EndIf $c_Btn_Elevate = GUICtrlCreateButton("Elevate Script", 25, 30, 130, 30) If IsAdmin() Then GUICtrlSetState(-1, $GUI_DISABLE) _GUICtrlButton_SetShield(GUICtrlGetHandle($c_Btn_Elevate)) $c_Btn_DeElevate = GUICtrlCreateButton("Remove Elevation", 165, 30, 130, 30) If Not IsAdmin() Then GUICtrlSetState(-1, $GUI_DISABLE) $c_ChkB_Elavate_Always = GUICtrlCreateCheckbox("Auto-Elevate script on Start", 25, 65) GUICtrlSetTip(-1, "Checking this box will add an ""Application Compatibility Flag"" to the registry at" & @CRLF & @CRLF & _ "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" & @CRLF & @CRLF & _ ",adding the executable URL as the Key with the value RUNASADMIN." & @CRLF & @CRLF & _ "Before moving or deleting the script make sure that the checkbox is unchecked (the registry" & @CRLF & _ "key is deleted) to not produce an orphaned RegKey.", "Auto-Elevate", 1, 1) If Not IsAdmin() Then GUICtrlSetState(-1, $GUI_DISABLE) Else If RegRead("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers", @ScriptFullPath) = "RUNASADMIN" Then GUICtrlSetState(-1, $GUI_CHECKED) EndIf GUISetState(@SW_SHOW) While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $c_Btn_Elevate If ShellExecute(@ScriptName, "", "", "runas") Then Exit Else MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong, you canceled the UAC prompt?") EndIf Case $c_Btn_DeElevate $iPID = _RunWithReducedPrivileges(@ScriptName, "", @ScriptDir) $iError = @error If $iError Then $iError &= @CRLF & _WinAPI_GetLastError() & @CRLF & _WinAPI_GetLastErrorMessage() If ProcessExists($iPID) Then Exit Else MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong..." & @CRLF & "Error code: " & $iError) EndIf Case $c_ChkB_Elavate_Always $sRegString = "HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Switch GUICtrlRead($c_ChkB_Elavate_Always) Case 1 If Not RegWrite("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers", @ScriptFullPath, "REG_SZ", "RUNASADMIN") Then MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong, could not write AppCompatFlag to Registry.") GUICtrlSetState($c_ChkB_Elavate_Always, $GUI_UNCHECKED) Else MsgBox(16 + 262144, $sTitle, "RUNASADMIN added.") EndIf Case Else If Not RegDelete("HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers", @ScriptFullPath) Then MsgBox(16 + 262144, $sTitle & " - Error", "Something went wrong, could not write AppCompatFlag to Registry.") GUICtrlSetState($c_ChkB_Elavate_Always, $GUI_UNCHECKED) Else MsgBox(16 + 262144, $sTitle & " - Error", "RUNASADMIN removed.") EndIf EndSwitch EndSwitch WEnd Exit ; =============================================================================================================================== ; <_RunWithReducedPrivileges.au3> ; ; Function to run a program with reduced privileges. ; Useful when running in a higher privilege mode, but need to start a program with reduced privileges. ; - A common problem this fixes is drag-and-drop not working, and misc functions (sendmessage, etc) not working. ; ; Functions: ; _RunWithReducedPrivileges() ; runs a process with reduced privileges if currently running in a higher privilege mode ; ; INTERNAL Functions: ; _RWRPCleanup() ; Helper function for the above ; ; Reference: ; See 'Creating a process with Medium Integration Level from the process with High Integration Level in Vista' ; @ http://www.codeproject.com/KB/vista-security/createprocessexplorerleve.aspx ; See Elmue's comment 'Here the cleaned and bugfixed code' ; Also see: 'High elevation can be bad for your application: How to start a non-elevated process at the end of the installation' ; @ http://www.codeproject.com/KB/vista-security/RunNonElevated.aspx ; (Elmue has the same code here too in his response to FaxedHead's comment ('Another alternative to this method')) ; Another alternative using COM methods: ; 'Getting the shell to run an application for you - Part 2:How | BrandonLive' ; @ http://brandonlive.com/2008/04/27/gettin...o-run-an-application-for-you-p ; ; Author: Ascend4nt, based on code by Elmue's fixed version of Alexey Gavrilov's code ; =============================================================================================================================== ; =================================================================================================================== ; Func _RunWithReducedPrivileges($sPath,$sCmd='',$sFolder='',$iShowFlag=@SW_SHOWNORMAL,$bWait=False) ; ; Function to run a program with reduced privileges. ; Useful when running in a higher privilege mode, but need to start a program with reduced privileges. ; - A common problem this fixes is drag-and-drop not working, and misc functions (sendmessage, etc) not working. ; ; $sPath = Path to executable ; $sCmd = Command-line (optional) ; $sFolder = Folder to start in (optional) ; $iShowFlag = how the program should appear on startup. Default is @SW_SHOWNORMAL. ; All the regular @SW_SHOW* macros should work here ; $bWait = If True, waits for the process to finish before returning with an exit code ; If False, it returns without waiting for the process to finish, with the process ID # ; ; Returns: ; Success: If $bWait=True, the exit code of the Process. If $bWait=False, then the Process ID # of the process ; Failure: 0, with @error set: ; @error = 2 = DLLCall error. @extended contains the DLLCall error code (see AutoIt Help) ; @error = 3 = API returned failure. Call 'GetLastError' API function to get more info. ; ; Author: Ascend4nt, based on code by Elmue's fixed version of Alexey Gavrilov's code ; =================================================================================================================== Func _RunWithReducedPrivileges($sPath, $sCmd = '', $sFolder = '', $iShowFlag = @SW_SHOWNORMAL, $bWait = False) Local $aRet, $iErr, $iRet = 1, $hProcess, $hToken, $hDupToken, $stStartupInfo, $stProcInfo Local $sCmdType = "wstr", $sFolderType = "wstr" ;~ Run normally if not in an elevated state, or if pre-Vista O/S If Not IsAdmin() Or StringRegExp(@OSVersion, "_(XP|200(0|3))") Then ; XP, XPe, 2000, or 2003? If $bWait Then Return RunWait($sPath & ' ' & $sCmd, $sFolder) Return Run($sPath & ' ' & $sCmd, $sFolder) EndIf ;~ Check Parameters and adjust DLLCall types accordingly If Not IsString($sCmd) Or $sCmd = '' Then $sCmdType = "ptr" $sCmd = 0 EndIf If Not IsString($sFolder) Or $sFolder = '' Then $sFolderType = "ptr" $sFolder = 0 EndIf #cs ; STARTUPINFOW struct: cb,lpReserved,lpDesktop,lpTitle,dwX,dwY,dwXSize,dwYSize,dwXCountChars,dwYCountChars,dwFillAttribute, ; dwFlags,wShowWindow,cbReserved2,lpReserved2,hStdInput,hStdOutput,hStdError ; NOTE: This is for process creation info. Also, not sure if the Std I/O can be redirected..? #ce $stStartupInfo = DllStructCreate("dword;ptr[3];dword[7];dword;word;word;ptr;handle[3]") DllStructSetData($stStartupInfo, 1, DllStructGetSize($stStartupInfo)) DllStructSetData($stStartupInfo, 4, 1) ; STARTF_USESHOWWINDOW DllStructSetData($stStartupInfo, 5, $iShowFlag) ; PROCESS_INFORMATION struct: hProcess, hThread, dwProcessId, dwThreadId ; This is for *receiving* info $stProcInfo = DllStructCreate("handle;handle;dword;dword") ;~ Open a handle to the Process ; Explorer runs under a lower privilege, so it is the basis for our security info. ; Open the process with PROCESS_QUERY_INFORMATION (0x0400) access $aRet = DllCall("kernel32.dll", "handle", "OpenProcess", "dword", 0x0400, "bool", False, "dword", ProcessExists("explorer.exe")) If @error Then Return SetError(2, @error, 0) If Not $aRet[0] Then Return SetError(3, 0, 0) $hProcess = $aRet[0] ;~ Open a handle to the Process's token (for duplication) ; TOKEN_DUPLICATE = 0x0002 $aRet = DllCall("advapi32.dll", "bool", "OpenProcessToken", "handle", $hProcess, "dword", 2, "handle*", 0) If @error Then Return SetError(_RWRPCleanup($hProcess, 0, 0, 2, @error), @extended, 0) If $aRet[0] = 0 Then Return SetError(_RWRPCleanup($hProcess, 0, 0, 3), @extended, 0) $hToken = $aRet[3] ;~ Duplicate the token handle ; TOKEN_ALL_ACCESS = 0xF01FF, SecurityImpersonation = 2, TokenPrimary = 1, $aRet = DllCall("advapi32.dll", "bool", "DuplicateTokenEx", "handle", $hToken, "dword", 0xF01FF, "ptr", 0, "int", 2, "int", 1, "handle*", 0) If @error Then Return SetError(_RWRPCleanup($hProcess, $hToken, 0, 2, @error), @extended, 0) If Not $aRet[0] Then Return SetError(_RWRPCleanup($hProcess, $hToken, 0, 3), @extended, 0) $hDupToken = $aRet[6] ;~ Create the process using 'CreateProcessWithTokenW' (Vista+ O/S function) $aRet = DllCall("advapi32.dll", "bool", "CreateProcessWithTokenW", "handle", $hDupToken, "dword", 0, "wstr", $sPath, $sCmdType, $sCmd, _ "dword", 0, "ptr", 0, $sFolderType, $sFolder, "ptr", DllStructGetPtr($stStartupInfo), "ptr", DllStructGetPtr($stProcInfo)) $iErr = @error _RWRPCleanup($hProcess, $hToken, $hDupToken, 2, @error) If $iErr Then Return SetError(2, $iErr, 0) If Not $aRet[0] Then Return SetError(3, 0, 0) ;~ MsgBox(0,"Info","Process info data: Process handle:"&DllStructGetData($stProcInfo,1)&", Thread handle:"&DllStructGetData($stProcInfo,2)& _ ;~ ", Process ID:"&DllStructGetData($stProcInfo,3)&", Thread ID:"&DllStructGetData($stProcInfo,4)&@CRLF) $iRet = DllStructGetData($stProcInfo, 3) ; Process ID ;~ If called in 'RunWait' style, wait for the process to close If $bWait Then ProcessWaitClose($iRet) $iRet = @extended ; Exit code EndIf ;~ Close Thread and then Process handles (order here is important): _RWRPCleanup(0, DllStructGetData($stProcInfo, 2), DllStructGetData($stProcInfo, 1), 0) Return $iRet EndFunc ;==>_RunWithReducedPrivileges ; =================================================================================================================== ; Func _RWRPCleanup($hProcess,$hToken,$hDupToken,$iErr=0,$iExt=0) ; ; INTERNAL: Helper function for _RunWithReducedPrivileges() ; ; Author: Ascend4nt ; =================================================================================================================== Func _RWRPCleanup($hProcess, $hToken, $hDupToken, $iErr = 0, $iExt = 0) Local $aHandles[3] = [$hToken, $hDupToken, $hProcess] ; order is important For $i = 0 To 2 If $aHandles[$i] <> 0 Then DllCall("kernel32.dll", "bool", "CloseHandle", "handle", $aHandles[$i]) Next Return SetExtended($iExt, $iErr) EndFunc ;==>_RWRPCleanup mLipok 1 OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
wanghong Posted May 19, 2011 Share Posted May 19, 2011 Hello KaFu! I'm sorry to bother you I come from China my English is poor, on the api do not know Just run your script the results are: Something went wrong... Error code: 3 1058 Can not start service, probably due to have been disabled or no enabled devices associated. I found the problem here: (204 lines) $aRet = DllCall("advapi32.dll", "bool", "CreateProcessWithTokenW", "handle", $hDupToken, "dword", 0, "wstr", $sPath, $sCmdType, $sCmd, _ "dword", 0, "ptr", 0, $sFolderType, $sFolder, "ptr", DllStructGetPtr($stStartupInfo), "ptr", DllStructGetPtr($stProcInfo)) >>$aRet[0]=0 Link to comment Share on other sites More sharing options...
KaFu Posted May 19, 2011 Author Share Posted May 19, 2011 Hi wanghong, your English is quite good , no problem to understand you. Googeling the error message brought me to this page: http://powerpivotgeek.com/2010/10/24/snapshots-not-being-taken/ "The error 1058 can have as a root cause the fact the Windows service “Secondary Logon” is disabled. The service as to be at least in manual (the service will be started by the call to CreateProcessWithToken if the permissions permit it)." Please check if the "Secondary Logon" service is running on your computer. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
wanghong Posted May 19, 2011 Share Posted May 19, 2011 Really problem is the "Secondary Logon" services, When turn on "Secondary Logon" service to normal. In addition to gratitude, to you recommend: http://www.shenyunperformingarts.org/?lang=en-us http://www.shenyunperformingarts.org/reviews If you where there, Be sure to see. You will never regret it. Link to comment Share on other sites More sharing options...
Yashied Posted May 19, 2011 Share Posted May 19, 2011 Why not just use #AutoIt3Wrapper_Res_RequestedExecutionLevel? My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More... Link to comment Share on other sites More sharing options...
KaFu Posted May 20, 2011 Author Share Posted May 20, 2011 Because of the restrictions enfored by that directive. UAC Elevation GUI Triggered Works for NonAdmin Can obtain Admin rights requestedExecutionLevel=asAdmin Yes Never Always requestedExecutionLevel=asInvoker No Always Never Method above No - but can be triggered Always Always OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Yashied Posted May 20, 2011 Share Posted May 20, 2011 I use "highestAvailable". My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More... Link to comment Share on other sites More sharing options...
KaFu Posted May 20, 2011 Author Share Posted May 20, 2011 This will work like AsAdmin if your account has admin rights and AsInvoker if your account has no admin rights. So if your Admin it will always trigger UAC elevation, the same restrictions as described above are still in place, only that they are not linked to the program but to your account rights. OS: Win10-22H2 - 64bit - German, AutoIt Version: 3.3.16.1, AutoIt Editor: SciTE, Website: https://funk.eu AMT - Auto-Movie-Thumbnailer (2024-Oct-13) BIC - Batch-Image-Cropper (2023-Apr-01) COP - Color Picker (2009-May-21) DCS - Dynamic Cursor Selector (2024-Oct-13) HMW - Hide my Windows (2024-Oct-19) HRC - HotKey Resolution Changer (2012-May-16) ICU - Icon Configuration Utility (2018-Sep-16) SMF - Search my Files (2024-Oct-20) - THE file info and duplicates search tool SSD - Set Sound Device (2017-Sep-16) Link to comment Share on other sites More sharing options...
Yashied Posted May 20, 2011 Share Posted May 20, 2011 (edited) UAC Elevation GUI Triggered Works for NonAdmin Can obtain Admin rights requestedExecutionLevel=asAdmin Yes Never Always requestedExecutionLevel=asInvoker No Always Never requestedExecutionLevel=highestAvailable Yes - Admin, No - Limited Always Never Method above No - but can be triggered Always Always For example, "highestAvailable" uses a regedit32.exe. To obtain an Admin rights, you can always use "Run as administrator..." context menu. Edited May 20, 2011 by Yashied My UDFs: iKey | FTP Uploader | Battery Checker | Boot Manager | Font Viewer | UDF Keyword Manager | Run Dialog Replacement | USBProtect | 3D Axis | Calculator | Sleep | iSwitcher | TM | NetHelper | File Types Manager | Control Viewer | SynFolders | DLL Helper Animated Tray Icons UDF Library | Hotkeys UDF Library | Hotkeys Input Control UDF Library | Caret Shape UDF Library | Context Help UDF Library | Most Recently Used List UDF Library | Icons UDF Library | FTP UDF Library | Script Communications UDF Library | Color Chooser UDF Library | Color Picker Control UDF Library | IPHelper (Vista/7) UDF Library | WinAPI Extended UDF Library | WinAPIVhd UDF Library | Icon Chooser UDF Library | Copy UDF Library | Restart UDF Library | Event Log UDF Library | NotifyBox UDF Library | Pop-up Windows UDF Library | TVExplorer UDF Library | GuiHotKey UDF Library | GuiSysLink UDF Library | Package UDF Library | Skin UDF Library | AITray UDF Library | RDC UDF Library Appropriate path | Button text color | Gaussian random numbers | Header's styles (Vista/7) | ICON resource enumeration | Menu & INI | Tabbed string size | Tab's skin | Pop-up circular menu | Progress Bar without animation (Vista/7) | Registry export | Registry path jumping | Unique hardware ID | Windows alignment More... Link to comment Share on other sites More sharing options...
Ascend4nt Posted May 20, 2011 Share Posted May 20, 2011 (edited) There are always good reasons to limit or expand what a script or program can do..For example: An installer must be elevated, but should probably run the installed program at a lower privilege level. If not, the app won't be able to be interacted with from other lower-privilege level applications- not in full, anyway. Things like drag-and-drop will fail to work.On the flip-side, a script or program might need to be able to run for both a regular user and an admin-level user, and only switch to an elevated mode when working with certain system elements (that a regular user shouldn't be allowed to work with). Then an elevation prompt can be provided, at which point the script/program can restart itself. For example, Task Manager will run unelevated and re-runs itself only when certain buttons are pressed ("Show processes from all users" for example). Note that, since taskmgr.exe is in the 'whitelist', you won't see a UAC prompt on the lower UAC settings in Windows 7. However, you can clearly see it is restarted.*edit: clarification Edited May 20, 2011 by Ascend4nt My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
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