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

Brethern --

I want to get the results of the windows program tlist.exe in a variable. This is easily accomplised by doing:

$tlist = `tlist`;

And if it is perl.exe that is running the script, the tlist window never shows up. If I run it with wperl.exe, the tlist window flickers up and disappears.

How can I get the results of tlist into a variable while my script is running under wperl.exe without the tlist window showing up?

I have tried using Win32::Process but 1.) I can't get it to start tlist in a non-windowed environment and 2.) I don't know how I could even get the results of the "forked" tlist back in my original script.

use Win32::Process; Win32::Process::Create($ProcessObj, "C:\\windows\\system32\\tlist.exe", "", 0, "CREATE_NO_WINDOW, ".")|| die ErrorReport();
Any light that could be shed would be greatly appreciated!

Thanks,
Matt

Replies are listed 'Best First'.
Re: Hiding programs launched within wperl'd script
by BrowserUk (Patriarch) on Jan 17, 2006 at 22:24 UTC

    Try

    $tlist = `start /b tlist`;

    That said, you might consider using Win32::Process::Info to obtain the information you're after.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Hey BrowserUK --

      I tried $tlist = `start /b tlist`; on XP and it still fires off the tlist window when run from wperl.exe. Just realized, I think I'm seeing the "start" window doing it this way...same problem.

      Also, I originally was using Win32::Process::Info but the overhead to fire that up is insane compared to tlist. It seriously takes about 20 times the juice to do this.

      I'd like to know how to do this for my own edification so that in the future I can fire off other programs I might shell out to without their windows coming up; however, my goal for this project is to check every 5 seconds or so to see if a program is running.

      So if there is a low overhead way to do this, I'd love to know...I've thought I could write some daemon that keeps track of process info that I could connect to and read data from or read a text file from...but this seems like overkill for something so simple. Using Win32::Process::Info it ate 20% of my CPU...tlist took 1% sometimes.

      Many thanks for your ideas!
      Matt

        In a wperl.exe app, I run the following at startup:
        my $AllocConsole = new Win32::API('kernel32', 'AllocConsole', [] , 'N' +); my $GetConsoleWindow = new Win32::API('kernel32', 'GetConsoleWindow', +[] , 'N'); my $ShowWindow = new Win32::API('user32', 'ShowWindow', ['N','I'] , 'N +'); my $apival = $AllocConsole->Call(); if($apival) { my $console = $GetConsoleWindow->Call(); my $hidewindow = 0; my $rval = $ShowWindow->Call($console, $hidewindow); }
        So I've now got a hidden console window that any console apps I call will run in. The console may flash once on app startup, but after that you're OK.
Re: Hiding programs launched within wperl'd script
by Sioln (Sexton) on Jan 18, 2006 at 06:52 UTC
    `tlist > somefile`; open DATA, 'somefile'; @tlist=<DATA>; close DATA; unlink 'somefile';

    Works?

      Sorry, no, it does the same shelling out which spawns a window...pretty much the same as `tlist`...thanks, though!
Re: Hiding programs launched within wperl'd script
by glasswalk3r (Friar) on Jan 18, 2006 at 12:14 UTC

    You may want to try IPC::Open3 at your MS Windows box, but I'm afraid it will not work as expected.

    Alceu Rodrigues de Freitas Junior
    ---------------------------------
    "You have enemies? Good. That means you've stood up for something, sometime in your life." - Sir Winston Churchill
Re: Hiding programs launched within wperl'd script
by bravenmd (Sexton) on Jan 18, 2006 at 17:45 UTC
    To answer the first question try:
     use Win32::Process;
     Win32::Process::Create($ProcessObj,"C:\\windows\\system32\\tlist.exe","tlist",0,"CREATE_NO_WINDOW,".")|| die ErrorReport();

      bravenmd --

      I was about to say I couldn't get tlist to spawn without a window but this works! Other users, remove the errant double quote before CREATE_NO_WINDOW. Still, do you know how to capture the output of tlist from this, though?

      Thanks for all the great help, monks!!! I love perlmonks (the site, that is)!

Re: Hiding programs launched within wperl'd script
by BrowserUk (Patriarch) on Jan 20, 2006 at 03:58 UTC

    mdog Sorry for the delay. I knew I'd seen this somewhere, but for the life of me couldn't remember what and where. Having googled and googled, I finally found that I had referred to this here once before. All credit goes to Jenda, not me.

    If you add the following code to your wperl scripts, using backticks will o longer cause that annoying flash as the console appears and disappears.

    BEGIN { Win32::SetChildShowWindow(0) if defined &Win32::SetChildShowWindow };

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      BrowserUK to the rescue! Again!

      Thanks to Jenda for figuring this out and putting it on the internet(s) and thanks to you, BrowserUK, for taking the time to track this down and post it!

      Works like a charm!