Jump to content

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

CMDret - return output from console progs [DLL version]


  • Please log in to reply
172 replies to this topic
corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Posted Image CMDret
- A Dll file designed for retrieving output from console based applications and saving the output in a variable and/or redirecting to a control without displaying the console window or creating/using temporary files.

Latest release:
CMDret 4d Beta - Download (cmdret.dll, cmdstub.exe, several test scripts)
- updated all functions for Windows 2000 compatibility (hopefully)
- This version contains the following functions:
RunRedirect(CMDin)
RunInControl(CMDin, ControlHwnd)
RunReturn(CMDin, CMDout)
RunWEx(CMDin, WorkingDir, CMDin, CMDout, CMDerr)
RunWCB(CMDin, CallbackAddress) - callback - (PID, NumberOfCharsInOutput, Output, FutureUse)


Previous Releases:
Posted Image CMDret - v3.2.1 (DLL version)

CMDret v3.x is a .DLL file (Freeware) that has been designed to return the output from a console program to a variable (rather than redirect to a textbox like the command line version). Version 3.1 (or greater) now includes a function that has the ability to output to a control and should be more stable than the command line version. Please keep in mind that CMDret is currently a beta realease. Any feedback would be greatly appreciated ;) .

Win9.x users
Note: only 32 bit console applications will currently work with the this dll version of CMDret (v3.1.2 or lower). Calls that require command.com will likely not produce any output and may crash. To avoid this I have included a file named "cmdstub.exe" with the download (in the Win9x folder in the zip file). This file should be used when calling 16 bit console applications to enable returning output. Example: cmdstub.exe command.com /C set


Updated: March 15, 2008 - version 3.2.1
- modified: the methods used in the functions to detect when a console program has finished executing to improve stability, reliability and efficiency (hopefully)
- modified required parameters for the RunInControl function
- Added: sample scripts

Updated: June 1, 2005 - version 3.1.2
- Added cmdstub.exe to the download to support 16 bit console applications

Updated: May 30, 2005 - version 3.1.2
- Tweaked the RunReturn function
- Added another function to the dll (RunWEx) to allow StdInput, StdOutput, StdError

Updated: May 24, 2005 - version 3.1.1
- Added another function to the dll (RunReturn) to allow returning output to a variable. This function does not require the additional LoadLibrary, lstrcpyA, and FreeLibrary calls.

Current functions:
RunReturn(CMD, StrOut)
- CMD - the console program/command to execute (str)
- StrOut - the variable used to store the output (str)
= If the function fails, the return value is zero

RunWEx(CMD, CMDdir, CMDin, CMDout, CMDerr)
- CMD - the console program/command to execute (str)
- CMDdir - Future Use (working directory - not currently functional) (str)
- CMDin - StdInput String (str)
- CMDout - the variable used to store StdOutput output (str)
- CMDerr - the variable used to store StdError output (str)
= If the function fails, the return value is zero

RunRedirect(CMD)
- Where CMD is the console program/command to execute (str)

RunInControl(CMD, WinHandle, CtrlClass, CtrlInstance)
- CMD should be the console program/command to execute (str)
- CtrlHWND should be the handle to the control to stream into
= If the function fails, the return value is zero

Download the latest version (DLL Version 3.2.1)

Download (DLL Version 3.1.2)
Alternate Download for version 3.1.2

BCX Source (version 3.1.2) - not currently available...

