Batch - Default Browser? - batch-file

Is there a way for using a batch file to find the default browser on my computer?

Simply use
start www.google.com
See here

If you're looking for a Windows .bat solution, this should work on Windows 2000 and later:
reg QUERY HKEY_CLASSES_ROOT\htmlfile\shell\open\command /ve
Result (on my Windows machine)
HKEY_CLASSES_ROOT\htmlfile\shell\open\command
(Default) REG_SZ "C:\Program Files (x86)\Internet Explorer\iexplore.exe" -nohome
See the REG.EXE help for more information:
REG /?

It is impossible to do this 100% correct in a batch file since the default command could come from a COM object and not a string in the registry (MayChangeDefaultMenu will force IContextMenu to be called for double-clicks and could change the default action)
Here is some code that tries to do the right thing (The fallback verb is open, it really should be the first subkey, but I did not feel like dealing with that)
#echo off
setlocal ENABLEEXTENSIONS
set progid=htmlfile&set verb=open&set browsercmd=
FOR /F "skip=2 tokens=2 delims=_" %%a IN ('2^>nul REG QUERY "HKCR\.html" /ve^|find /V ""^|find /V "HKEY_"') DO FOR /F "tokens=1,*" %%b IN ("%%~a") DO if not "%%~c"=="" set progid=%%~c
FOR /F "skip=2 tokens=2 delims=_" %%a IN ('2^>nul REG QUERY "HKCR\%progid%\shell" /ve^|find /V ""^|find /V "HKEY_"') DO FOR /F "tokens=1,*" %%b IN ("%%~a") DO if not "%%~c"=="" set verb=%%~c
FOR /F "skip=2 tokens=2 delims=_" %%a IN ('2^>nul REG QUERY "HKCR\%progid%\shell\%verb%\command" /ve^|find /V ""^|find /V "HKEY_"') DO FOR /F "tokens=1,*" %%b IN ("%%~a") DO if not "%%~c"=="" set browsercmd=%%c
echo.DefaultBrowser=%browsercmd%
This code probably has problems, but at least it tries to find the correct verb. You also have to deal with the fact that the returned string could contain "%1".
If all you really want to do is open a URL, all you need is start http://example.com
If you want to open the browser, but not a specific URL, a ugly hack like start "" http://about:blank might just work.

I hope this helps someone. I needed to start the default browser with a html file.
#echo off
setlocal
rem setup a default browser in case we fail
set default_browser=C:\Program Files\Internet Explorer\iexplore.exe
rem look in the HKEY_CLASSES_ROOT\htmlfile\shell\open\command registry for the default browser
for /f "tokens=*" %%a in ('REG QUERY HKEY_CLASSES_ROOT\htmlfile\shell\open\command /ve ^| FIND /i "default"') do (
set input=%%a
)
setlocal enableDelayedExpansion
rem parse the input field looking for the second token
for /f tokens^=^2^ eol^=^"^ delims^=^" %%a in ("!input!") do set browser=%%a
setlocal disableDelayedExpansion
rem this may not be needed, check if reg returned a real file, if not unset browser
if not "%browser%" == "" if not exist "%browser%" set browser=
if "%browser%"=="" set browser=%default_browser%
"%browser%" index.html
endlocal

This code will set the Environment variable browser to FirefoxURL which gives you a good indicator:
#ECHO OFF
REG QUERY HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice > browser.txt
FOR /F "skip=2 tokens=*" %%G IN (browser.txt) DO ( SET browser=%%G )
SET browser=%browser:~20%
ECHO Is: %browser%
It works by querying the registry to a text file then skipping the first two lines (useless for your purposes), then taking the text that starts at the 20th character of te remaining line. Which gives you FirefoxURL

Andy E's answer does not seem to work for me, it opens IE instead of Chrome.
But, if I use http instead of htmlfile it does. Like this.
reg QUERY HKEY_CLASSES_ROOT\http\shell\open\command /ve

