Jump to content

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

Simplified versions of Sean's StdOutToVar()


  • Please log in to reply
22 replies to this topic
SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Plain Version.



StdOutToVar( sCmd ) { ;  GAHK32 ; Modified Version : SKAN 05-Jul-2013  http://goo.gl/j8XJXY                             
  Static StrGet := "StrGet"     ; Original Author  : Sean 20-Feb-2007  http://goo.gl/mxCdn  
   
  DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 )
  DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 )

  VarSetCapacity( STARTUPINFO, 68, 0  )      ; STARTUPINFO          ;  http://goo.gl/fZf24
  NumPut( 68,         STARTUPINFO,  0 )      ; cbSize
  NumPut( 0x100,      STARTUPINFO, 44 )      ; dwFlags    =>  STARTF_USESTDHANDLES = 0x100 
  NumPut( hPipeWrite, STARTUPINFO, 60 )      ; hStdOutput
  NumPut( hPipeWrite, STARTUPINFO, 64 )      ; hStdError

  VarSetCapacity( PROCESS_INFORMATION, 16 )  ; PROCESS_INFORMATION  ;  http://goo.gl/b9BaI      
  
  If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ;  http://goo.gl/USC5a
              , UInt,1, UInt,0x08000000, UInt,0, UInt,0
              , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) 
   Return "" 
   , DllCall( "CloseHandle", UInt,hPipeWrite ) 
   , DllCall( "CloseHandle", UInt,hPipeRead )
   , DllCall( "SetLastError", Int,-1 )     

  hProcess := NumGet( PROCESS_INFORMATION, 0 )                 
  hThread  := NumGet( PROCESS_INFORMATION, 4 )                      

  DllCall( "CloseHandle", UInt,hPipeWrite )

  AIC := ( SubStr( A_AhkVersion, 1, 3 ) = "1.0" )                   ;  A_IsClassic 
  VarSetCapacity( Buffer, 4096, 0 ), nSz := 0 
  
  While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, UInt,0 )
   sOutput .= ( AIC && NumPut( 0, Buffer, nSz, "UChar" ) && VarSetCapacity( Buffer,-1 ) ) 
              ? Buffer : %StrGet%( &Buffer, nSz, "CP850" )
 
  DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode )
  DllCall( "CloseHandle", UInt,hProcess  )
  DllCall( "CloseHandle", UInt,hThread   )
  DllCall( "CloseHandle", UInt,hPipeRead )

Return sOutput,  DllCall( "SetLastError", UInt,ExitCode )
}
Usage examples:
Msgbox % StdOutToVar( "cmd /c dir c:\*.*" )
MsgBox % StdOutToVar( "ipconfig /all" )
 
Stream Version. Thanks to HotKeyIt
 
StdOutStream( sCmd, Callback = "" ) { ; Modified  :  SKAN 31-Aug-2013 http://goo.gl/j8XJXY                             
  Static StrGet := "StrGet"           ; Thanks to :  HotKeyIt         http://goo.gl/IsH1zs                                   
                                      ; Original  :  Sean 20-Feb-2007 http://goo.gl/mxCdn
                                    
  DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 )
  DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 )

  VarSetCapacity( STARTUPINFO, 68, 0  )      ; STARTUPINFO          ;  http://goo.gl/fZf24
  NumPut( 68,         STARTUPINFO,  0 )      ; cbSize
  NumPut( 0x100,      STARTUPINFO, 44 )      ; dwFlags    =>  STARTF_USESTDHANDLES = 0x100 
  NumPut( hPipeWrite, STARTUPINFO, 60 )      ; hStdOutput
  NumPut( hPipeWrite, STARTUPINFO, 64 )      ; hStdError

  VarSetCapacity( PROCESS_INFORMATION, 16 )  ; PROCESS_INFORMATION  ;  http://goo.gl/b9BaI      
  
  If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ;  http://goo.gl/USC5a
              , UInt,1, UInt,0x08000000, UInt,0, UInt,0
              , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) 
   Return "" 
   , DllCall( "CloseHandle", UInt,hPipeWrite ) 
   , DllCall( "CloseHandle", UInt,hPipeRead )
   , DllCall( "SetLastError", Int,-1 )     

  hProcess := NumGet( PROCESS_INFORMATION, 0 )                 
  hThread  := NumGet( PROCESS_INFORMATION, 4 )                      

  DllCall( "CloseHandle", UInt,hPipeWrite )

  AIC := ( SubStr( A_AhkVersion, 1, 3 ) = "1.0" )                   ;  A_IsClassic 
  VarSetCapacity( Buffer, 4096, 0 ), nSz := 0 
  
  While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, Int,0 ) {

   tOutput := ( AIC && NumPut( 0, Buffer, nSz, "Char" ) && VarSetCapacity( Buffer,-1 ) ) 
              ? Buffer : %StrGet%( &Buffer, nSz, "CP850" )

   Isfunc( Callback ) ? %Callback%( tOutput, A_Index ) : sOutput .= tOutput

  }                   
 
  DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode )
  DllCall( "CloseHandle",  UInt,hProcess  )
  DllCall( "CloseHandle",  UInt,hThread   )
  DllCall( "CloseHandle",  UInt,hPipeRead )
  DllCall( "SetLastError", UInt,ExitCode  )

