Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

Intended software: windows command line processor (version 6.1.7601.17514)

Hi,

I've been trying to build a multiple-statement command line that runs within a short-cut. My goal is to be able to click one short-cut that checks if my hosted network is started or not, and then takes appropriate action based on the check. The code that starts and stops the hosted network is fine, and for the most part, the logic works, but I notice odd behavior when I check the outputs of the logic. I suspect that my problem has to do with the way I structured the statements, but I'm having difficulty properly interpreting the built-in documentation and the documentation I can find in the MSDN library. If it's possible, I want to avoid using batch files for this solution.

To keep things simple, I've substituted my lengthy "netsh" commands with "echo" commands that show the errorcode. The code below is what I'm using to test my logic:

Test Code

netsh wlan show hostednetwork | find "Not" && echo found %errorlevel% || echo lost %errorlevel%

Currently, the way I'm reading this is:

  1. Show me hostednetwork's status and send the output to input
  2. Attempt to find the string "Not" in the input
  3. If the attempt succeeds, output "found" and the errorcode to the screen
  4. If the attempt fails, then output "lost" and the errorcode to the screen

Notice that I'm not using any flags on the find command. I'm doing this because I want to reduce the chance of finding a false match. To clarify what I mean, I'll show the output if I just put in
netsh wlan show hostednetwork:

Sample Output of Hostednetwork Status

C:\Windows\system32>netsh wlan show hostednetwork

Hosted network settings
-----------------------
    Mode                   : Allowed
    SSID name              : "TestHost"
    Max number of clients  : 100
    Authentication         : WPA2-Personal
    Cipher                 : CCMP

Hosted network status
---------------------
    Status                 : Not started

If I search for the string "Not", then that's sufficient to tell me that the hosteadnetwork is not started, because when the hosteadnetwork is started, the output shows "Started".

The way I'm simulating the conditions of the hostednetwork is with the following commands:

netsh wlan start hostednetwork
netsh wlan stop hostednetwork

I expect that when I open a command prompt (as an administrator):

  1. If the hostednetwork is not started, I should see a "found 0" in the output, meaning that the string was found and that there were no errors.
  2. If the hostednetwork is started, I should see a "lost 1" in the output, meaning that the string was not found and that there was an error.

Case #1 works, but case #2 doesn't work on the first try. Here's my output when the hostednetwork is already started:

Output With Hostednetwork Started

C:\Windows\system32>netsh wlan start hostednetwork
The hosted network started.


C:\Windows\system32>netsh wlan show hostednetwork | find "Not" && echo found %er
rorlevel% || echo lost %errorlevel%
lost 0

C:\Windows\system32>netsh wlan show hostednetwork | find "Not" && echo found %er
rorlevel% || echo lost %errorlevel%
lost 1

Other Attempted Solutions

The way I've written the test code is the best I could come up with so far. In previous attempts, I've tried:

  1. Setting a custom variable instead of using the errorlevel variable, but I get the same output on case #2.
  2. Changing the code into an if else equivalent, but that didn't pan out very well.
  3. Wrapping the conditional statements in brackets "()" after the pipe and using different combinations of the special symbols "&" and "|".

Other Questions

This question is related to another that I've been trying to figure out. If I wanted to search for three different strings in a command's output and exit on a different error code for each string, how can I do this? The syntax below is my starting point:

myCommand [/options] | ((find "string1" && exit /b 2 || ver>nul) && 
(find "string2" && exit /b 3 || ver>nul) && (find "string3" && exit /b 4 || ver>nul))

For the same reasons above, I didn't use any flags on the "find" commands. Also, I used "ver>nul" in an attempt to keep the syntax correct since I know the "ver" operation succeeds.

Any assistance is appreciated.

share|improve this question
1  
Just out of curiosity (I don't know the answer to your question): why don't you try to do this in Powershell / C# / VB? You could just run each command, check the exit codes and decide what / how to run next. You'd probably have an easier time. –  xxbbcc Jun 8 '13 at 5:03
 
I think you were addressing my other question. I didn't try the syntax in C# or Powershell because I haven't learned those languages yet. The reason why I haven't tried the syntax in VB is that the "myCommand" is part of the PuTTY Telnet tools and from what I understand, I cannot run the operation directly, I have to run them through the command line. Then again, I should try it anyway. –  user2465349 Jun 8 '13 at 5:14
 
You can run command-line programs / batch files from within VB and you can get the exit code using the System.Diagnostics.Process class. (Exit code is the same as errorlevel in a batch file. Based on that, you can then make decisions about next steps. –  xxbbcc Jun 8 '13 at 5:16
 
To parse the output of a program, just redirect the console programs to text files and then read the files in VB and do the search. I'm not familiar with PuTTY so it may make it very hard to do this but in general it's easy to run command-line tools from VB code. –  xxbbcc Jun 8 '13 at 5:18
 
I think I misunderstood you. At the moment, I'm coding in VBA within excel, not VB, so the System.Diagnostics.Process is not available. I've read that I could install the "Visual Studio Tools for Office (VSTO)" package, which would allow me to use VB tools in excel, but I would rather not incorporate more software to do the searches. Also, I want to avoid using batch files. –  user2465349 Jun 9 '13 at 0:06
add comment

2 Answers

up vote 0 down vote accepted

I don't understand why you want to avoid use of a batch script. Your shortcut can simply point to a small batch script, and life will be much easier.

But it is possible to do what you want. The value of %errolevel% is determined during parsing, and the entire shortcut is parsed in one pass, so you get the value that existed prior to execution of your FIND commands. You need delayed expansion !errorlevel! to get your desired results.

In batch you use setlocal enableDelayedExpansion, but that does not work from the command line (or a shortcut). Instead you must instantiate an extra CMD.EXE with the /V:ON option.

netsh wlan show hostednetwork | cmd /v:on /c "find "Not" && echo found !errorlevel! || echo lost !errorlevel!"

There are multiple levels of quoting going on, and that can sometimes cause problems. You can eliminate the quotes enclosing the command if you escape the special characters.

netsh wlan show hostednetwork | cmd /v:on /c find "Not" ^&^& echo found !errorlevel! ^|^| echo lost !errorlevel!



Regarding your 2nd question, I see 2 problems.

1) I don't understand the point of having a shortcut designed to exit with different error codes. How can you possibly make use of the returned error code?

2) You cannot pipe content into multiple FIND commands. The first FIND command will consume all the content and close the pipe, and then subsequent FIND commands will wait indefinitely for content from the keyboard.

You would have to redirect your command output to a temp file, and then redirect input of each FIND command to the temp file.

share|improve this answer
 
Both of your code blocks worked. I did try the setlocal enableDelayedExpansion approach before posting here, but as you've explained, that doesn't work without using a batch file. –  user2465349 Jun 9 '13 at 1:03
 
As for my 2nd question, I knew that the first FIND command closes the pipe since I get the correct output if I only used one FIND command. However, I was trying to show what I was attempting. I want to see if using curly braces {} would work, but I don't know the proper syntax and I think I'll run into the same piping problem as before. Regardless, my main question is solved. The second question was more of a wishful extension of the first. –  user2465349 Jun 9 '13 at 1:17
add comment

You cannot evaluate a variable in the same line. It needs delayed expansion and !errorlevel! to be used.

Do it in a batch file and you won't have a problem using delayed expansion.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.