Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Invoking the Windows command line for selected directories

by spurperl (Priest)
on Nov 27, 2006 at 18:26 UTC ( [id://586301]=CUFP: print w/replies, xml ) Need Help??

To anyone who is doing development on Windows platforms...

A very common task I must do from time to time is open the command-line ("cmd") in some directory. The path I usually take is run "cmd" via Start -> Run and then copy and paste the directory path into it, with an appropriate "cd". Of course, Windows' drive rules suck and in addition to the "cd" you must sometimes make it change a drive by typing "c:" or "d:".

Today I found a solution. It's so simple and obvious I can't imagine how I didn't see it before. I wrote a Perl script that reads what's in the clipboard buffer and just runs 'cmd' with an appropriate drive change and "cd" into that directory. Placing a shortcut to the script into the Quicklaunch bar makes opening "cmd" in the desired place only one Ctrl-C and one mouse click away. It doesn't get shorter than this :-)

Anyway here is the script:

use warnings; use strict; $|++; use Win32::Clipboard; # Take the path from the clipboard # my $clip = Win32::Clipboard(); my $path = $clip->Get(); # Does it look like a valid path ? # if ($path !~ /^([a-z]) :/xi) { die "$path\ndoesn't look like a path\n"; } # The drive letter must be gathered separately to issue a drive # change command # my $drive = $1; my $BAT_FILENAME = 'crun.bat'; open(my $ofh, ">", $BAT_FILENAME) or die $!; print $ofh "${drive}:\n"; print $ofh "cd $path\n"; print $ofh "cmd\n"; close($ofh); # Run ! # system($BAT_FILENAME);

One question though... I recall that on Unixes one can create a child and then detach it, allowing the parent process to exit with the child staying alive. Is there a way to do it on Windows ? The problem with this script is that a perl process stays alive while the "cmd" window is open. It doesn't take any CPU so it's not a big deal, but still I yearn for something cleaner. Any ideas ?

Replies are listed 'Best First'.
Re: Invoking the Windows command line for selected directories
by xdg (Monsignor) on Nov 27, 2006 at 19:18 UTC

    Not Perl, but similarly handy is the "Open Command Window Here" PowerToy free from Microsoft.

    Another fun thing is "start some_dir" from the command line to pop up a file explorer for that directory. (E.g. "start ." to see the explorer for the current directory).

    start has other neat uses. Given a filename, it will open the file up the default app for that filetype. Handy for .html files, for example. Type "help start" at the command line for more details.

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      Hi

      The "power toy" is a registry entry
      Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Folder\shell\cmd] [HKEY_CLASSES_ROOT\Folder\shell\cmd\Command] @="cmd.exe /K \"cd %L\""
      and is insanely useful. To be able to right-click on the directory and pop the command line saves a great deal of time.

      Getting a bash shell would probably be even better.

      Windows Registry Editor Version 5.00 [HKEY_CLASSES_ROOT\Folder\shell\bash shell] [HKEY_CLASSES_ROOT\Folder\shell\bash shell\Command] @="cmd /C \"cd /d %L && c:\\cygwin\\bin\\bash.exe\""

      Analogously on OS X you can use the open command to perform similar tasks (open a directory in the Finder, or open a file with either its default application or a specified application (via the -a flag)). See man 1 open for more details.

Re: Invoking the Windows command line for selected directories
by ikegami (Patriarch) on Nov 27, 2006 at 18:43 UTC

    (Update: Once you solve your problem, you might want to use wperl instead of perl. ActivePerl's wperl is identical to their perl, except it doesn't open a console window. By using wperl, you won't see the console blink in and out. )

    When I misread your problem, I thought you might have found the following batch file useful.

    (Update: Corion just informed me that cd /d drive:\path does the same as the following. )

    @echo off if (%1)==() ( cd goto Exit ) if (%1)==(/?) goto Usage if not (%2)==() goto Usage for %%p in (%1) do ( %%~dp cd "%%~fp" ) goto Exit :Usage echo usage: %0 [ {rel_path} / {abs_path} ] echo. echo Switches to current drive and the current dir to those echo of the supplied path. echo. echo If no argument is supplied, displays the current dir. :Exit
    You can use it as follows:
    mycd d:\
    mycd "C:\Program Files"
    # Start a shell in d:\ cmd /k mycd d:\
    # Start a command in d:\ cmd /c mycd d:\ & mycommand args
Re: Invoking the Windows command line for selected directories
by BrowserUk (Patriarch) on Nov 27, 2006 at 18:39 UTC
    Any ideas ?

    Make that last line system( 1, $BAT_FILENAME); and the script will terminate leaving the shell running.


    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.
      This works ! But unfortunately I don't understand how :-(

      Can't find anything coherent in the documentation of system and exec. perldoc just says:

      If there is more than one argument in LIST, or if LIST is an array with more than one value, starts the program given by the first element of the list with arguments given by the rest of the list.
      Although this only makes things less clear.

      Where can I read the documentation about your solution ?

        Um. Off the top of my head, I don't know where it actually documented. It's one of those things that I picked up by osmosis through reading PM. Probably from tye. He's the source of most of the useful stuff regarding Perl and Win32 around here.

        As for how it works, that's fairly easily explainable. It is a Win32-only special case coded into the sources. If the first argument to system is (exactly) '1', then the code adds the CREATE_NEW_PROCESS_GROUP flag to the creation flags parameter passed to CreateProcess(), which has the required effect of 'detaching' the process created from it's parent.

        See also Re: How does system(1,"foo") work on Windows?.


        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.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: CUFP [id://586301]
Approved by Corion
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-18 04:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found