Code: Select all
RunAsNetOnly(lpUsername,lpDomain,lpPassword,lpCommandLine,lpCurrentDirectory="%windir%",wShowWindow=0)
{
;DO NOT DEFINE INVALID DIRECTORY NAME OR ENVIRONMENT VARIABLE FOR lpCurrentDirectory
;WILL CAUSE failure and A_LastError to be non-zero (likely 123 or 267)
IfInString, lpUsername, \
{
unArray := StrSplit(lpUsername,"\")
lpUsername := unArray[2]
lpDomain := unArray[1]
}
RegexMatch(lpCurrentDirectory,"O)(%.*?%)",Match)
Needle := Match.Value(1)
If (Needle <> "")
{
StringReplace, EnvVar, Needle, `%,, All ;%;end variable color in npp
EnvGet, EnvVar2, %EnvVar%
StringReplace, lpCurrentDirectory, lpCurrentDirectory, %Needle%, %EnvVar2%
}
;ahk tutorial on structures - http://maul-esel.github.io/ahkbook/en/Structures.html
;stdOutToVar modified from from https://autohotkey.com/board/topic/96903-simplified-versions-of-seans-stdouttovar/
;4 (bytes) used for DWORD arguments, A_PtrSize used for all other ptr arguments
;https://msdn.microsoft.com/en-us/library/windows/desktop/aa365152(v=vs.85).aspx
DllCall("CreatePipe", "UIntP", hPipeRead, "UIntP", hPipeWrite, "UInt", 0, "UInt", 0)
;https://msdn.microsoft.com/en-us/library/windows/desktop/ms724935(v=vs.85).aspx
DllCall("SetHandleInformation", "UIntP", hPipeWrite, "UInt", 1, "UInt", 1)
;Process_Information STRUCT - https://msdn.microsoft.com/en-us/library/ms684873(v=vs.85).aspx
piSize := 4+4+(2*A_PtrSize)
VarSetCapacity(lpProcessInfo,piSize)
;StartupInfo STRUCT - https://msdn.microsoft.com/en-us/library/ms686331(v=vs.85).aspx
siSize := (9*4)+(9*A_PtrSize)
VarSetCapacity(lpStartupInfo,siSize)
NumPut(siSize,lpStartupInfo,0,"UInt")
dwFlagsOffset := (9*4)+(3*A_PtrSize)
;to set the next flag active and activate std handles
NumPut(0x00000101,lpStartupInfo,dwFlagsOffset,"UInt")
wShowWindowOffset := dwFlagsOffset + 4
;1=normal window, 0=hide window - https://msdn.microsoft.com/en-us/library/ms633548(v=vs.85).aspx
NumPut(wShowWindow,lpStartupInfo,wShowWindowOffset,"UInt")
hStdOutputOffset := wShowWindowOffset + (3*A_PtrSize)
NumPut(hPipeWrite,lpStartupInfo,hStdOutputOffset)
hStdErrorOffset := hStdOutputOffset + A_PtrSize
NumPut(hPipeWrite,lpStartupInfo,hStdErrorOffset)
;https://msdn.microsoft.com/en-us/library/windows/desktop/ms682431(v=vs.85).aspx
Result := DllCall("advapi32\CreateProcessWithLogonW"
,"Str", lpUsername
,"Str", lpDomain
,"Str", lpPassword
,"UInt", 2 ;dwLogonFlags
,"Ptr", 0 ;lpApplicationName
,"Str", lpCommandLine
,"UInt", 0 ;dwCreationFlags
,"Ptr", 0 ;lpEnvironment
,"Str", lpCurrentDirectory
,"UPtr", &lpStartupInfo
,"UPtr", &lpProcessInfo
,"UInt")
createProcessErrorLevel := ErrorLevel
hProcess := NumGet(lpProcessInfo,0,"UInt")
hThreadOffset := 0+A_PtrSize
hThread := NumGet(lpProcessInfo,hThreadOffset,"UInt")
dwProcessIdOffset := hThreadOffset+A_PtrSize
dwProcessId := NumGet(lpProcessInfo,dwProcessIdOffset,"UInt")
dwThreadIdOffset := dwProcessId+4
dwThreadId := NumGet(lpProcessInfo,dwThreadIdOffset,"UInt")
If (dwProcessId = 0)
{
If (A_LastError = 2)
msgReturn := "System Error Code: 2`nFile Does Not Exist"
Else If (A_LastError = 123)
msgReturn := "System Error Code: 123`nThe filename, directory name, or volume label syntax is incorrect."
Else If (A_LastError = 267)
msgReturn := "System Error Code: 267`nPath Does Not Exist"
Else If (A_LastError = -1073741819)
msgReturn := "Error Number: 0xc0000005`nAccess Violation"
Else
msgReturn := "System Error Code:" . A_LastError
}
Else
{
Process, WaitClose, dwProcessId, 10
DllCall("CloseHandle","Ptr",hPipeWrite)
If (createProcessErrorLevel = 0)
{
;grab stdOut
;stdOutToVar modified from from https://autohotkey.com/board/topic/96903-simplified-versions-of-seans-stdouttovar/
stdOutput := "", bytesRead := 0
AIC := (SubStr(A_AhkVersion,1,3) = "1.0")
VarSetCapacity(Buffer,4096,0)
While DllCall("ReadFile", "UInt", hPipeRead, "Ptr", &Buffer, "UInt", 4094, "UIntP", bytesRead, "Ptr", 0, "UInt")
stdOutput .= (AIC && NumPut(0,Buffer,bytesRead,"UChar") && VarSetCapacity(Buffer,-1)) ? Buffer : StrGet(&Buffer,bytesRead,"CP850") ;maybe ? change CP850 to UTF-8 or UTF-16
}
Else
{
;end process that was started
Process, Exist, %dwProcessId%
ProcessEL := ErrorLevel
If (ProcessEL <> 0)
RunWait, %comspec% /c taskkill.exe /f /pid %dwProcessId%,, Hide, UseErrorLevel
}
}
}
;clean-up
DllCall("CloseHandle","Ptr",hProcess)
DllCall("CloseHandle","Ptr",hThread)
DllCall("CloseHandle","Ptr",hPipeRead)
VarSetCapacity(lpProcessInfo,0)
VarSetCapacity(lpStartupInfo,0)
returnObj := {}
returnObj.msgReturn := msgReturn
returnObj.stdOutput := stdOutput
Return returnObj
}