May 05, 2024, 07:08:23 AM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


ERROR_BROKEN_PIPE

Started by Parker, May 27, 2006, 02:20:28 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Parker

May 27, 2006, 02:20:28 PM Last Edit: May 27, 2006, 02:28:30 PM by Parker
What could be causing that error? The code I'm using is this:
struct PROCESS_T
{
CommanderWnd *commander;
unsigned int hReadOut;
PROCESS_INFORMATION pi;
}

global sub DoCommand( CommanderWnd *commander, string command )
{
Dim si As STARTUPINFO;
Dim pi As PROCESS_INFORMATION;
Dim sa As SECURITY_ATTRIBUTES;
Dim hReadPipe=0 As unsigned int;
Dim hWritePipe=0 As unsigned int;
Dim bytesRead=0 As Int;
Dim result=0 As Int;
Dim totalBytes=0 As Int;
commander->ClearOutput( );
commander->SendOutputString( "Doing command\n" );

RtlZeroMemory( si, sizeof( STARTUPINFO ) );
RtlZeroMemory( pi, sizeof( PROCESS_INFORMATION ) );
RtlZeroMemory( sa, sizeof( SECURITY_ATTRIBUTES ) );

sa.nLength = Len(SECURITY_ATTRIBUTES);
sa.bInheritHandle = 1;

If CreatePipe(hReadPipe, hWritePipe, sa, 0) = 0
{
commander->SendOutputString( "Failed to create pipe..." );
Return;
}

si.cb = Len(STARTUPINFO);
si.dwFlags = 25 | 1;//STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
si.wShowWindow = 0;

If CreateProcess(0, command, sa, sa, 1, 0x00000020/*NORMAL_PRIORITY_CLASS*/, 0, 0, si, pi) = 0
{
commander->SendOutputString( "Failed to open..." );
Return;
}

CloseHandle( hWritePipe );

//TODO: Start a thread of PipeProc
PROCESS_T *pp;
pp = new( PROCESS_T, 1 );
pp->commander = commander;
pp->hReadOut = hReadPipe;
pp->pi = pi;

ThreadStart( &PipeProc, pp );
}

sub PipeProc( PROCESS_T *p )
{
Dim sBuffer[1024] As DString;
int bytesRead=0;
int totalBytes=0;
int result;
RtlZeroMemory( sBuffer, 1024 );

Do{
result = ReadFile(p->hReadOut, &sBuffer, 1024, &bytesRead, 0);
if( !result ) p->commander->SendOutputString( numtostr( GetLastError( ) ) );
p->commander->SendOutputString( strLeft(sBuffer, bytesRead) );
totalBytes += bytesRead;
}Until !result;
p->commander->SendOutputString( sprint( "\nRead ", totalBytes, " bytes" ) );

CloseHandle( p->pi.hProcess );
CloseHandle( p->pi.hThread );
CloseHandle( p->hReadOut );
}


Hmm, and the Aurora console version works fine ???
struct PROCESS_T
{
unsigned int hReadOut;
PROCESS_INFORMATION pi;
}

global sub DoCommand( string command )
{
Dim si As STARTUPINFO;
Dim pi As PROCESS_INFORMATION;
Dim sa As SECURITY_ATTRIBUTES;
Dim hReadPipe=0 As unsigned int;
Dim hWritePipe=0 As unsigned int;

print( "Doing command" );

RtlZeroMemory( si, sizeof( STARTUPINFO ) );
RtlZeroMemory( pi, sizeof( PROCESS_INFORMATION ) );
RtlZeroMemory( sa, sizeof( SECURITY_ATTRIBUTES ) );

sa.nLength = Len(SECURITY_ATTRIBUTES);
sa.bInheritHandle = 1;

If CreatePipe(hReadPipe, hWritePipe, sa, 0) = 0
{
print( "Failed to create pipe..." );
Return;
}

si.cb = Len(STARTUPINFO);
si.dwFlags = 25 | 1;//STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.hStdOutput = hWritePipe;
si.hStdError = hWritePipe;
si.wShowWindow = 0;

If CreateProcess(0, command, sa, sa, 1, 0x00000020/*NORMAL_PRIORITY_CLASS*/, 0, 0, si, pi) = 0
{
print( "Failed to open..." );
Return;
}

CloseHandle( hWritePipe );

//TODO: Start a thread of PipeProc
PROCESS_T *pp;
pp = new( PROCESS_T, 1 );
pp->hReadOut = hReadPipe;
pp->pi = pi;

ThreadStart( &PipeProc, pp );
}

sub PipeProc( PROCESS_T *p )
{
Dim sBuffer[1024] As DString;
int bytesRead=0;
int totalBytes=0;
int result;
RtlZeroMemory( sBuffer, 1024 );

Do{
result = ReadFile(p->hReadOut, &sBuffer, 1024, &bytesRead, 0);
if( !result ) print( "\n\nError: ", GetLastError( ) );
print( strLeft(sBuffer, bytesRead) );
totalBytes += bytesRead;
}Until !result;
print( "\nRead ", totalBytes, " bytes" );

CloseHandle( p->pi.hProcess );
CloseHandle( p->pi.hThread );
CloseHandle( p->hReadOut );
delete p;
}

global sub main( )
{
string command;
print(">> ",);
command=readln( );
DoCommand(command);
}

Ionic Wind Support Team

Windows programs don't get assigned stdio handles by the OS.  If you use the code I presented in the developers area you shouldn't have any problems.  You need the process atrributes from the running parent (assuming your IDE) assigned to the pipe or no data will flow.  Hence the DuplicateHandle calls.

In a console program Windows assigns stdio handles to the parent process and they will be shared by any pipes you create. 

Ionic Wind Support Team

Parker

Okay, thanks. I thought I could make the conversion easier on myself by converting a simple console program, but I guess not ;)