Notes:
- To check which version you currently have - right click on cmdret.dll, select Properties, and click the Version tab
- When trying to retrieve a directory listing be sure to specify a directory after a 'DIR' command. ( COMSPEC " /C Dir c:\" )

Sample Code:
; CMDret DLL version 3.1.1 (or greater) required 

ret1 := CMDret(COMSPEC " /C set") 
MsgBox, %ret1% 

CMDret(CMD) 
{ 
  VarSetCapacity(StrOut, 10000) 
  RetVal := DllCall("cmdret.dll\RunReturn", "str", CMD, "str", StrOut) 
  Return, %StrOut% 
}


; CMDret (DLL version 3.0 or greater required) examples

CMD := COMSPEC " /C set"

  VarSetCapacity(StrOut, 1000) 
  hModule := DllCall("LoadLibrary", "str", "cmdret.dll","UInt") 
  DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
  DllCall("FreeLibrary", "UInt", hModule)

  MsgBox %StrOut%



CMD := "ipconfig /all"

  VarSetCapacity(StrOut, 1000) 
  hModule := DllCall("LoadLibrary", "str", "cmdret.dll","UInt") 
  DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
  DllCall("FreeLibrary", "UInt", hModule)

  MsgBox %StrOut%

Streaming Example:
; CMDret DLL version 3.1 (or greater) required

Gui, Add, Edit, x6 y10 w460 h360 +HScroll
Gui, Show, x398 y110 h377 w477, CMDret - DLL version - Streaming Test App

CMD = ping 127.0.0.1
OutputWindow := WinExist("CMDret - DLL version - Streaming Test App")

StrOut := DllCall("cmdret.dll\RunInControl", "str", CMD, "Uint", OutputWindow, "str", "Edit", "int", "1")
Return

GuiClose:
ExitApp


corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Same as above but only loads and unloads the dll once for speed:

; CMDret (DLL version) examples
hModule := DllCall("LoadLibrary", "str", "cmdret.dll","UInt") 

CMD := COMSPEC " /C set"
  VarSetCapacity(StrOut, 1000) 
  DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
MsgBox %StrOut%

CMD := "ipconfig /all"
  VarSetCapacity(StrOut, 1000) 
  DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
MsgBox %StrOut%

DllCall("FreeLibrary", "UInt", hModule)


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
Nice! It's getting better and better and someday soon your work should finally get added as a built-in feature.

Thanks.

Atomhrt
  • Members
  • 124 posts
  • Last active: Nov 13 2006 09:18 PM
  • Joined: 02 Sep 2004
Very good and very handy indeed! Keep up the good work. :D

corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Thanks :) . Please keep in mind that this is a beta. Any feedback regarding code that works/doesn't work as expected would be greatly appreciated.

corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Another example:
; Generated using SmartGUI Creator 3.4

Gui, Add, Edit, x12 y30 w310 h20 -WantReturn vCMD,  ;
Gui, Add, Button, x322 y30 w51 h20 gBrowse1, ...
Gui, Add, Text, x12 y10 w130 h20, Command:
Gui, Add, Text, x12 y90 w130 h20, Output:
Gui, Add, Edit, x12 y110 w410 h280 +HScroll vEditOut,  ;
Gui, Add, Button, x372 y30 w51 h20 Default, Go
Gui, Add, Checkbox, x12 y60 w190 h20 vChk1, Use COMSPEC
Gui, Show, h408 w436, CMDret - DLL version - Test App
Return

Browse1:
FileSelectFile, SelectedFile, 3, , Please select a console program 
if SelectedFile
{
  Loop, %SelectedFile%
    Spath = %A_LoopFileShortPath%
  GuiControl,,Edit1,%Spath% 
}
Return

buttonGo:
StrOut=
GuiControl, Text, Edit2,  ;
GuiControlGet, CMD,, Edit1 
GuiControlGet, Chk1
if Chk1
  CMD := COMSPEC " /C " CMD
if CMD
  IfNotInString, CMD, dir 
  {
    VarSetCapacity(StrOut, 1000)
    hModule := DllCall("LoadLibrary", "str", "cmdret.dll","UInt") 
    DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
    GuiControl, Text, Edit2, %StrOut%
    DllCall("FreeLibrary", "UInt", hModule)
  }
  else
  {
    msgbox, Sorry, 'Dir' command not currently allowed
  }
ControlFocus, Edit1
Return

GuiClose:
ExitApp


JBensimon
  • Members
  • 167 posts
  • Last active: Mar 24 2014 02:25 AM
  • Joined: 16 Nov 2004
Looks very promising, corrupt. I'll play with it as soon as I can find the time. In practice, I'd probably wind up "wrapping it" in a user-defined function to keep the setup machinery out of sight.

Later,

Jacques.

corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Added a function to allow streaming to a control. This function should be more stable than the command line version.

RunInControl(CMD, WinHandle, CtrlClass, CtrlInstance)
- CMD should be the console program/command to execute (str)
- WinHandle should be the handle to the window where the ouput control exists (Uint)
- CtrlClass should be the ClassName of the output control (str)
- CtrlInstance should be the instance number of the output control (int)
= If the function fails, the return value is zero

; CMDret DLL version 3.1 (or greater) required 

Gui, Add, Edit, x6 y10 w460 h360 +HScroll 
Gui, Show, x398 y110 h377 w477, CMDret - DLL version - Streaming Test App 

CMD = ping 127.0.0.1 
OutputWindow := WinExist("CMDret - DLL version - Streaming Test App") 

StrOut := DllCall("cmdret.dll\RunInControl", "str", CMD, "Uint", OutputWindow, "str", "Edit", "int", "1") 
Return 

GuiClose: 
ExitApp


corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Another streaming example
; CMDret DLL version 3.1 (or greater) required