Return Isfunc( Callback ) ? %Callback%( "", 0 ) : sOutput      
}
Usage examples:
MsgBox % StdOutStream( "ping www.autohotkey.com", "StdOutStream_Callback" ) 
MsgBox % StdOutStream( "ipconfig /All" )

StdOutStream_Callback( data, n ) {
  Static D
  ToolTip % D .= data

  if ! ( n ) {
    Tooltip % D := ""
    Return "Callback says: Hi!"
  }
}
Note: Within the callback function, you may pre-process the output of StdOutStream()
kWo4Lk1.png

HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Hi SKAN, looks good, thanks for that ;)

 

How about allowing capturing stream or alternatively passing a ByRef variable to capture stream?

; Launch a function that receives the output
MsgBox % StdOutToVar("ping www.autohotkey.com","OnStream")
OnStream(ByRef data){
	ToolTip % data
}

; Use SetTimer to capture stream that is saved in a global variable
Settimer,OnStream,100
StdOutToVar("ping www.autohotkey.com",globalvar)
SetTimer,OnStream,Off
MsgBox % globalvar
ExitApp
OnStream:
 ToolTip % globalvar
Return

StdOutToVar( sCmd, ByRef sOutput:="" ) { ;  GAHK32 ; Modified Version : SKAN 05-Jul-2013  http://goo.gl/j8XJXY                             
  Static StrGet := "StrGet"     ; Original Author  : Sean 20-Feb-2007  http://goo.gl/mxCdn  
   
  DllCall( "CreatePipe", UIntP,hPipeRead, UIntP,hPipeWrite, UInt,0, UInt,0 )
  DllCall( "SetHandleInformation", UInt,hPipeWrite, UInt,1, UInt,1 )

  VarSetCapacity( STARTUPINFO, 68, 0  )      ; STARTUPINFO          ;  http://goo.gl/fZf24
  NumPut( 68,         STARTUPINFO,  0 )      ; cbSize
  NumPut( 0x100,      STARTUPINFO, 44 )      ; dwFlags    =>  STARTF_USESTDHANDLES = 0x100 
  NumPut( hPipeWrite, STARTUPINFO, 60 )      ; hStdOutput
  NumPut( hPipeWrite, STARTUPINFO, 64 )      ; hStdError

  VarSetCapacity( PROCESS_INFORMATION, 16 )  ; PROCESS_INFORMATION  ;  http://goo.gl/b9BaI      
  
  If ! DllCall( "CreateProcess", UInt,0, UInt,&sCmd, UInt,0, UInt,0 ;  http://goo.gl/USC5a
              , UInt,1, UInt,0x08000000, UInt,0, UInt,0
              , UInt,&STARTUPINFO, UInt,&PROCESS_INFORMATION ) 
   Return "" 
   , DllCall( "CloseHandle", UInt,hPipeWrite ) 
   , DllCall( "CloseHandle", UInt,hPipeRead )
   , DllCall( "SetLastError", Int,-1 )     

  hProcess := NumGet( PROCESS_INFORMATION, 0 )                 
  hThread  := NumGet( PROCESS_INFORMATION, 4 )                      

  DllCall( "CloseHandle", UInt,hPipeWrite )

  AIC := ( SubStr( A_AhkVersion, 1, 3 ) = "1.0" )                   ;  A_IsClassic 
  VarSetCapacity( Buffer, 4096, 0 ), nSz := 0 
  if (IsFunc(sFunc:=sOutput) && !sOutput:=""){
		While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, UInt,0 )
			%sFunc%(sOutput .= ( AIC && NumPut( 0, Buffer, nSz, "UChar" ) && VarSetCapacity( Buffer,-1 ) ) 
              ? Buffer : %StrGet%( &Buffer, nSz, "CP850" ))
	} else if (!sOutput:="")
		While DllCall( "ReadFile", UInt,hPipeRead, UInt,&Buffer, UInt,4094, UIntP,nSz, UInt,0 )
			sOutput .= ( AIC && NumPut( 0, Buffer, nSz, "UChar" ) && VarSetCapacity( Buffer,-1 ) ) 
              ? Buffer : %StrGet%( &Buffer, nSz, "CP850" )
 
  DllCall( "GetExitCodeProcess", UInt,hProcess, UIntP,ExitCode )
  DllCall( "CloseHandle", UInt,hProcess  )
  DllCall( "CloseHandle", UInt,hThread   )
  DllCall( "CloseHandle", UInt,hPipeRead )

  Return sOutput,  DllCall( "SetLastError", UInt,ExitCode )
}


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

