AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Running another program then retrieving a value

 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
fooz



Joined: 08 Jan 2006
Posts: 8

PostPosted: Fri Jan 20, 2006 8:17 am    Post subject: Running another program then retrieving a value Reply with quote

I have the following ahk script that is supposed to execute my php program, passing the value 5. Then the ahk script should receive a single value from the program.

None of the 3 methods I've tried (based on various threads I've read) seem to work. Help appreciated. And I'll admit I'm a total newb with this stuff.

Here' the ahk:

Code:
#SingleInstance

; 1st method
/*
ErrorLevel = 999

RunWait, C:\php\php.exe getVPIP.php 5, ,Hide UseErrorLevel

MsgBox, Result: %ErrorLevel%
*/


; 2nd method
/*
ret1 := CMDret("C:\php\php.exe getVPIP.php 5")

MsgBox, Result: *%ret1%*

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


; 3rd method
CMDout=
CMDerr=
ProgramName := "C:\php\php.exe getVPIP.php 5"

Ret := RunWaitEx(ProgramName, NULL, TextIn, CMDout, CMDerr)
MsgBox, Return Value: %Ret% `r`n`r`nStdError: `r`n%CMDerr%`r`nStdOutput: `r`n%CMDout%

RunWaitEx(CMD, CMDdir, CMDin, ByRef CMDout, ByRef CMDerr)
{
  VarSetCapacity(CMDOut, 100000)
  VarSetCapacity(CMDerr, 100000)
  RetVal := DllCall("cmdret.dll\RunWEx", "str", CMD, "str", CMDdir, "str", CMDin, "str", CMDout, "str", CMDerr)
  Return, %RetVal%
}


And here's the PHP (super simple):
Code:

<?

$inputVar = $argv[1];

// perform logic based on input, then return value

// trying 3 different methods to return a value
echo 3;
return 4;
exit(5);

?>


Last edited by fooz on Fri Jan 20, 2006 5:43 pm; edited 1 time in total
Back to top
View user's profile Send private message
toralf



Joined: 31 Jan 2005
Posts: 3841
Location: Bremen, Germany

PostPosted: Fri Jan 20, 2006 8:44 am    Post subject: Reply with quote

There is one obvious bug, so I do not search further. Please test if that is the problem. Anyway, please give feedback.

When you want a value to be returned from a function, you have to use no %. This this line
Code:
Return, %var%
has to be
Code:
Return, var
This is wrong in method 2 and 3.

Method 1 will not work since the ErrorLevel will not contain the output of the command you run, but if the run command could be run. You have to use a pipe "|" and cb.exe to achieve it.

And please use the [ code] [ /code] tags to format your posts. This helps us to read your post.
_________________
Ciao
toralf
Back to top
View user's profile Send private message Send e-mail Visit poster's website
fooz



Joined: 08 Jan 2006
Posts: 8

PostPosted: Fri Jan 20, 2006 3:21 pm    Post subject: Reply with quote

Thanks for the reply.

Changing the return syntax as you suggest doesn't seem to matter. I think the nuance may be whether or not you follow Return with a comma.
Code:
Return, %RetVal%


...as opposed to...
Code:
Return RetVal


I was copying and pasting code directly from corrupt, who seems to know what he's doing. The code came from this post on CMDret: http://www.autohotkey.com/forum/viewtopic.php?t=3687


And I attempted method 1 based on this statement in the AutoHotKey Help manual:
Quote:
UseErrorLevel: UseErrorLevel can be specified alone or in addition to one of the above words (by separating it from the other word with a space). When the launch fails, this option skips the warning dialog, sets ErrorLevel to the word ERROR, and allows the current thread to continue. If the launch succeeds, RunWait sets ErrorLevel to the program's exit code, and Run sets it to 0.
Back to top
View user's profile Send private message
toralf



Joined: 31 Jan 2005
Posts: 3841
Location: Bremen, Germany

PostPosted: Fri Jan 20, 2006 3:28 pm    Post subject: Reply with quote

You are right. It seams to me that the StrOut is a pointer, so the %% are needed. But I'm not sure, since I do not know much about about DllCall.

Regarding method 1 you might be right.

I have now idea what is wrong. Sorry.
_________________
Ciao
toralf
Back to top
View user's profile Send private message Send e-mail Visit poster's website
fooz



Joined: 08 Jan 2006
Posts: 8

PostPosted: Fri Jan 20, 2006 5:42 pm    Post subject: Reply with quote

Ok. I got method 1 to work, but I'd still like to learn more about how CMDret works. The first method is acceptable because my passed value can be an integer, but in the future it would help to have the flexibility to pass floats and strings and multiple values.

Regarding CMDret, and the following code:

Code:

CMDout=
CMDerr=
ProgramName := "C:\php\php.exe getVPIP.php 5"

Ret := RunWaitEx(ProgramName, NULL, TextIn, CMDout, CMDerr)
MsgBox, Return Value: %Ret% `r`n`r`nStdError: `r`n%CMDerr%`r`nStdOutput: `r`n%CMDout%

RunWaitEx(CMD, CMDdir, CMDin, ByRef CMDout, ByRef CMDerr)
{
VarSetCapacity(CMDOut, 100000)
VarSetCapacity(CMDerr, 100000)
RetVal := DllCall("cmdret.dll\RunWEx", "str", CMD, "str", CMDdir, "str", CMDin, "str", CMDout, "str", CMDerr)
Return, %RetVal%
}


I am using it to call a PHP program that outputs values/data to standard out. Is this what is captured in "CMDout"? Or do I need to somehow access that variable by reference within the called PHP program?



The way I got method 1 to work was by:
- ensuring the PHP program was passing specifically an INTEGER in its exit code
- and, using the full path to reference both the php.exe and the .php file
Back to top
View user's profile Send private message
corrupt



Joined: 29 Dec 2004
Posts: 2436

PostPosted: Sun Jan 22, 2006 11:56 pm    Post subject: Reply with quote

fooz wrote:
I am using it to call a PHP program that outputs values/data to standard out. Is this what is captured in "CMDout"? Or do I need to somehow access that variable by reference within the called PHP program?
CMDout should contain the text that was output to standard out Smile .
Back to top
View user's profile Send private message Visit poster's website
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Mon Jan 23, 2006 12:55 am    Post subject: Reply with quote

Although CmdRet is a fine tool, I never needed it. I use one of a few very simple approaches:
- I start "cmd.exe /c" with console programs, which accept a parameter, an expression to be evaluated, and redirect the output to a file. This file is read back by the AHK script. Because the file remains in the Windows buffer, this is not slower than any other method. Here is an example, which evaluates the marked expression and writes the result back to the same application.
Code:
!x::
   Send ^x
   calc = %ClipBoard%
   StringReplace calc, calc, ^, ^^, All
   StringReplace calc, calc, <, ^<, All
   StringReplace calc, calc, >, ^>, All
   RunWait %Comspec% /c "C:\Program Files\GnuWin32\bin\calc.exe" -p %calc% > c:\calc.tmp,,HIDE
   FileRead Result, c:\calc.tmp
   StringTrimRight Result, Result, 2
   StringReplace Result, Result, `r`n, `;, All
   Send ^v = %Result%
Return

- There are console programs, like LUA, which take input from a file. Cmd.exe allows writing the result to another file. The input file can be set up in AHK, and the result is read and processed in AHK.
Code:
AHKvar = 14

FileDelete C:\LUA.IN
FileAppend,
(
   c = 1+2*3-%AHKvar%
   print(c)
)
, C:\LUA.IN
RunWait %COMSPEC% /c C:\LUA\bin\lua.exe C:\LUA.IN > C:\LUA.OUT,,HIDE
FileRead result, C:\LUA.OUT
MsgBox %result%

- If a console application does not take input from a file, you can still use cmd.exe with "< file.in".
- If an application needs to start up and waits for the input, we can use Send from a Timer subroutine to give it its input. This example runs the Diehard randomness test with some parameters, and the result is processed in an editor, moving the cursor to the first failed result.
Code:
SetTimer Keys
RunWait %DieHard%\DIEHARD.EXE, %DieHard%,,PID
Run C:\t\notepad2\Notepad2.exe %DieHard%\%file%.res,,,np2PID
WinActivate ahk_pid %np2PID%
WinWaitActive ahk_pid %np2PID%
ControlSend,,{F3},ahk_pid %np2PID%
Sleep 250
ControlSend,Edit1,.0000{Enter},ahk_pid %np2PID%
Return

Keys:
   IfWinNotExist ahk_pid %PID%
      Return
   SetTimer Keys, Off
   ControlSend,,%file%.dat{Enter},ahk_pid %PID%
   ControlSend,,%file%.res{Enter},ahk_pid %PID%
   ControlSend,,111111111111111{Enter},ahk_pid %PID%
Return

- If a console application does not allow redirecting the output, you can always use the Clipboard to get the content of the terminal window. It is the case with interactive programs, where you want to see the output and also capture it.
Back to top
View user's profile Send private message
fooz



Joined: 08 Jan 2006
Posts: 8

PostPosted: Mon Jan 23, 2006 3:35 pm    Post subject: Reply with quote

Both the file and clipboard methods seem sloppy to me.

The php file I'm calling is a database api that I run many times a second to pull information from the database. Using file i/o would certainly slow this process down. And as for the clipboard, what if I'm copying and pasting in another app, couldn't I potentially lose either the programs data or the manual data I'm copying and pasting?
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Mon Jan 23, 2006 5:13 pm    Post subject: Reply with quote

fooz wrote:
Both the file and clipboard methods seem sloppy to me.
Several months ago we benchmarked all the return value capture methods we could think of (including modifications of the program to be run):
- ErrorLevel as return value
- Exit code
- Clipboard
- Process memory access (dll)
- Registry I/O
- Temporary files
- CmdRet dll
The temporary file method in the root directory of the boot disk was the fastest, for the reasons I mentioned: the file is created in the Windows buffer and accessed from there (delayed write). If it is deleted in the script, it never gets written to the disk, so it is just accessing fast internal memory. An idle disk is not even spun up.

Accessing a dll is not fast, even if it is cached. Also, it requires to install an extra file in all the machines your script is run, and update that, too, when the OS or the compiled script changes.

fooz wrote:
...as for the clipboard, what if I'm copying and pasting in another app, couldn't I potentially lose either the programs data or the manual data I'm copying and pasting?
You could save the clipboard content to an AHK variable before using the clipboard, and restore it at the end. I don't normally do it, because it could be slow if you have a gigabyte clipboard. Instead I use my own clipboard management script, which saves automatically, what I need.
Back to top
View user's profile Send private message
fooz



Joined: 08 Jan 2006
Posts: 8

PostPosted: Mon Jan 23, 2006 5:15 pm    Post subject: Reply with quote

Great to hear about the file i/o benchmarking results. Thanks!
Back to top
View user's profile Send private message
shimanov



Joined: 25 Sep 2005
Posts: 612

PostPosted: Mon Jan 23, 2006 8:54 pm    Post subject: Reply with quote

Laszlo wrote:
Accessing a dll is not fast, even if it is cached.


Accessing a DLL file loaded in memory is fast, which is the case for many of the core libraries.

Quote:
Also, it requires to install an extra file in all the machines your script is run, and update that, too, when the OS or the compiled script changes.


Given a careful selection of functions (easily accomplished), the library file(s) will exist on all Windows platforms and this will not be an issue.
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4078
Location: Pittsburgh

PostPosted: Mon Jan 23, 2006 9:18 pm    Post subject: Reply with quote

shimanov wrote:
Accessing a DLL file loaded in memory is fast, which is the case for many of the core libraries.
The benchmarks showed, that dll calls are not faster than buffered disk I/O, that is, dll calls accessing different processes or windows are slow.
shimanov wrote:
Given a careful selection of functions (easily accomplished), the library file(s) will exist on all Windows platforms and this will not be an issue.
We are speaking about CmdRet, a custom dll to capture the standard output in an AHK variable.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group