Sysinternals Homepage
Forum Home Forum Home > Sysinternals Utilities > PsTools
  New Posts New Posts RSS Feed - Program Output Lost when Passed through PsExec
  FAQ FAQ  Forum Search   Events   Register Register  Login Login

Program Output Lost when Passed through PsExec

 Post Reply Post Reply
Author
Message
dbingham View Drop Down
Newbie
Newbie
Avatar

Joined: 14 August 2009
Location: New York
Status: Offline
Points: 3
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbingham Quote  Post ReplyReply Direct Link To This Post Topic: Program Output Lost when Passed through PsExec
    Posted: 14 August 2009 at 4:07pm
Hello all,
I'm testing the possibility of writing a small java application the will use Psexec to kick off remote jobs.  In the course of testing binding the stdin and stdout of a java program to psexec I came across an odd bug.

My test program is a basic echo program.  It starts a thread to read from stdin and then pipes the read output directly back to stdout.  When run on the local machine, not from psexec, it works beautifully.  Exactly as it should.

However, when I call it from PsExec the first time the input is piped directly into stdout it is lost.  What makes the bug really bizzare is that it is only the first time the input is piped directly into stdout that it is lost.  If the input String is appended to another string it works fine.  Either a String literal or a String variable.  However, if the input String is sent directly to stdout it doesn't go through.   The second time it is sent to stdout it goes through fine - and everytime there after.  

I'm at a complete loss as to what's going on here.  I've tried to test for every possible bug I can think of.  I'm out of ideas.  Did I miss one or is this just something inside psexec?

Here is the code in question, it's in three classes (one of which implements an interface which is a single function interace).

The Main class:
public class Main {
public static void main(String[] args) {
System.out.println("Starting up.");

CReader input = new CReader(new BufferedReader(new InputStreamReader(System.in)));
CEcho echo = new CEcho();

input.addInputStreamListener(echo);
input.start();

System.out.println("Successfully started up.  Awaiting input.");
}
}

The CReader class which is the thread that reads from stdin:
public class CReader extends Thread {
private ArrayList<InputStreamListener> listeners = new ArrayList<InputStreamListener>();
private boolean exit = false;
private Reader in;

public CReader(Reader in) {
this.in = in;
}

public void addInputStreamListener(InputStreamListener listener) {
listeners.add(listener);
}

public void fireInputRecieved(String input) {

if(input.equals("quit"))
exit = true;

System.out.println("Input string has made it to fireInputRecieved: "+input);

for(int index = 0; index < listeners.size(); index++)
listeners.get(index).inputRecieved(input);
}

@Override
public void run() {

StringBuilder sb = new StringBuilder();
int current = 0, last = 0;

while (!exit) {
try {
current = in.read();
}
catch (IOException e) {
System.out.println("Encountered IOException.");
}

if (current == -1)
break;
else if (current == (int) '\r') {
if(sb.toString().length() == 0) // Extra \r, don't return empty string.
continue;
fireInputRecieved(new String(sb.toString()));
sb = new StringBuilder();
}
else if(current == (int) '\n') {
if(sb.toString().length() == 0) // Extra \n, don't return empty string.
continue;
fireInputRecieved(new String(sb.toString()));
sb = new StringBuilder();
}
else {
System.out.println("Recieved character: " + (char)current);
sb.append((char) current);
last = current;
}
}
}
}

The CEcho class, which is the class that pipes it back to stdout:
public class CEcho implements InputStreamListener {
public void inputRecieved(String input) {
System.out.println("\n\nSTART INPUT RECIEVED");
System.out.println("The input that has been recieved is: "+input);
System.out.println("It is a String, that has been copied from a StringBuilder's toString().");
System.out.println("Outputting it cleanly to standard out: ");
System.out.println(input);
System.out.println("Outputting it cleanly to standard out again: ");
System.out.println(input);
System.out.println("Finished example outputs of input: "+input);
System.out.println("END INPUT RECIEVED\n\n");
}
}

And finally, here is the program output:
>psexec \\[A Remote Computer] "C:\Program Files\Java\jre1.6.0_05\bin\java.exe" -jar "C:\Documents and Settings\testProgram.jar"