How about allowing capturing stream or alternatively passing a ByRef variable to capture stream?


I have implemented the former part of your suggestion as a different version. Please see Title post.
I have an immediate use for the stream version.
Many thanks to you HotKeyIt. happy.png

joedf
  • Administrators
  • 986 posts
  • AutoHotkey Foundation
  • Last active: Nov 02 2019 08:38 PM
  • Joined: 20 May 2012

cool! :)


Why ahkscript.org? - autohotkey.com is outdated

tmplinshi
  • Members
  • 245 posts
  • Last active: Mar 12 2015 02:29 PM
  • Joined: 06 Apr 2012
Great! The StdOutStream() is what I was looking for to getting the stdout in real time. Thanks a lot.

An example:
MsgBox % StdOutStream( "curl -O -# http://ftp.icm.edu.pl/packages/unix/graphics/GraphicsMagick/windows/GraphicsMagick-1.3.18-Q8-win32-dll.exe", "StdOutStream_Callback" ) 

StdOutStream_Callback( data, n ) {
  Static D

  D := data
  D := Trim(D, "`r`n")
  D := RegExReplace(D, "s).*[\r\n]+")
  ToolTip, % D

  if ! ( n ) {
    Tooltip % D := ""
    Return "Callback says: Hi!"
  }
}


Menixator
  • Members
  • 744 posts
  • Last active: Sep 01 2015 02:54 PM
  • Joined: 10 Jul 2013

Great! The StdOutStream() is what I was looking for to getting the stdout in real time. Thanks a lot.

 

Thanks! I was looking for this as well! happy.png



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

when i run this, i get a blank message box? confused.png

Great! The StdOutStream() is what I was looking for to getting the stdout in real time. Thanks a lot.

An example:

MsgBox % StdOutStream( "curl -O -# http://ftp.icm.edu.pl/packages/unix/graphics/GraphicsMagick/windows/GraphicsMagick-1.3.18-Q8-win32-dll.exe", "StdOutStream_Callback" ) 

StdOutStream_Callback( data, n ) {
  Static D

  D := data
  D := Trim(D, "`r`n")
  D := RegExReplace(D, "s).*[\r\n]+")
  ToolTip, % D

  if ! ( n ) {
    Tooltip % D := ""
    Return "Callback says: Hi!"
  }
}


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005

when i run this, i get a blank message box?

 

You need curl.exe for that example to work.

@tmplinshi Nice demo. Thanks! happy.png



joedf
  • Administrators
  • 986 posts
  • AutoHotkey Foundation
  • Last active: Nov 02 2019 08:38 PM
  • Joined: 20 May 2012

its weird... i have curl and, i only got a msgbox with "Callback says: Hi!"... :(


Why ahkscript.org? - autohotkey.com is outdated

Wicked
  • Members
  • 504 posts
  • Last active: Nov 18 2018 02:17 AM
  • Joined: 07 Jun 2008
I was thinking about this just a few days ago. Thanks again, SKAN!

3nL8f.png


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

@joedf

 

its weird... i have curl and, i only got a msgbox with "Callback says: Hi!"...

I have curl.exe with 3 dll-files in same folder as script, it works for me



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

Is it possible to send the output to a second gui's edit box?  Here an example below, it works fine if using a single gui containing the editbox for soutput. With the second gui nothing shows in the edit box.

Gui, Add, Button, x435 y10 w43 h23 gnmap, info
Gui, 2:Add, Edit, x15 y10 w620 h605 vtxtStdout,
Gui, Show, w486 h45, 
return

nmap:
Gui, 2:Show, w652 h631, 
Gui, 2:submit, nohide
sOutput := StdOutStream("C:\Program Files (x86)\Nmap\nmap.exe -sn 10.117.10.162")
GuiControl, , txtStdOut, %sOutput%
return


;GuiClose:
ExitApp


SKAN
  • Administrators
  • 9115 posts
  • Last active:
  • Joined: 26 Dec 2005
Use "2:" in GuiControl to indicate variable txtStdOut resides in Gui-2
GuiControl, 2:, txtStdOut, %sOutput%


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

JZC
  • Members
  • 1 posts
  • Last active: Sep 20 2013 02:41 PM
  • Joined: 20 Aug 2013
I tried "Simplified versions of Sean's StdOutToVar()" with netstat -b and got the message "The requested operation requires elevation.". This is a Windows 7 OS. The solution I found was to go to Start >> All Programs >> Administrative Tools >> Local Security Policy >> Security Settings >> Local Policies >> Security Options >> User Account Control: Run all administrators in Admin Approval Mode ,setting it to Disabled and restarting the computer.