IPC :: Open3. Solving the problem with STDERR

    When we write a graphical application, it happens that you need to call external programs and read from STDOUT / STDERR.
    The IPC :: Open3 module does an excellent job of this .

    However, the program you wrote, everything works, but you do not want the user (or you) to see an unnecessary terminal window.

    There are several options to hide it:

    1. Run the script through wperl.exe, and not through perl.exe
    2. ???

    Consider the program
    use strict;
    use Tkx;
    use IPC :: Open3;
    my $ mw = Tkx :: widget-> new ('.');
    my $ tw = $ mw-> new_text ();
    my $ bt = $ mw-> new_ttk__button (
        -text => 'dir',
        -command => sub {
            my ($ rdr, $ pid);
            $ pid = open3 (undef, $ rdr, undef, 'dir');
            $ tw-> insert ('end', do {local $ /; <$ rdr>});
    Tkx :: pack ($ tw);
    Tkx :: pack ($ bt);
    Tkx :: MainLoop;


    The dir command is called, and its result is displayed. (ignore the encoding).

    Everything works, but if you run the script through wperl.exe, then when you call open3 you get an error:
    open3: Can't call method "close" on an undefined value at C: /perl5.8/lib/IPC/Open3.pm line 368.
    open3: Can't call method "close" on an undefined value at C: /perl5.8/lib/IPC/Open3.pm line 368.

    The problem is that wperl does not create standard threads (STDIN, STDOUT, STDERR).

    I puzzled for a long time how to make the program work. I tried to call WINAPI inside the body of the program, run the file via bat (it works, but not with all programs), but the solution turned out to be a simple surprise.

    You must use the ShellExecute function from shell32.dll with the SW_HIDE attribute.

    Below is the loader code in C.
    static char * ldr_file = "app.pl";
    static char * ldr_path = "";
    int main (int argc, char * argv [])
      int code;
      LoadLibrary ("shell32.dll");
      code = (int) ShellExecute (NULL, "open", ldr_file, ldr_path, NULL, SW_HIDE);
      if (code <= 32)
    	char buf [200];
    	sprintf (buf, "Cannot run application. Code:% d", code);
    	MessageBox (
    		"Dynld Error",
      return code;

    Compile gcc from MinGW.
    gcc -mwindows loader.c -o loader.exe

    Also popular now: