Using Win32::API To call CreateProcess - help!

C

Chris Lowth

I need to call the "real" CreateProcess of windows NT from an ActiveState
perl script. The code below always reports a return of 0 (FALSE) and fails
to start "notepad". Where as the matching C code (also listed) works fine.

I cant see what's wrong myself - has anyone got this to work, and if so -
can you see what is wrong with the script?

---------- perl --------------
[ This doesnt work ]

use Win32::API;

Win32::API::Struct->typedef( "STARTUPINFO", qw(
DWORD cb;
LPTSTR lpReserved;
LPTSTR lpDesktop;
LPTSTR lpTitle;
DWORD dwX;
DWORD dwY;
DWORD dwXSize;
DWORD dwYSize;
DWORD dwXCountChars;
DWORD dwYCountChars;
DWORD dwFillAttribute;
DWORD dwFlags;
WORD wShowWindow;
WORD cbReserved2;
LPBYTE lpReserved2;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
) );

Win32::API::Struct->typedef( "PROCESS_INFORMATION", qw(
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
) );

my $CreateProcess = Win32::API->new( "kernel32", "
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPVOID lpProcessAttributes,
LPVOID lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCTSTR lpCurrentDirectiry,
LPSTARTUPINFO lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)");

$cmd = "c:\\winnt\\notepad.exe";
$dir = ".";

my $si = Win32::API::Struct->new( "STARTUPINFO" );
my $pi = Win32::API::Struct->new( "PROCESS_INFORMATION" );
$rtn = $CreateProcess->Call(undef, $cmd, undef, undef, 0, 0, undef, $dir,
$si, $pi);

print "rtn = $rtn\n";

------------- and now in C -------------------
[ This works ]

#include <windows.h>

void ErrorExit( char *str )
{
printf("ERROR: %s\n", str);
exit(2);
}

void main( VOID )
{
STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

// Start the child process.
if( !CreateProcess( NULL, // No module name (use command line).
"c:\\winnt\\notepad.exe", // Command line.
NULL, // Process handle not inheritable.
NULL, // Thread handle not inheritable.
FALSE, // Set handle inheritance to FALSE.
0, // No creation flags.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory.
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
)
{
ErrorExit( "CreateProcess failed." );
}

// Wait until child process exits.
WaitForSingleObject( pi.hProcess, INFINITE );

// Close process and thread handles.
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
}
 
B

Bryan Castillo

Chris Lowth said:
I need to call the "real" CreateProcess of windows NT from an ActiveState
perl script. The code below always reports a return of 0 (FALSE) and fails
to start "notepad". Where as the matching C code (also listed) works fine.

I cant see what's wrong myself - has anyone got this to work, and if so -
can you see what is wrong with the script?

---------- perl --------------
[ This doesnt work ]

use Win32::API;

Win32::API::Struct->typedef( "STARTUPINFO", qw(
DWORD cb;
<snip some stuff>
HANDLE hStdError;
) );

Win32::API::Struct->typedef( "PROCESS_INFORMATION", qw(
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
) );

my $CreateProcess = Win32::API->new( "kernel32", "
BOOL CreateProcess(
LPCTSTR lpApplicationName,
)");

$cmd = "c:\\winnt\\notepad.exe";
$dir = ".";

my $si = Win32::API::Struct->new( "STARTUPINFO" );
my $pi = Win32::API::Struct->new( "PROCESS_INFORMATION" );
$rtn = $CreateProcess->Call(undef, $cmd, undef, undef, 0, 0, undef, $dir,
$si, $pi);

print "rtn = $rtn\n";


There is a module Win32::process you should use instead.
The documentation for it has an example running notepad.


<snip the C>
 
C

Chris Lowth

Bryan said:
Chris Lowth said:
I need to call the "real" CreateProcess of windows NT from an ActiveState
perl script. The code below always reports a return of 0 (FALSE) and
fails to start "notepad". Where as the matching C code (also listed)
works fine.

I cant see what's wrong myself - has anyone got this to work, and if so -
can you see what is wrong with the script?

---------- perl --------------
[ This doesnt work ]

use Win32::API;

Win32::API::Struct->typedef( "STARTUPINFO", qw(
DWORD cb;
<snip some stuff>
HANDLE hStdError;
) );

Win32::API::Struct->typedef( "PROCESS_INFORMATION", qw(
HANDLE hProcess;
HANDLE hThread;
DWORD dwProcessId;
DWORD dwThreadId;
) );

my $CreateProcess = Win32::API->new( "kernel32", "
BOOL CreateProcess(
LPCTSTR lpApplicationName,
)");

$cmd = "c:\\winnt\\notepad.exe";
$dir = ".";

my $si = Win32::API::Struct->new( "STARTUPINFO" );
my $pi = Win32::API::Struct->new( "PROCESS_INFORMATION" );
$rtn = $CreateProcess->Call(undef, $cmd, undef, undef, 0, 0, undef, $dir,
$si, $pi);

print "rtn = $rtn\n";


There is a module Win32::process you should use instead.
The documentation for it has an example running notepad.


<snip the C>

Thanks for the reply. Yes I looked at Win32::process, but it isnt rich
enough for my needs. I want to be able to "play" with the Standard file
handles passed in the STARTUPINFO structure - and Win32::process does
provide this facility - which is why I am trying to use Win32::API.

So I am still stuck - does anyone have a working example you'd be happy to
share?

Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top