Section 7.1. Invoke Commands with


7.1. Invoke Commands with &

If you've been exploring the shell, you may have noticed that MSH and cmd.exe treat filenames differently. For example, if a file is dragged from Explorer onto the command prompt window in MSH, the window still acts as though the filename were typed in, but the behavior can differ.

For example, dragging a file HelloWorld.exe from the folder D:\Apps in an Explorer window onto either a cmd.exe or MSH window will result in "D:\Apps\HelloWorld.exe" being typed at the prompt. However, Examples 7-1 and 7-2 show how the two shells differ in their interpretation of the action.

Example 7-1. Entering a fully qualified path in cmd.exe
 D:\> "D:\Apps\HelloWorld.exe" Hello, World!

Example 7-2. Entering a fully qualified path in MSH
 MSH D:\MshScripts> "D:\Apps\HelloWorld.exe" D:\Apps\HelloWorld.exe

cmd.exe is running the program, whereas MSH is happy to echo back the string that it's just been given. This difference can be reconciled with the ampersand (&) syntax, which forces MSH to interpret a string as a command.

7.1.1. How Do I Do That?

MSH treats anything enclosed in quotation marks as a string. Even if it looks like a path, cmdlet name, alias, or function, MSH will not give material enclosed in quotation marks any special treatment.

Prefixing a string with the & character tells MSH that the string immediately following it is to be run as either an alias, cmdlet, function, script, or executable, following exactly the same execution rules we saw in Chapter 2:

     MSH D:\MshScripts> & "D:\Apps\HelloWorld.exe"     Hello, World!

The string must contain only the command to be executed, and any options to the command should be supplied separately. Otherwise, MSH tries to find the whole thingcommand, options, and allwhich doesn't usually have the desired effect:

     MSH D:\MshScripts> & "get-help new-object"     : 'get-help new-object' is not recognized as a Cmdlet, function, operable program,  or script file.     At line:1 char:2     + &" <<<< get-help new-object"     MSH D:\MshScripts> & "get-help" new-object     NAME         new-object     SYNOPSIS         [-TypeName] type-name                     [[-Arguments] arguments]                     [-AssemblyName]                     [-FileName]     ...

Many command-line tools use an errorlevel or exit code to indicate success, failure, or some additional status after the program has run. A common technique in cmd.exe batch file authoring involves a statement such as IF errorlevel 3 GOTO label, which allows a batch file to make a decision based on the outcome of an external program. This same information is available to MSH scripts by way of the $LASTEXITCODE global variable:

     MSH D:\MshScripts> ping nonexistenthost     Ping request could not find host foo. Please check the name and try again.     MSH D:\MshScripts> $lastexitcode     1     MSH D:\MshScripts> ping 127.0.0.1     Pinging 127.0.0.1 with 32 bytes of data:     Reply from 127.0.0.1: bytes=32 time<1ms TTL=128     Reply from 127.0.0.1: bytes=32 time<1ms TTL=128     Reply from 127.0.0.1: bytes=32 time<1ms TTL=128     Reply from 127.0.0.1: bytes=32 time<1ms TTL=128     Ping statistics for 127.0.0.1:         Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),     Approximate round trip times in milli-seconds:         Minimum = 0ms, Maximum = 0ms, Average = 0ms     MSH D:\MshScripts> $lastexitcode     0

7.1.2. What Just Happened?

Here we've seen one of the subtle yet significant differences between MSH and cmd.exe. For consistency, MSH treats all objects in a predictable manner. In the case of a filename, MSH is unable to distinguish whether the intent is to run an executable or just store a string that points to it. More information is needed (in the form of an &) to indicate to the shell that it should treat the string differently. It should come as no surprise that if Tab completion in MSH results in a quoted string (which will happen if there are spaces in the path or filename), the shell automatically prefixes it with &, and therefore ensures that the command shell tries to run the executable as expected.

Error and exit codes have been used for a long time as a medium for a command-line tool to pass on some information about its execution, and they are usually used to determine exactly what (if anything) went wrong. While it serves this purpose well enough, there is a limit to the amount of useful information that can be captured in a single number. With MSH, we generally find that cmdlets report information in the type and number of objects they return, leaving little need for an additional exit code. However, when interoperating with other command-line tools, the value of an exit code can be critical to further decision making. Because the $lastexitcode variable is updated with every external program that is run, make sure to check it immediately after running each external command when running several in sequence. Otherwise, you'll only be able to see the status of the last one. While MSH updates this variable automatically when an external command is run, MSH cmdlets and scripts can also modify it by a simple assignment, which can be useful for testing purposes.

7.1.3. What About ...

How do I start a program associated with a file extension? In cmd.exe, typing the name of a nonexecutable file (for example, a Word document) has the same effect as double-clicking the file from Explorernamely, its associated application is started and the document is loaded. The & symbol is used only for starting executable programs in MSH and does not offer the same behavior. Instead, the invoke-item cmdlet should be used on the file to emulate this behavior. invoke-item . is identical to the cmd.exe start . command. The get-command cmdlet can be used with a wildcard (get-command *) or partial wildcard (get-command *txt) to show a list of all possible invocations in the current environment.




Monad Jumpstart
Monad Jumpstart
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 117

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net