Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

StdoutToVar


  • Please log in to reply
121 replies to this topic
segalion
  • Members
  • 50 posts
  • Last active: Oct 16 2014 09:20 AM
  • Joined: 02 Feb 2011
Finally the class/object version...

Maybe, the comparison between this code (object oriented) and the above (not oo) can help newbies like me to understand some concepts of this kind of programming

And PLEASE:
This is a call to experts in object/class and experts in console and unicode stuff to help to test and improve this little code...


class cli {
    __New(sCmd, sDir="") {
      DllCall("CreatePipe","Ptr*",hStdInRd,"Ptr*",hStdInWr,"Uint",0,"Uint",0)
      DllCall("CreatePipe","Ptr*",hStdOutRd,"Ptr*",hStdOutWr,"Uint",0,"Uint",0)
      DllCall("SetHandleInformation","Ptr",hStdInRd,"Uint",1,"Uint",1)
      DllCall("SetHandleInformation","Ptr",hStdOutWr,"Uint",1,"Uint",1)
      if (A_PtrSize=4) {
         VarSetCapacity(pi, 16, 0)
         sisize:=VarSetCapacity(si,68,0)
         NumPut(sisize, si,  0, "UInt"), NumPut(0x100, si, 44, "UInt"),NumPut(hStdInRd , si, 56, "Ptr"),NumPut(hStdOutWr, si, 60, "Ptr"),NumPut(hStdOutWr, si, 64, "Ptr")
         }
      else if (A_PtrSize=8) {
         VarSetCapacity(pi, 24, 0)
         sisize:=VarSetCapacity(si,96,0)
         NumPut(sisize, si,  0, "UInt"),NumPut(0x100, si, 60, "UInt"),NumPut(hStdInRd , si, 80, "Ptr"),NumPut(hStdOutWr, si, 88, "Ptr"), NumPut(hStdOutWr, si, 96, "Ptr")
         }
      DllCall("CreateProcess", "Uint", 0, "Ptr", &sCmd, "Uint", 0, "Uint", 0, "Int", True, "Uint", 0x08000000, "Uint", 0, "Ptr", sDir ? &sDir : 0, "Ptr", &si, "Ptr", &pi)
      DllCall("CloseHandle","Ptr",NumGet(pi,0))
      DllCall("CloseHandle","Ptr",NumGet(pi,A_PtrSize))
      DllCall("CloseHandle","Ptr",hStdOutWr)
      DllCall("CloseHandle","Ptr",hStdInRd)
         ; Create an object.
      this.hStdInWr:= hStdInWr, this.hStdOutRd:= hStdOutRd
       }
    __Delete() {
        this.close()
    }
    close() {
       hStdInWr:=this.hStdInWr
       hStdOutRd:=this.hStdOutRd
       DllCall("CloseHandle","Ptr",hStdInWr)
       DllCall("CloseHandle","Ptr",hStdOutRd)
      }
   stdin(sInput="",codepage="")  {
       hStdInWr:=this.hStdInWr
       if (codepage="")
            codepage:=A_FileEncoding
         If   sInput <>
         FileOpen(hStdInWr, "h", codepage).Write(sInput)
      }
   stdout(chars="",codepage="") {
       hStdOutRd:=this.hStdOutRd
       if (codepage="")
            codepage:=A_FileEncoding
       fout:=FileOpen(hStdOutRd, "h", codepage)
       if (IsObject(fout) and fout.AtEOF=0)
         return fout.Read()
      return ""
      }
}

;The example using the code to comunicate with commandline apps...

FileEncoding, CP850
netsh:= new cli("netsh.exe")
;msgbox % "hStdInWr=" netsh.hStdInWr "`thStdOutRd=" netsh.thStdOutRd
sleep 300
netsh.stdin("firewall`r`n")
sleep 100
netsh.stdin("show config`r`n")
sleep 1000
out:=netsh.stdout()
msgbox,, FIREWALL CONFIGURATION:, %out%
netsh.stdin("bye`r`n")
netsh.close() 


irontomato
  • Members
  • 64 posts
  • Last active: Jul 17 2015 06:23 PM
  • Joined: 23 Jun 2008
So this might be totally newb, but how do you use this class?

I tried using another example "ConsoleApp.ahk" but it doesn't work at all. Fails instantly.

I tried dropping your class and example code into an AHK file but that doesn't appear to work. Looks like the class needs to be placed somewhere else, but I'm not familiar with how to do this in AutoHotKey. Any help for a newb?

segalion
  • Members
  • 50 posts
  • Last active: Oct 16 2014 09:20 AM
  • Joined: 02 Feb 2011

So this might be totally newb, but how do you use this class?
....


