shura has asked for the wisdom of the Perl Monks concerning the following question:

Hi. I am trying to call some function like this :
sub my_function { local *STDOUT; open STDOUT , "> my_file"; my $proc; Win32::Process::Create($proc , 'c:\windows\system32\cmd.exe' , '/c dir +' , 1 , 0, "."); }
The problem is that Win32::Process::Create don't see the local redirected STDOUT , but only the global one. Does anyone knows how can I do in this case local redirection of STDOUT , in such way that in main program STDOUT will stay untouched and only my created process will inherit this local redirected handle. Thanks

Replies are listed 'Best First'.
Re: Win32::Process handle inheritance
by ysth (Canon) on May 13, 2008 at 08:20 UTC
    open(SAVEOUT, ">&STDOUT") before redirecting STDOUT and creating the process, and open(STDOUT, ">&SAVEOUT") and close SAVEOUT after.

      You also have to get rid of the local *STDOUT; (which hides away the current STDOUT which prevents file handle 1 from being reused which is all that C code and child processes care about).

      - tye        

        The real problem here is that the InheritHandles flag on CreateProcess() relates to OS handles (of all types), not Perl filehandles or C-runtime file numbers or FILE* structs. Nothing you do to the current process Perl handles or CRT handles will have any influence upon the created process at all.

        Setting the Inherit Handles flag will cause the process created to inherit access to exists OS handles of the current process. But in order for the new process to inherit redirections of it's STD_INPUT_HANDLE, STD_OUTPUT_HANDLE, or STD_ERROR_HANDLE handles, it is necessary to pass the handles that it should inherit as a part of the STARTUPINFO struct on the CreateProcess() and set the STARTF_USESTDHANDLES flag. Only then would the OS got the information required to make the appropriate redirection(s). This functionality is not visible via Win32::Process.

        I did manage to get this to work from Perl using Win32::API a couple of years ago, but that was before I upgraded my 0.41 installation. Since then, trying pretty much anything with Win32::API breaks :(

        That's problem when people with no real interest in the OS start messing with things just to try and make it so that other people with no real interest in the OS can avoid using it.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
      It is not working for Win32::Process::Create.
Re: Win32::Process handle inheritance
by Anonymous Monk on Jun 12, 2008 at 00:53 UTC
    I believe this does what you want, but not sure if this is a global or local redirect: Win32::Process::Create($ProcessObj, 'c:\WINDOWS\system32\cmd.exe', '/c dir /console /command bye > my_file', 0, NORMAL_PRIORITY_CLASS, ".")|| die ErrorReport() And yeah, I did not set all of the parameters the way you did, but should not matter
Re: Win32::Process handle inheritance
by Anonymous Monk on Apr 26, 2013 at 10:39 UTC

    use as the 4th argument (before cwd, before ".") Win32::Process::CREATE_NEW_CONSOLE()

    That will create a new process, with a new console, with a new stdin/stdout/stderr

    Don't use DETACHED_PROCESS as it will create a process without a console and without stdin/stdout/stderr

A reply falls below the community's threshold of quality. You may see it by logging in.