PsExec v1.96 - Execute processes remotely
Copyright (C) 2001-2009 Mark Russinovich
Sysinternals - www.sysinternals.com


Starting up.
Successfully started up.  Awaiting input.
Test
Recieved character: T
Recieved character: e
Recieved character: s
Recieved character: t
Input string has made it to fireInputRecieved: Test


START INPUT RECIEVED
The input that has been recieved is: Test
It is a String, that has been copied from a StringBuilder's toString().
Outputting it cleanly to standard out:

Outputting it cleanly to standard out again:
Test
Finished example outputs of input: Test
END INPUT RECIEVED


Edited by dbingham - 14 August 2009 at 8:39pm
Back to Top
dbingham View Drop Down
Newbie
Newbie
Avatar

Joined: 14 August 2009
Location: New York
Status: Offline
Points: 3
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbingham Quote  Post ReplyReply Direct Link To This Post Posted: 21 August 2009 at 7:30pm
*bump* 

Anyone got any ideas, suggestions, comments?  We were going to try and build psexec into our product, but if it inconsistently passes input, that's a pretty major bug and pretty much excludes that.  Anyone know what's going on here?
Back to Top
molotov View Drop Down
Moderator Group
Moderator Group
Avatar

Joined: 04 October 2006
Status: Offline
Points: 17516
Post Options Post Options   Thanks (0) Thanks(0)   Quote molotov Quote  Post ReplyReply Direct Link To This Post Posted: 24 August 2009 at 2:43am
Hi Daniel,

In the PsTools FAQ, there are various similar reports from others that have attempted to use PsExec in a similar fashion.  A suggestion may be to attempt to make use of batch files containing PsExec commands, and redirect the output of them, and then parse that output...


Edited by molotov - 24 August 2009 at 2:44am
Daily affirmation:
net helpmsg 4006
Back to Top
dbingham View Drop Down
Newbie
Newbie
Avatar

Joined: 14 August 2009
Location: New York
Status: Offline
Points: 3
Post Options Post Options   Thanks (0) Thanks(0)   Quote dbingham Quote  Post ReplyReply Direct Link To This Post Posted: 09 September 2009 at 4:37pm
Hi Molotov, sorry for the absence.  I've done exactly that in essence.  It's still causing problems.  It doesn't consistently exit when the process it is used to call exists - and as a result I've been forced to try and read the output and error streams.  However, said streams are passing back output extremely inconsistantly.  And psexec frequently exits with the error code mentioned in another thread: [program called] exited on [remote machine] with error code -1073741786.  It's three separate programs all called with psexec all exit with that code and message.

Psexec's inconsistencies make it awfully frustrating to work with.  What gives?  Why isn't it just passing the output and error streams as it should?  Why doesn't it exit when the process it is running exits?



Edited by dbingham - 09 September 2009 at 4:37pm
Back to Top
molotov View Drop Down
Moderator Group
Moderator Group
Avatar

Joined: 04 October 2006
Status: Offline
Points: 17516
Post Options Post Options   Thanks (0) Thanks(0)   Quote molotov Quote  Post ReplyReply Direct Link To This Post Posted: 15 September 2009 at 4:39am
Have you tried to get things working in an environment that does not include the Java program, where the output is redirected and parsed manually?

That exit code is the code with which the process launched exits - psexec is not exiting with that code.  The code is "STATUS_INVALID_DISPOSITION" - "An invalid exception disposition was returned by an exception handler."  This suggests the program is crashing for some reason.  Perhaps there is some difference between the "common" environment, and the environment provided to PsExec, and the program is failing for some reason?  Are the programs Java programs?

Quote Why doesn't it exit when the process it is running exits?
Is AV software perhaps interfering with things?  Is something preventing communication with the remote system?  Is the service still running on the remote system? Is it removed after PsExec exits?


Daily affirmation:
net helpmsg 4006
Back to Top
 Post Reply Post Reply
  Share Topic   

Forum Jump Forum Permissions View Drop Down