bubble's answer has some caveats.
This is what works in much more cases for me:
start "" explorer "protocol://your.complicated/url?foo=bar"
The only thing you have to escape is a double quote, and you escape it by typing it once more.
Works at least for protocols http://, https:// and file:// (without query string). Doesn't work for ftp:// URLs (it opens them as a network drive).
Fail cases of the accepted answer
First, the webpage has to start with www.
rem Works
start www.google.com
rem FAILS!
start google.com
The system cannot find the file google.com
rem FAILS!
start translate.google.com
The system cannot find the file translate.google.com
This can be fixed by prepending http://
rem Works
start http://google.com
rem Works even for file:// protocol
start file://C:/test/main.html
rem Works - you can even pass QSA
start http://google.com?foo=bar
rem FAILS! outch, you have to escape ampersands
start http://google.com?foo=bar&baz=baz
'baz' is not recognized as an internal or external command, operable program or batch file.
rem FAILS! but QSA only works for http/s URLs; for file:// protocol, it is ignored
start file://D:/Programování/lumix-link/Control.html?foo=bar
rem opens file://D:/Programování/lumix-link/Control.html
One might e.g. think of enclosing the webpage in double quotes (to avoid misinterpretation of some characters). Then it fails and instead tries to open another CMD.exe with the given string as name:
rem FAILS!
start "http://google.com"
Okay, this is not a bug, just a mislead. This is the expected behavior. Let's fix it:
rem Works
start "" "http://google.com"
rem FAILS!
start "" "google.com"
The system cannot find the file google.com.
So we really have to provide an executable that should be launched. You can see the super-long answers here that succeed better or worse in getting the path to the default browser. But what's much simpler and bullet-proof is to use explorer to launch the webpage. But since explorer decides on what app to launch based on the protocol, you have to use the protocol prefix. And that's it!
rem FAILS!
rem start "" explorer "google.com"
rem Works
rem start "" explorer "http://google.com"
rem Works
rem start "" explorer "http://google.com?foo=bar"
rem FAILS! QSA still not supported on file:// URLs
rem start "" explorer "file://C:/test/main.html?foo=bar"

Thank you, #Rob.
#Rob's answer is close, but it still only pulls the ProgId. This one will set the browser name as reported by the ProgId (not always what you expect) in the browser variable, the specific verb used as browserverb, and the cmd path as browsercmd:
setlocal enableDelayedExpansion
:: parse the ProgId
FOR /F "usebackq tokens=1,2,* delims==" %%A IN (`REG QUERY "HKCU\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice" /v ProgId 2^>NUL ^| more +2`) DO (
SET browserstub=%%C
:: parse for Class information
FOR /F "usebackq tokens=1,2,* delims==" %%R IN (`REG QUERY "HKCR\!browserstub!" /v AppUserModelId 2^>NUL`) DO SET "browser=%%T"
FOR /F "usebackq tokens=1,2,* delims==" %%R IN (`REG QUERY "HKCR\!browserstub!\shell" /ve 2^>NUL`) DO SET "browserverb=%%T"
FOR /F "usebackq tokens=1,2,* delims==" %%R IN (`REG QUERY "HKCR\!browserstub!\shell\!browserverb!\command" /ve 2^>NUL`) DO SET "browsercmd=%%T"
)
:: display results
SET browser

This is the method i am using to open a browser window
start /REALTIME "~\iexplore.exe" "http://192.168.0.1"
Which opens internet explorer at the logon screen of the router, i have tested it on win 7 and win 10 and it works well. What i have gotten from this forum is that opening any website from a batch file or cmd window will use the default browser.
which works well here on win 10
start /REALTIME "" "http://192.168.0.1"
This also works well.
start /ABOVENORMAL /SEPARATE "" "http://192.168.0.1"
which allows the browser priority over other apps using cpu and also runs in a separate memory space which i have found to cause a lot of work for intruders of sorts.
The empty (path) "" need to be there other wise it just opens another cmd window.

Related

batch file variables view client ip