Gui, Add, Edit, x12 y30 w310 h20 -WantReturn vCMD,  ;

Gui, Add, Button, x322 y30 w51 h20 gBrowse1, ...

Gui, Add, Text, x12 y10 w130 h20, Command:

Gui, Add, Text, x12 y90 w130 h20, Output:

Gui, Add, Edit, x12 y110 w410 h280 +HScroll vEditOut,  ;

Gui, Add, Button, x372 y30 w51 h20 Default, Go

Gui, Add, Checkbox, x12 y60 w190 h20 vChk1, Use COMSPEC

Gui, Show, h408 w436, CMDret - DLL version - Streaming Test App 2

Return



Browse1:

FileSelectFile, SelectedFile, 3, , Please select a console program 

if SelectedFile

{

  Loop, %SelectedFile%

    Spath = %A_LoopFileShortPath%

  GuiControl,,Edit1,%Spath% 

}

Return



buttonGo:

; Retrieve output window handle

OutputWindow := WinExist("CMDret - DLL version - Streaming Test App 2")

; Clear Edit control & wait for refresh

GuiControl, Text, Edit2, ;

sleep, 250

; Retrieve & process command info

GuiControlGet, CMD,, Edit1 

GuiControlGet, Chk1

if Chk1

  CMD := COMSPEC " /C " CMD

if CMD

  IfNotInString, CMD, dir 

  {

  ; one line call. loadlibrary not necessary to output to control

  StrOut := DllCall("cmdret.dll\RunInControl", "str", CMD, "Uint", OutputWindow, "str", "Edit", "int", "2")

  }

  else

  {

    msgbox, Sorry, 'Dir' command not currently supported

  }

ControlFocus, Edit1

Return



GuiClose:

ExitApp


Rajat
  • Members
  • 1904 posts
  • Last active: May 20 2014 06:34 PM
  • Joined: 28 Mar 2004
its a nice util, thanx! (just curious) why is dir cmd not supported?

corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004

its a nice util, thanx! (just curious) why is dir cmd not supported?

Thanks :) . I haven't currently specified a working directory so the function fails and locks up when trying to do a directory listing. I should have a fix and/or option to allow a directory listing and related commands soon.

corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Stream to Notepad:
; CMDret DLL version 3.1 (or greater) required

Run, Notepad,,, notepid
WinWait, ahk_pid %notepid%
WinWaitActive, ahk_pid %notepid%

CMD := "ping 127.0.0.1"
OutputWindow := WinExist(ahk_pid %notepid%)
if OutputWindow <> 0
  StrOut := DllCall("cmdret.dll\RunInControl", "str", CMD, "Uint", OutputWindow, "str", "Edit", "int", "1")


corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004

its a nice util, thanx! (just curious) why is dir cmd not supported?

Thanks :) . I haven't currently specified a working directory so the function fails and locks up when trying to do a directory listing. I should have a fix and/or option to allow a directory listing and related commands soon.

However, the following does seem to work ok:
; CMDret DLL version 3.0 (or greater) required

VarSetCapacity(StrOut, 10000) ; this number may need to be increased if your directory has many, many entries
hModule := DllCall("LoadLibrary", "str", "cmdret.dll","UInt") 

CMD := COMSPEC " /C Dir c:"
DllCall("lstrcpyA", "str", StrOut, "int", DllCall("cmdret.dll\RunRedirect", "str", CMD))
MsgBox, %StrOut%
DllCall("FreeLibrary", "UInt", hModule)

So it might be best to just make a note that a directory must be specified after a 'Dir' command. Opinions welcome...

Rajat
  • Members
  • 1904 posts
  • Last active: May 20 2014 06:34 PM
  • Joined: 28 Mar 2004
even better!

corrupt
  • Members
  • 2558 posts
  • Last active: May 17 2013 01:30 AM
  • Joined: 29 Dec 2004
Updated to version 3.1.1

- Added another function to the dll (RunReturn) to allow returning output to a variable. This function does not require the additional LoadLibrary, lstrcpyA, and FreeLibrary calls.

RunReturn(CMD, StrOut)
- CMD - the console program/command to execute (str)
- StrOut - the variable used to store the output (str)
= If the function fails, the return value is zero

; CMDret DLL version 3.1.1 (or greater) required

ret1 := CMDret(COMSPEC " /C set")
MsgBox, %ret1%

CMDret(CMD)
{
  VarSetCapacity(StrOut, 10000) 
  RetVal := DllCall("cmdret.dll\RunReturn", "str", CMD, "str", StrOut)
  Return, %StrOut%
}