Sorry. I haven´t indicate that this code is only for AHK_L (an advanced version of AHK).
This is an old post prior to last chage in forum, that has AHK and AHK_L mixed code.

Probably is better to open a new post in custom forum... I will try when I have the code well tested...

Thanks.

stephenp1983
  • Members
  • 41 posts
  • Last active: Jul 02 2014 03:19 AM
  • Joined: 12 Mar 2012
Does anyone know of a way to use a variable within the specified command of this function? Example I have an edit box where a user would specific a remote machine name which is stored in the %compname% variable. When I include it in the command below it appears to run tasklist /s %compname% instead of tasklist /s actualmachinename

MsgBox % sOutput := StdoutToVar_CreateProcess("tasklist /s %compname%")

BTW thanks for this function, its worked great in my other uses.

  • Guests
  • Last active:
  • Joined: --
This would be my guess MsgBox % sOutput := StdoutToVar_CreateProcess("tasklist /s " compname) (remove the %% and move it out of the ""

stephenp1983
  • Members
  • 41 posts
  • Last active: Jul 02 2014 03:19 AM
  • Joined: 12 Mar 2012

This would be my guess MsgBox % sOutput := StdoutToVar_CreateProcess("tasklist /s " compname) (remove the %% and move it out of the ""


I changed it to MsgBox % sOutput := StdoutToVar_CreateProcess("tasklist /s " compname) and get an invalid syntax associated with the tasklist command itself.

Thanks for the suggestion though. Below is the function in case anyone else has some input so they dont have to scroll through the entire thread.

StdoutToVar_CreateProcess(sCmd, bStream = False, sDir = "", sInput = "")
{
	DllCall("CreatePipe", "UintP", hStdInRd , "UintP", hStdInWr , "Uint", 0, "Uint", 0)
	DllCall("CreatePipe", "UintP", hStdOutRd, "UintP", hStdOutWr, "Uint", 0, "Uint", 0)
	DllCall("SetHandleInformation", "Uint", hStdInRd , "Uint", 1, "Uint", 1)
	DllCall("SetHandleInformation", "Uint", hStdOutWr, "Uint", 1, "Uint", 1)
	VarSetCapacity(pi, 16, 0)
	NumPut(VarSetCapacity(si, 68, 0), si)	; size of si
	NumPut(0x100	, si, 44)		; STARTF_USESTDHANDLES
	NumPut(hStdInRd	, si, 56)		; hStdInput
	NumPut(hStdOutWr, si, 60)		; hStdOutput
	NumPut(hStdOutWr, si, 64)		; hStdError
	If Not	DllCall("CreateProcess", "Uint", 0, "Uint", &sCmd, "Uint", 0, "Uint", 0, "int", True, "Uint", 0x08000000, "Uint", 0, "Uint", sDir ? &sDir : 0, "Uint", &si, "Uint", &pi)	; bInheritHandles and CREATE_NO_WINDOW
		ExitApp
	DllCall("CloseHandle", "Uint", NumGet(pi,0))
	DllCall("CloseHandle", "Uint", NumGet(pi,4))
	DllCall("CloseHandle", "Uint", hStdOutWr)
	DllCall("CloseHandle", "Uint", hStdInRd)
	If	sInput <>
	DllCall("WriteFile", "Uint", hStdInWr, "Uint", &sInput, "Uint", StrLen(sInput), "UintP", nSize, "Uint", 0)
	DllCall("CloseHandle", "Uint", hStdInWr)
	bStream ? (bAlloc:=DllCall("AllocConsole"),hCon:=DllCall("CreateFile","str","CON","Uint",0x40000000,"Uint",bAlloc ? 0 : 3,"Uint",0,"Uint",3,"Uint",0,"Uint",0)) : ""
	VarSetCapacity(sTemp, nTemp:=bStream ? 64-nTrim:=1 : 4095)
	Loop
		If	DllCall("ReadFile", "Uint", hStdOutRd, "Uint", &sTemp, "Uint", nTemp, "UintP", nSize:=0, "Uint", 0)&&nSize
		{
			NumPut(0,sTemp,nSize,"Uchar"), VarSetCapacity(sTemp,-1), sOutput.=sTemp
			If	bStream&&hCon+1
				Loop
					If	RegExMatch(sOutput, "[^\n]*\n", sTrim, nTrim)
						DllCall("WriteFile", "Uint", hCon, "Uint", &sTrim, "Uint", StrLen(sTrim), "UintP", nSize:=0, "Uint", 0)&&nSize ? nTrim+=nSize : ""
					Else	Break
		}
		Else	Break
	DllCall("CloseHandle", "Uint", hStdOutRd)
	bStream ? (DllCall("Sleep","Uint",1000),hCon+1 ? DllCall("CloseHandle","Uint",hCon) : "",bAlloc ? DllCall("FreeConsole") : "") : ""
	Return	sOutput
}


HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
Works fine for me after a small change:
MsgBox % sOutput := StdoutToVar_CreateProcess("tasklist /s " A_ComputerName)



StdoutToVar_CreateProcess(sCmd, bStream = False, sDir = "", sInput = "")

{

   DllCall("CreatePipe", "UintP", hStdInRd , "UintP", hStdInWr , "Uint", 0, "Uint", 0)

   DllCall("CreatePipe", "UintP", hStdOutRd, "UintP", hStdOutWr, "Uint", 0, "Uint", 0)

   DllCall("SetHandleInformation", "Uint", hStdInRd , "Uint", 1, "Uint", 1)

   DllCall("SetHandleInformation", "Uint", hStdOutWr, "Uint", 1, "Uint", 1)

   VarSetCapacity(pi, 16, 0)

   NumPut(VarSetCapacity(si, 68, 0), si)   ; size of si

   NumPut(0x100   , si, 44)      ; STARTF_USESTDHANDLES

   NumPut(hStdInRd   , si, 56)      ; hStdInput

   NumPut(hStdOutWr, si, 60)      ; hStdOutput

   NumPut(hStdOutWr, si, 64)      ; hStdError

   If Not   DllCall("CreateProcess", "Uint", 0, "Uint", &sCmd, "Uint", 0, "Uint", 0, "int", True, "Uint", 0x08000000, "Uint", 0, "Uint", sDir ? &sDir : 0, "Uint", &si, "Uint", &pi)   ; bInheritHandles and CREATE_NO_WINDOW

      ExitApp

   DllCall("CloseHandle", "Uint", NumGet(pi,0))

   DllCall("CloseHandle", "Uint", NumGet(pi,4))

   DllCall("CloseHandle", "Uint", hStdOutWr)

   DllCall("CloseHandle", "Uint", hStdInRd)

   If   sInput <>

   DllCall("WriteFile", "Uint", hStdInWr, "Uint", &sInput, "Uint", StrLen(sInput), "UintP", nSize, "Uint", 0)

   DllCall("CloseHandle", "Uint", hStdInWr)

   bStream ? (bAlloc:=DllCall("AllocConsole"),hCon:=DllCall("CreateFile","str","CON","Uint",0x40000000,"Uint",bAlloc ? 0 : 3,"Uint",0,"Uint",3,"Uint",0,"Uint",0)) : ""

   VarSetCapacity(sTemp, nTemp:=bStream ? 64-nTrim:=1 : 4095)

   Loop

      If   DllCall("ReadFile", "Uint", hStdOutRd, "Uint", &sTemp, "Uint", nTemp, "UintP", nSize:=0, "Uint", 0)&&nSize

      {

         NumPut(0,sTemp,nSize,"Uchar"), VarSetCapacity(sTemp,-1), sOutput.=sTemp

         If   bStream&&hCon+1

            Loop

               If   RegExMatch(sOutput, "[^\n]*\n", sTrim, nTrim)

                  DllCall("WriteFile", "Uint", hCon, "Uint", &sTrim, "Uint", StrLen(sTrim), "UintP", nSize:=0, "Uint", 0)&&nSize ? nTrim+=nSize : ""

               Else   Break

      }

      Else   Break

   DllCall("CloseHandle", "Uint", hStdOutRd)

   bStream ? (DllCall("Sleep","Uint",1000),hCon+1 ? DllCall("CloseHandle","Uint",hCon) : "",bAlloc ? DllCall("FreeConsole") : "") : ""

   Return   [color=#BF0000]StrGet(&sOutput,"CP0")[/color]

}


stephenp1983
  • Members
  • 41 posts
  • Last active: Jul 02 2014 03:19 AM
  • Joined: 12 Mar 2012
Awesome, that worked great.

Can you expand on the change you made, and why that seems to have fixed my issue? From scanning through the two functions the difference I see is the last line - Return StrGet(&sOutput,"CP0") instead of just Return sOutput

Thanks for the help btw

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008
The text in sOutput is not Unicode but ANSI so we need to convert it.

stephenp1983
  • Members
  • 41 posts
  • Last active: Jul 02 2014 03:19 AM
  • Joined: 12 Mar 2012

The text in sOutput is not Unicode but ANSI so we need to convert it.

Thanks for the clarification

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006

The text in sOutput is not Unicode but ANSI so we need to convert it.

sOutput still gets its value from ordinary (potentially 16-bit) string concatenation: sOutput.=sTemp. That doesn't seem reliable...

Guest2
  • Guests
  • Last active:
  • Joined: --
emh.. :p the DOWNLOAD link at the begin of the post is broken https://ahknet.autoh...StdoutToVar.zip ... what is the right link? can someone update it to the right one? thanks 8-)

wnltl
  • Members
  • 8 posts
  • Last active: May 09 2013 01:20 PM
  • Joined: 12 Jun 2012

unicode version StdoutToVar is Good script!

 

Thanks!



Guest10
  • Members
  • 1216 posts
  • Last active: Oct 30 2015 05:12 PM
  • Joined: 27 Oct 2012

When I run the following, I get blank MsgBox.

MsgBox % sOutput := StdoutToVar_CreateProcess("tasklist /s " A_ComputerName)



StdoutToVar_CreateProcess(sCmd, bStream = False, sDir = "", sInput = "")

{

   DllCall("CreatePipe", "UintP", hStdInRd , "UintP", hStdInWr , "Uint", 0, "Uint", 0)

   DllCall("CreatePipe", "UintP", hStdOutRd, "UintP", hStdOutWr, "Uint", 0, "Uint", 0)

   DllCall("SetHandleInformation", "Uint", hStdInRd , "Uint", 1, "Uint", 1)

   DllCall("SetHandleInformation", "Uint", hStdOutWr, "Uint", 1, "Uint", 1)

   VarSetCapacity(pi, 16, 0)

   NumPut(VarSetCapacity(si, 68, 0), si)   ; size of si

   NumPut(0x100   , si, 44)      ; STARTF_USESTDHANDLES

   NumPut(hStdInRd   , si, 56)      ; hStdInput

   NumPut(hStdOutWr, si, 60)      ; hStdOutput

   NumPut(hStdOutWr, si, 64)      ; hStdError

   If Not   DllCall("CreateProcess", "Uint", 0, "Uint", &sCmd, "Uint", 0, "Uint", 0, "int", True, "Uint", 0x08000000, "Uint", 0, "Uint", sDir ? &sDir : 0, "Uint", &si, "Uint", &pi)   ; bInheritHandles and CREATE_NO_WINDOW

      ExitApp

   DllCall("CloseHandle", "Uint", NumGet(pi,0))

   DllCall("CloseHandle", "Uint", NumGet(pi,4))

   DllCall("CloseHandle", "Uint", hStdOutWr)

   DllCall("CloseHandle", "Uint", hStdInRd)

   If   sInput <>

   DllCall("WriteFile", "Uint", hStdInWr, "Uint", &sInput, "Uint", StrLen(sInput), "UintP", nSize, "Uint", 0)

   DllCall("CloseHandle", "Uint", hStdInWr)

   bStream ? (bAlloc:=DllCall("AllocConsole"),hCon:=DllCall("CreateFile","str","CON","Uint",0x40000000,"Uint",bAlloc ? 0 : 3,"Uint",0,"Uint",3,"Uint",0,"Uint",0)) : ""

   VarSetCapacity(sTemp, nTemp:=bStream ? 64-nTrim:=1 : 4095)

   Loop

      If   DllCall("ReadFile", "Uint", hStdOutRd, "Uint", &sTemp, "Uint", nTemp, "UintP", nSize:=0, "Uint", 0)&&nSize

      {

         NumPut(0,sTemp,nSize,"Uchar"), VarSetCapacity(sTemp,-1), sOutput.=sTemp

         If   bStream&&hCon+1

            Loop

               If   RegExMatch(sOutput, "[^\n]*\n", sTrim, nTrim)

                  DllCall("WriteFile", "Uint", hCon, "Uint", &sTrim, "Uint", StrLen(sTrim), "UintP", nSize:=0, "Uint", 0)&&nSize ? nTrim+=nSize : ""

               Else   Break

      }

      Else   Break

   DllCall("CloseHandle", "Uint", hStdOutRd)

   bStream ? (DllCall("Sleep","Uint",1000),hCon+1 ? DllCall("CloseHandle","Uint",hCon) : "",bAlloc ? DllCall("FreeConsole") : "") : ""

   Return   [color=#BF0000]StrGet(&sOutput,"CP0")[/color]

}


garry
  • Spam Officer
  • 3219 posts
  • Last active: Sep 20 2018 02:47 PM
  • Joined: 19 Apr 2005

another example

;-- http://www.autohotkey.com/board/topic/89581-exiftoolexe-comspec-output/
objShell := ComObjCreate("WScript.Shell")
objExec := objShell.Exec(comspec " /c netstat -e -s")
strStdOut := ""
while, !objExec.StdOut.AtEndOfStream
    strStdOut := objExec.StdOut.ReadAll()
MsgBox %strStdOut%