Trying to record a user client IP for a remote session. Currently have a little batch file recording logon times, and hostname. Need to also include the client IP address;
Currently using this;
reg query "HKEY_CURRENT_USER\Volatile Environment" /s > %temp%\IPINFO.txt
findstr /L ViewClient_IP_Address %temp%\IPINFO.txt > %temp%\IPRESULTS.txt
FOR /F “tokens=* delims= ” %%a in (%temp%\IPRESULTS.txt) do set IP=%%a
del %temp%\IPRESULTS.txt
set IP=%IP%
echo Login ,%Date%,%Time%,%computername%,%clientname%,%IP% >> Y:\%username%.csv
The registry key viewclient_ip_Address has the information I need, but the registry folder it sits within changes name each time so I'm having to export the whole directory and then filter for the key itself.
I just need to add the information from that IPRESULTS.txt into my end .csv file but struggling with writing it up.
Any help appreciated.
Is this what you're looking for? (The for-loop runs the command and parses it's output in memory)
For /F "EOL=HTokens=2*" %%H In ('^""%__AppDir__%reg.exe" Query "HKCU\Volatile Environment" /V ViewClient_IP_Address 2^>NUL^"')Do Set "IP=%%~I"
To find out more about how to use reg.exe with query, open up a Command Prompt window and enter reg query /?
If, as you've stated in your question, the required value and data is located under HKEY_CURRENT_USER\Volatile Environment but within a variable/unknown, subkey name, the help information should show you that you can use the /F option to locate your known value name, ViewClient_IP_Address, if you specify that the search is to locate a value using /V, it should retrieve the line you need.
For example, at the Command Prompt:
Reg Query "HKCU\Volatile Environment" /S /F "ViewClient_IP_Address" /V
Returns:
C:\Users\smith_ll>Reg Query "HKCU\Volatile Environment" /S /F "ViewClient_IP_Add
ress" /V
HKEY_CURRENT_USER\Volatile Environment\UnknownSubKey
ViewClient_IP_Address REG_SZ 192.168.1.15
End of search: 1 match(es) found.
You can then put that command into your for-loop, and pass its output through find.exe to isolate the line you need to parse. The underscore, for instance, looks unique to just the line you need. As we're already excluding any line beginning with H ,(with EOL=H), it will not match the End of search: 1 match(es) found. line:
Example:
For /F "EOL=HTokens=2*" %%H In ('^""%__AppDir__%reg.exe" Query "HKCU\Volatile Environment" /S /F "ViewClient_IP_Address" /V 2^>NUL^|"%__AppDir__%find.exe" "_"^"')Do #Set "IP=%%~I"
If you don't like the super long line, you can split into more using the caret:
For /F "EOL=HTokens=2*" %%H In ('^""%__AppDir__%reg.exe" Query^
"HKCU\Volatile Environment" /S /F "ViewClient_IP_Address" /V 2^>NUL^
^|"%__AppDir__%find.exe" "_"^"')Do #Set "IP=%%~I"

Batch File: "Environment Variable Not Defined" on a path

I have the following in a batch file
for /f "delims=" %%a in ("C:\Program Files (x86)\Wowza\creds.txt") do set %%a
net use J: https://csv/dav %p% /user:%u% /persistent:yes
I get an error:
Environment variable C:\Program Files (x86)\Wowza\creds.txt not defined
What do I need to resolve this?
Secondly, it works for all colleagues apart from one. Same laptop make, model and build. I used my details and it failed on his but worked on mine.
What fails is that it asks for the credentials to map the drive instead of taking them from the file
creds.txt
u:JoeBloggs
p:Password1234
Any idea?
Thanks
the reason for your errormessage is, your for /f loop doesn't evaluate the contents of the file. It takes a quoted string as string not as filename. Usebackq changes that behaviour.
You have another failure in your script: With your code, set %%a translates to set u:JoeBloggs, which is invalid syntax. Correct syntax requrires set u=Joebloggs. Therefore you have to split the line in a part before the colon and a part after the colon and build your set command accordingly (just set %%a would work, when the contents of the file would look like u=JoeBloggs)
Change your for loop to:
for /f "usebackq tokens=1,* delims=:" %%a in ("C:\Program Files (x86)\Wowza\creds.txt") do set "%%a=%%b"
I was going to post a similar answer to #stephan but he beat me to it. If however you have the option to change your creds.txt file to the below:
u=JoeBloggs
p=Password1234
You can shorten the for loop a bit to this:
for /f "usebackq delims=" %%a in ("C:\Program Files (x86)\Wowza\creds.txt") do set "%%~a"
which effectively just does this:
set "u=JoeBloggs"
set "p=Password1234"

Correct syntax for nested for loops in batch file

I am trying to query the registry value of an installed application on many servers. I could hardcode the servers in, and have a lot of repetition and it seems to work. But sometimes a list of servers may change, and I'd like to take a more sensible modular approach.
So I can provide a test file with a list of server names, and then query the registry values of all of these servers, outputting them in a logfile.
I think the issue is definitely with my loops/variable storing. Not sure exactly what is going on, but it seems like once I get one set of Registry values, these are outputted for every single server, regardless of their respective registry values.
Not too experience with this kind of scripting, so I have been sort of mashing this together through trial and error, below is what I have so far. Please point out any woeful syntax errors I've made.
So essentially this is to find a McAfee scan engine version installed to each server. The reporting from the McAfee console itself is not always reliable, and I want to check that the contents are successfully pulled down to each server.
There are two registry values required to create a full engine version, so I am required to pull both of these and then combine them into a single string.
At the moment I do get an output that looks correct, but it does not represent what is actually installed to each server. It is like one value is being picked up and then replicated.
On an additional note, this only seems to work when executed in command line. And the first 1-2 times it is ran, no values are pulled up. Get the feeling I am quite far away from a solution.
SET LOGFILE=C:\LogFile.log
For /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Major ^| find /i "EngineVersion32Major"') do set /a major=%%a
for /f "tokens=3" %%b in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Minor ^| find /i "EngineVersion32Minor"') do set /a minor=%%b
echo %%i: %major%.%minor% >> %LOGFILE%
)
Would expect an output like this:
server1 : 5900.5647
server2 : 6000.4589
server3 : 5900.5647
server4 : 5900.5647
Cheers for any help you can provide.
It has nothing to do with for syntax, but how cmd parses scripts. See How does the Windows Command Interpreter (CMD.EXE) parse scripts?
When cmd parses a block (anything within parens), processes it as a single line. So it expands any %var% to its actual content. Changes made to it, are not taken into account until the block is exited. To retrieve new content within a block, you must enable delayed expansion, which forces the parser to evaluate it for every iteration. Also, syntax must be changed from %var% to !var!
Here, also, removed the /a switch from set command, as you are not doing calculations, and you may get results you won't expect (imagine a minor version equal to 0080 that will be treated as octal (invalid) and would break the script). Also, note both var name and var content enclosed in quotes (set "minor=%%b"), to avoid undesired trailing/leading spaces.
More also, I think you don't need the ^| find /i "EngineVersion32Major part, as possibly the key named EngineVersion32Major will content only what you are looking for. And again, enclose data in quotes (never know when a space may appear). You may also change "tokens=3" by "skip=1 tokens=3" to avoid process the heading reg echoes.
Thus
#echo off
SetLocal EnableDelayedExpansion
SET LOGFILE=C:\LogFile.log
for /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Major"') do set "major=%%a"
for /f "tokens=3" %%b in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Minor"') do set "minor=%%b"
echo %%i: !major!.!minor!>>%LOGFILE%
)
EndLocal
Also, this works within a block regardless delayed expansion is enabled or not (note double percent sign)
call echo %%i: %%major%%.%%minor%%>>%LOGFILE%
Another issue, any time a redirection is used within a block, the system opens and closes the file (or stream).
But
#echo off
SetLocal EnableDelayedExpansion
SET LOGFILE=C:\LogFile.log
>>"%LOGFILE%" (
for /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Major"') do set "major=%%a"
for /f "tokens=3" %%b in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Minor"') do set "minor=%%b"
echo %%i: !major!.!minor!
)
)
EndLocal
Processes all commands in the block, so the file is opened and closed only once. This may improve performance, specially with large files.
BTW,
>>"%LOGFILE%" (
...
...
)
Is the same as
(
...
...
)>>"%LOGFILE%"
Please use the search facility to locate many SO articles on delayed expansion.
The easy way in your case is to use
call echo %%i: %%major%%.%%minor%% >> %LOGFILE%

