|
|
Joined: Sep 2026
Posts: 2
Bowl of petunias
|
OP
Bowl of petunias
Joined: Sep 2026
Posts: 2 |
I have a small script that I use to launch programs via $com and wscript.shell using the exec method as this allows me to control the exe to some extent, All works fine until I try to read the stdout & call AtEndOfStream property or ReadLine method when I am at the end, this cause mIRC to freeze until the exe exits. Shouldn't AtEndOfStream simply give a true result? I've looked online at other languages using com (vbscript etc..) and they have examples of this working as expected. This only affects still running programs, if the program runs and quits then I can read the stdout with no issues. System used: Win 7 Ultimate x64 Using the script below:
alias testcom {
set -e %testcom $exec(cmd.exe)
echo eos: $exec(%testcom).eos == $false
echo line1: $exec(%testcom).readline = $true
echo line2: $exec(%testcom).readline = $true Microsoft Windows [Version 6.1.7601]
echo line3: $exec(%testcom).readline = $true Copyright (c) 2009 Microsoft Corporation. All rights reserved.
echo line4: $exec(%testcom).readline = $true
; this next line freezes
echo line5: $exec(%testcom).readline = $true C:\mIRC>
echo eos: $exec(%testcom).eos == $true
echo terminate: $exec(%testcom).terminate
comclose %testcom
}
Here is the exec script I'm using
; $1- = item to execute & args
; or if $prop is set
; $1 = com object returned by exec()
; $prop = Terminate or pid or Status or eos or Line or ReadLine or WriteLine or debug
alias exec {
if ($0 == 0) return
if ($prop) {
if (!$com($1)) return
if ($prop == Terminate) noop $com($1,Terminate,1)
elseif ($prop == pid) noop $com($1,ProcessID,2)
elseif ($prop == Status) noop $com($1,Status,2)
elseif ($prop == EOS) {
; BUG: causes mirc to freeze when used on a running task when it should return $true! Unfreezes on task exit.
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
.timer 1 0 .comclose %exec_stdout
if ((!$com(%exec_stdout,AtEndOfStream,2)) || ($comerr)) return -2
return $com(%exec_stdout).result
}
elseif ($prop == ReadLine) {
; BUG: causes mirc to freeze when used on a running task when it should return $false! Unfreezes on task exit.
; also freezes if ReadLine is used without AtEndOfStream check.
; NB: results can be an empty line, $true used to make it clear this is a good result
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
.timer 1 0 .comclose %exec_stdout
if ((!$com(%exec_stdout,AtEndOfStream,2)) || ($comerr)) return -2
if ($com(%exec_stdout).result) return $false
if ((!$com(%exec_stdout,ReadLine,1)) || ($comerr)) return -3
return $true $com(%exec_stdout).result
}
elseif ($prop == WriteLine) {
; NB: results can be an empty line, $true used to make it clear this is a good result
var %exec_stdin exec_stdout $+ $ticks
if ((!$com($1,StdIn,2,dispatch* %exec_stdin)) || ($comerr)) return -1
.timer 1 0 .comclose %exec_stdin
if ((!$com(%exec_stdin,WriteLine,1,bstr,$2)) || ($comerr)) return -3
return $true
}
elseif ($prop == Line) {
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
.timer 1 0 .comclose %exec_stdout
if ((!$com(%exec_stdout,Line,2)) || ($comerr)) return -2
return $com(%exec_stdout).result
}
elseif ($prop == debug) {
echo -s start
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
.timer 1 0 .comclose %exec_stdout
echo -s got stdout
if ((!$com(%exec_stdout,AtEndOfStream,2)) || ($comerr)) return -2
echo -s got AtEndOfStream
var %res = $com(%exec_stdout).result
echo -s ok
return %res
}
else return
return $com($1).result
}
var %% = s $+ $ticks, %exec_com = $+(%%,_exec)
if (!$com(%%)) .comopen %% wscript.shell
if ($comerr) return
.comclose %% $com(%%,exec,1,bstr,$1-,dispatch* %exec_com)
return %exec_com
}
|
|
|
|
|
Joined: Dec 2002
Posts: 3,926
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 3,926 |
When I run your script, the error "* Invalid parameters: $com" is reported when a second call to "ReadLine" is made with a parameter at the line: echo line2: $exec(%testcom).readline = $true Microsoft Windows [Version 6.1.7601] So I have not been able to reproduce the issue here yet.
|
|
|
|
|
Joined: Dec 2002
Posts: 3,926
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 3,926 |
Looking at your script, it was specifying two parameters in the $com() call instead of one. If I change it to one, it seems to work as expected. As for the momentary pause before the $com() call returns, I was able to reproduce this every twenty calls or so but it was pretty intermittent. mIRC is dependent on ActiveX returning from the call in this case, so there isn't anything it can actually do about this. As far as I can see, $com() is just waiting for the call to return.
|
|
|
|
|
Joined: Sep 2026
Posts: 2
Bowl of petunias
|
OP
Bowl of petunias
Joined: Sep 2026
Posts: 2 |
I have done some more research into this & it seems to be all com's fault, so nothing mirc can do about it  I also found the script issue, the .timer 1 0 .comclose line was causing the issue when the commands were used quickly Fixed version....
; $1- = item to execute & args
; or if $prop is set
; $1 = com object returned by exec()
; $prop = Terminate or pid or Status or eos or Line or ReadLine or WriteLine or debug
alias exec {
if ($0 == 0) return
if ($prop) {
if (!$com($1)) return
if ($prop == Terminate) noop $com($1,Terminate,1)
elseif ($prop == pid) noop $com($1,ProcessID,2)
elseif ($prop == Status) noop $com($1,Status,2)
elseif ($prop == EOS) {
; BUG: causes mirc to freeze when used on a running task when it should return $true! Unfreezes on task exit.
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
if ((!$com(%exec_stdout,AtEndOfStream,2)) || ($comerr)) var %res = -2
else var %res = $com(%exec_stdout).result
.comclose %exec_stdout
return %res
}
elseif ($prop == ReadLine) {
; BUG: causes mirc to freeze when used on a running task when it should return 0! Unfreezes on task exit.
; NB: results can be an empty line, 1 used to make it clear this is a good result
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
if ((!$com(%exec_stdout,AtEndOfStream,2)) || ($comerr)) var %res = -2
elseif ($com(%exec_stdout).result) var %res = 0
elseif ((!$com(%exec_stdout,ReadLine,1)) || ($comerr)) var %res -3
else var %res = 1 $com(%exec_stdout).result
.comclose %exec_stdout
returnex %res
}
elseif ($prop == WriteLine) {
var %exec_stdin exec_stdout $+ $ticks
if ((!$com($1,StdIn,2,dispatch* %exec_stdin)) || ($comerr)) return -1
if ((!$com(%exec_stdin,WriteLine,1,bstr,$2)) || ($comerr)) var %res = -3
else var %res = 1
.comclose %exec_stdin
return %res
}
elseif ($prop == Line) {
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
if ((!$com(%exec_stdout,Line,2)) || ($comerr)) var %res = -2
else var %res = $com(%exec_stdout).result
.comclose %exec_stdout
return %res
}
elseif ($prop == debug) {
echo -s start
var %exec_stdout exec_stdout $+ $ticks
if ((!$com($1,StdOut,2,dispatch* %exec_stdout)) || ($comerr)) return -1
echo -s got stdout
if ((!$com(%exec_stdout,AtEndOfStream,2)) || ($comerr)) var %res = -2
else {
echo -s got AtEndOfStream
var %res = $com(%exec_stdout).result
}
echo -s ok
.comclose %exec_stdout
return %res
}
else return
return $com($1).result
}
var %% = s $+ $ticks, %exec_com = $+(%%,_exec), %exec_stdout = %exec_com $+ _stdout.txt
if (!$com(%%)) .comopen %% wscript.shell
if ($comerr) return
.comclose %% $com(%%,exec,1,bstr,$1-,dispatch* %exec_com)
return %exec_com
}
|
|
|
|
|