Using Win32::API To call CreateProcess - help!

Discussion in 'Perl Misc' started by Chris Lowth, Jul 2, 2003.

  1. Chris Lowth

    Chris Lowth Guest

    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 );
    }


    --
    Real address: chris at lowth dot sea oh em.
    World's first wrist-watch PDA with Palm OS, available June 30
    from Amazon.com. Order now to beat the rush!
    http://www.lowth.com/shop/wrist_pda
     
    Chris Lowth, Jul 2, 2003
    #1
    1. Advertising

  2. Chris Lowth <> wrote in message news:<yvAMa.1017$>...
    > 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,

    <snip some stuff>
    > )");
    >
    > $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>
     
    Bryan Castillo, Jul 2, 2003
    #2
    1. Advertising

  3. Chris Lowth

    Chris Lowth Guest

    Bryan Castillo wrote:

    > Chris Lowth <> wrote in message
    > news:<yvAMa.1017$>...
    >> 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,

    > <snip some stuff>
    >> )");
    >>
    >> $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
    --
    Real address: chris at lowth dot sea oh em.
    World's first wrist-watch PDA with Palm OS, available June 30
    from Amazon.com. Order now to beat the rush!
    http://www.lowth.com/shop/wrist_pda
     
    Chris Lowth, Jul 2, 2003
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Kroum Grigorov
    Replies:
    1
    Views:
    701
    Christopher Benson-Manica
    Apr 26, 2004
  2. Elly Sokol

    CreateProcess

    Elly Sokol, Jun 17, 2004, in forum: C++
    Replies:
    13
    Views:
    4,416
    Frederic Banaszak
    Jun 18, 2004
  3. Baskar

    Createprocess

    Baskar, Jan 20, 2005, in forum: C++
    Replies:
    1
    Views:
    449
    Victor Bazarov
    Jan 20, 2005
  4. Replies:
    1
    Views:
    3,707
    Roland de Ruiter
    Jun 28, 2006
  5. Achim Domma

    CreateProcess / redirect output

    Achim Domma, May 28, 2004, in forum: Python
    Replies:
    2
    Views:
    7,203
    Achim Domma
    May 28, 2004
Loading...

Share This Page