output net view (batch) into text then perform action against each computer

I have been trying to find away to search for the existence of my company's software on PC's by searching hostnames on the network \\computername\c$\Program Files\Foo, and if it finds it, copy over an updated config etc.
I've seen that net view will out put all the PC's on the network, something like this:
\\DISKSTATION
\\JWLAPTOP
\\TEST
\\XP
The command completed successfully.
I was wondering if there was a way to just get the computer names in a clean list (without "command completed" etc.):
\\DISKSTATION
\\JWLAPTOP
\\TEST
\\XP
Then run some commands against it, for everything in hostnames.txt, if exist:
\\JWLAPTOP\c$\Program Files\Foo --> do copy xyz to wherever
I can take care of the part \c$\Program Files\Foo as a variable to add after the computer names in the text file.
Hope that makes sense, thanks for any tips.
edit
Been re thinking this perhaps there is a more direct way to do this....
I need to see the list of PC's on customers network.....net view is a good way of getting this info so far, but I further need to see which ones are online. Any online, query for folder and update a *.CFG file, any offline, output to text for reference.
So at the minute....
FOR /F "tokens=1 delims= " %%G IN ('net view ^|findstr /L /B /C:"\\"')
this is working great, I then made it output to a text file..
FOR /F "tokens=1 delims= " %%G IN ('net view ^|findstr /L /B /C:"\\"') DO (echo %%G>>%~dp0netview.txt)
However, the %%G echo's back \somecomputer which means I am struggling to get a new line..
for /f %%G in (%~dp0netview.txt) DO (ping etc......
to ping because of the \ before the computer name. So was wonder if we can make the list 'just" have the PC name without the \ before it.
Also this is the content of the .cfg file I need to edit...
<?xml version="1.0" encoding="utf-8"?>
<ClientConfigurationFile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ServerPath>**\\server\shared\data**</ServerPath>
<ApplicationMode>Workstation</ApplicationMode>
<VRPath />
<ServicePollingInterval>0</ServicePollingInterval>
</ClientConfigurationFile>
perhaps there is a way of editing a certain section of this directly once its existence is found. \server\shared\data...in bold is what I need to update often when clients have new servers and things and involves having to go round lots of rooms to update manually. This batch could save hours upon hours of unnecessary work.
over writing the existing .cfg file is still a good way of doing it if it's too tricky or not possible directly.
Hope it makes sense, thanks for the replies!!!
Assuming none of your computer names have spaces in them.
#echo off
FOR /F "tokens=1 delims= " %%G IN ('net view ^|findstr /L /B /C:"\\"') DO (
IF EXIST "%%~G\c$\Program Files\Foo" copy "C:\folder\xyz.txt" "C:\other folder\"
)
If you want the leading back slashes stripped then use it as a delimiter just like I am using the space as a delimiter to get rid of all the extraneous NET VIEW output.
#echo off
FOR /F "tokens=1 delims=\ " %%G IN ('net view ^|findstr /L /B /C:"\\"') DO (
PING %%G
IF EXIST "\\%%~G\c$\Program Files\Foo" copy "C:\folder\xyz.txt" "C:\other folder\"
)
You could do the following:
#echo off
setlocal EnableExtensions
set "TARGET=C$\Program Files\Foo"
for /F "eol=| delims=" %%C in ('
net view ^| find "\\"
') do (
pushd "%%C\%TARGET%"
if not ErrorLevel 1 (
rem do your operations here...
copy "\your\source\path\xyz" "."
popd
)
)
endlocal
The for /F loop walks through all host names returned by net view (supposing each one starts with \\ and there are only the host names).
Since the resulting path (for instance \\TEST\C$\Program Files\Foo) is a UNC path which is not supported by several commands, pushd is used, which is capable of connecting to the given resource by establishing a temporary drive letter like Z:, and changing the working directory to its root immediately (if the command extensions are on, which is the Windows default).
The query if not ErrorLevel 1 is used to skip over the remaining commands in case pushd could not connect to the resource for some reason.
After all your operations, popd ensures that the temporary drive created by pushd is unmounted and that the former working directory is restored.

script to findstr and then inject next line with variable - can't quite get it working

I've got a script I'm working on that checks a text file to match pc name, then match a port number. That then info gets injected into an ini file for specific settings. I'm using this in a Citrix setup.
Here's a piece of my test script:
:Set_Client_Name
for /f "tokens=1-3" %%1 in ('query session %USERNAME% ^| find ">"') do set ses_num=%%3
for /f "tokens=1-3" %%1 in ('reg query "HKCU\Volatile Environment\%ses_num%" /v CLIENTNAME') do set client_name=%%3
:CHECK
findstr /i /c:%client_name% "C:\star.txt"
IF ERRORLEVEL 1 goto end
:CREATE
set port=
set parse=findstr /i /c:%client_name% "C:\star.txt"
for /f "tokens=2 delims=," %%a in ('"%parse%"') do (set port=%%a)
for /F %%G IN C:\hbowem32.ini DO (
findstr /i /c:"[0_Network Def.]"
echo Local Port=%port% >> C:\hbowem32.ini
)
:END
`
The :Set_Client_Name, :Check, and :Create portions work correctly.
I'm just doing something wrong with the next piece, and I'm not sure what it is.
I need to find the string [0_Network Def.] in the hbowem32.ini, and right after that, inject the %port% variable. I can get it to add to the ini file at the bottom, but I need it to be able to inject this in the correct section of the ini.
I'm also wanting to add a section that pulls the client IP address (this is a Terminal Services/Citrix server) so it can be injected into a different ini/section. I can't seem to get it to pull the user's workstation IP address. It only pulls the IP address of the Citrix server. I no longer have this section in my test script above, but figured I'd go ahead and ask since I'm here and already stuck.
Thanks for any insight and advice.
Add the /L switch to the FINDSTR so that you are dealing with Literals not (default) Regular expressions.

Resources