according to choice specific line should run in cmd.exe using batch file - powershell

I wanted to give this choice
#echo off
echo what operation you wanted to perform
echo a:creating a new web server?
echo or
echo b:Edit root url for already existed web server
set /P var = "What is your option a or b"
if "%var%" == "A" (
cd C:\Program Files\Infor\Mongoose\Tools
infordbcl.exe addwebserver -name:sample -product:Mongoose -rooturl:https://uscovwmongoose3
)
if "%var%" == "B" (
infordbcl.exe addwebserver -name:sample -product:Mongoose -rooturl:https://mongoose.com -
mode:edit
)
I ran this batch file using powershell.
After entering the choice A or B, the commands specified in if blocks are not getting executed in cmd.exe
Is their any syntax errors in it, please let me know

This is how Choice could be used here:
#echo off
Choice /N /C ce /M " <?> (C)reate new Server <?> (E)dit root url for existing web server"
If Errorlevel 2 (
REM If the Change directory command is also meant to execute in this block, remove and place CD command prior to choice command.
infordbcl.exe addwebserver -name:sample -product:Mongoose -rooturl:https://mongoose.com -mode:edit
) Else (
REM confirm if lack of url extension is correct
cd "C:\Program Files\Infor\Mongoose\Tools"
infordbcl.exe addwebserver -name:sample -product:Mongoose -rooturl:https://uscovwmongoose3
)
Explanation:
/N hides the default prompt (whatever keys are defined using /C or the default Y/N if /C is not used)
/C allows definition of keys within the range 0-9 and A-Z
errorlevel for each key is set according to occurance after the /C
switch
for /C ce, c will return Errorlevel 1, e will return errorlevel 2
and so on
/M "string" allows a custom string to be defined to explain the Choice. Encase the string within doublequotes.
When you test the returned Errorlevel
You must test from Highest to Lowest.
This is because the command intepreter reads If Errorlevel n as If Errorlevel n or higher
For more information and usage examples, type choice /? in cmd.exe

Related

Why is my GOTO statement not working (batch)

It always goes to the first lapel no matter what is the input
I saw other posts with the same issue but none of the syntax mistakes they made were present in my script.
Here is the script :
#echo off
cls
cd /d %~dp0
echo "Include files? [Y/N]"
set /p option=
if %option%=="Y" GOTO yes
if %option%=="y" GOTO yes
if %option%=="N" GOTO no
if %option%=="n" GOTO no
:yes
cls
powershell -command "iex \"tree /f\" > \"tree-filed.txt\""
GOTO end
:no
cls
powershell -command "iex \"tree\" > \"tree-folders.txt\""
GOTO end
:end
cls
echo the tree list was created.
pause
What am I missing?
rifteyy's solution is effective, but some background information may be helpful:
As Squashman notes, an if conditional either requires both sides to be either (double-)quoted or unquoted; that is, both if %option%==y ... and if "%option%"=="y" ... work:
The double-quoted form is more robust, as it also handles values with metacharacters such as & correctly, but the match must be exact with respect to presence or absence of spaces.
Conversely, only the unquoted form is forgiving of leading and trailing spaces; e.g. if %option%==y ... still works if the user entered y rather than just y.
You can use if's /I option to make the comparison case-insensitive, which obviates the need to check for y and Y separately, for instance. help if shows more information.
tree.com is a stand-alone executable that can be called from any (Windows) shell, so there is generally no good reason to call PowerShell (powershell.exe, which is expensive), given that you can invoke tree directly from your batch file - though you may need PowerShell to control the character encoding of the output files.[1]
As an aside: Inside PowerShell there is no need for Invoke-Expression (iex), which should generally be avoided; the best way to invoke an external executable such as tree.com fundamentally works the same as from cmd.exe (see below).
If you do need PowerShell, call it as follows, for instance:
powershell -command "tree > tree-folders.txt"
Therefore, a streamlined version of your batch file would look like this (cls commands omitted):
#echo off
cd /d "%~dp0"
:prompt
echo "Include files? [Y/N/Q]"
set /p option=
if /I "%option%"=="y" GOTO yes
if /I "%option%"=="n" GOTO no
if /I "%option%"=="q" GOTO :eof
goto prompt
:yes
tree /f > tree-files.txt
GOTO end
:no
tree > tree-folders.txt
GOTO end
:end
echo the tree list was created.
pause
As Stephan points out, the standard choice.exe utility offers a simpler prompting solution:
choice /c ynq /m "Include files?"
if %ERRORLEVEL% EQU 1 goto yes
if %ERRORLEVEL% EQU 2 goto no
goto :eof
choice.exe:
is case-insensitive by default (use /CS for case-sensitivity)
accepts only a single input character from the user, which instantly exits the prompt (no Enter keypress required), with the %ERRORLEVEL% variable set to the 1-based position of the character in the list of permitted characters passed to /C
Note: The above deliberately uses, e.g., if %ERRORLEVEL% EQU 1 rather than if ERRORLEVEL 1, because the latter uses equal-or-greater logic, which would require you to reverse the order of the branching statements.
automatically validates the input (beeps if an invalid character is typed)
See choice /? for more information.
[1] However, you do need PowerShell if the command's output contains non-ASCII characters and you want the output redirection (>) to create UTF-16LE ("Unicode") files (Windows PowerShell) or (BOM-less) UTF-8 files (PowerShell (Core) v6+). Using > from cmd.exe results in OEM-encoded files, based on the console's code page, reported via chcp. Alternatively, you could switch the console code page to (BOM-less) UTF-8, via chcp 65001, but that wouldn't work with tree.com, because it is too old to support this code page. By contrast, it would work with the output from dir, for instance.
You must use brackets in IF statement also, if you did not, it will automatically do the actions under the IF statements.
#echo off
cls
cd /d %~dp0
echo "Include files? [Y/N]"
set /p option=
if "%option%"=="Y" GOTO yes
if "%option%"=="y" GOTO yes
if "%option%"=="N" GOTO no
if "%option%"=="n" GOTO no
:yes
cls
powershell -command "iex \"tree /f\" > \"tree-filed.txt\""
GOTO end
:no
cls
powershell -command "iex \"tree\" > \"tree-folders.txt\""
GOTO end
:end
cls
echo the tree list was created.
pause

How to launch html report from cake (build)

I'm using cake in my projects to build, run unit tests, check code coverage and then generate an HTML report (using ReportGenerator). This is all working correctly, and I can open the generated report in my browser.
However, when I was previously using a dos batch file to do this, it would also launch my default browser and load the report after it was generated, but I can't find a way to do that with cake.
Here are the contents of the batch file I've been using:
#ECHO OFF
SET SearchDirectory=%~dp0Grapevine.Tests\bin\Debug
SET DllContainingTests=%~dp0Grapevine.Tests\bin\Debug\Grapevine.Tests.dll
for /R "%~dp0packages" %%a in (*) do if /I "%%~nxa"=="xunit.console.exe" SET TestRunnerExe=%%~dpnxa
for /R "%~dp0packages" %%a in (*) do if /I "%%~nxa"=="OpenCover.Console.exe" SET OpenCoverExe=%%~dpnxa
for /R "%~dp0packages" %%a in (*) do if /I "%%~nxa"=="ReportGenerator.exe" SET ReportGeneratorExe=%%~dpnxa
if not exist "%~dp0GeneratedReports" mkdir "%~dp0GeneratedReports"
call :RunOpenCoverUnitTestMetrics
if %errorlevel% equ 0 (
call :RunReportGeneratorOutput
)
if %errorlevel% equ 0 (
call :RunLaunchReport
)
exit /b %errorlevel%
:RunOpenCoverUnitTestMetrics
"%OpenCoverExe%" ^
-target:"%TestRunnerExe%" ^
-targetargs:"\"%DllContainingTests%\"" ^
-filter:"+[*]* -[*.Tests*]* -[*]*.*Config -[xunit*]* -[*]Grapevine.Interfaces.*" ^
-mergebyhash ^
-skipautoprops ^
-register:user ^
-output:"%~dp0GeneratedReports\CoverageReport.xml"^
-searchdirs:"%SearchDirectory%"
exit /b %errorlevel%
:RunReportGeneratorOutput
"%ReportGeneratorExe%" ^
-reports:"%~dp0\GeneratedReports\CoverageReport.xml" ^
-targetdir:"%~dp0\GeneratedReports\ReportGeneratorOutput"
exit /b %errorlevel%
:RunLaunchReport
start "report" "%~dp0\GeneratedReports\ReportGeneratorOutput\index.htm"
exit /b %errorlevel%
I have tried using the following:
StartProcess(new FilePath("./GeneratedReports/ReportGeneratorOutput/index.htm"));
To which I receive the following error:
An error occured when executing task 'generate-report'.
Error: The specified executable is not a valid application for this OS platform.
I have verified that the path is correct and the file exists, and that copy/pasting the file path on the command line indeed opens the file in my default browser.
I couldn't figure out a way to do this with just Cake, so I resorted to calling CMD with StartProcess:
if (IsRunningOnWindows()) {
StartProcess("cmd", new ProcessSettings {
Arguments = $"/C start \"\" {testCoverageReportPath}index.htm"
});
}
This works great for my needs.
You can do this using the StartProcess alias example:
FilePath reportpath = File("./GeneratedReports/ReportGeneratorOutput/index.htm");
StartProcess(reportpath);
What finally worked for me was this:
if (IsRunningOnWindows())
{
StartProcess("explorer.exe", reportPath);
}
Obviously, this won't work on non-windows environments, but that's outside the scope of my needs. Everything else I tried produced an error either that the file could not be found or that the executable was invalid for the OS.

Strip CMD output to just show directories

I'm currently trying to replace a powershell script with a cmd script as it's more suitable for what is trying to be done.
In Powershell I'm using this bit of code to return a list of personal folder directories on the computer
$Name = [Environment]::UserName
get-item HKCU:\software\Microsoft\Office\15.0\Outlook\Search\Catalog - ErrorAction SilentlyContinue | select -expandProperty property | Out-File Z:\global\pst\PowershellOutput\$Name.txt -append
This does what I want and outputs a list of directories like so
H:\PST\My Outlook Data File 1.pst
H:\PST\My Outlook Data File 2.pst
C:\PST\My Outlook Data File 3.pst
However when I run this line to extract the registry key
regedit.exe /e Z:\global\battest\%username%.txt "HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog"
I get an output with lots of unnecessary data
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog]
"H:\\PST\\My Outlook Data File 1.pst"=hex:0c,01,00,00,00,00,00,00
"H:\\PST\\My Outlook Data File 2.pst"=hex:f8,00,00,00,00,00,00,00
"C:\\PST\\My Outlook Data File 3.pst"=hex:ac,02,00,00,00,00,00,00
This data is passed onto another program* so a work-around could be to use data within the "" marks however it also has the double backslashes which makes the data awkward to pass on.
Is there a better way to grab these values within CMD or perhaps a parameter which I've missed which just shows the directories?
-Sorry for not including this before however this program is not a CMD program, it's visual basic
While I don't have Office installed to test, this should get the work done
#echo off
setlocal enableextensions disabledelayedexpansion
set "HKCU=&H80000001"
set "subKey=software\Microsoft\Office\15.0\Outlook\Search\Catalog"
>> "Z:\global\pst\PowershellOutput\%username%.txt" (
for /f "tokens=2 delims={" %%a in ('
wmic
/NameSpace:\\root\default
Class StdRegProv
Call EnumValues
hDefKey^="%HKCU%"
sSubKeyName^="%subkey%"
2^>nul
^| find "sNames = {"
') do for %%b in (%%a) do (
for /f delims^=^" %%c in ("%%~b") do echo(%%~fc
)
)
It uses wmic to retrieve the list of values defined under the indicated key and filter the output to only retrieve the line with the names of those values in the form sNames = {"v1", "v2", "v3"}.
The { is used to separate the start of the line from the list of values (%%a) , and this list is iterated (%%b) to get each value. The last element in the list includes an ending } that needs to be removed, this is handled by %%c using the quotes in the value as delimiters.
The equivalent vbs version could be
Option Explicit
Const HKEY_CURRENT_USER = &H80000001
Const ForAppending = 8
Const SUB_KEY = "software\Microsoft\Office\15.0\Outlook\Search\Catalog"
Const OUTPUT_PATH = "Z:\global\pst\PowershellOutput"
Dim fso, shell
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
Set shell = WScript.CreateObject("WScript.Shell")
Dim values
Call GetObject( _
"winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv" _
).EnumValues( _
HKEY_CURRENT_USER, SUB_KEY, values _
)
Dim outputFile
Set outputFile = fso.OpenTextFile( _
fso.BuildPath( _
OUTPUT_PATH, shell.ExpandEnvironmentStrings("%username%") & ".txt" _
) _
, ForAppending _
, True _
)
Dim value
If Not IsNull(values) Then
For Each value In values
Call outputFile.WriteLine(fso.GetAbsolutePathName( value ))
Next
End If
Call outputFile.Close()
You would probably need to use the REG QUERY command. In a single bat file it would like like:
#echo OFF
for /f "usebackq tokens=1-3" %%A in (`REG QUERY "HKCU\Software\Microsoft\Office\15.0\Outlook\Search\Catalog"`) do (
set ValueName=%%A
)
echo %ValueName% > Z:\global\battest\%username%.txt
Got this from How can I get the value of a registry key from within a batch script?
Here is a batch code to get the list of *.pst files (not directories) which work independent on number of *.pst files and their file names as long as the file names end with .pst.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
for /F "skip=1 delims=" %%# in ('%SystemRoot%\System32\reg.exe query HKCU\Software\Microsoft\Office\15.0\Outlook\Search\Catalog 2^>nul') do (
set "RegData=%%#"
set "DelData=!RegData:*.pst=!"
if not "!DelData!" == "!RegData!" call :OutputFileName
)
endlocal
goto :EOF
:OutputFileName
set "RegData=!RegData:%DelData%=!"
echo !RegData:~4!
goto :EOF
*.pst files are Outlook Personal Storage files which are container files for emails, contacts, ...
The command FOR runs console application REG to query all values of registry key:
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog
The output on Windows Vista and later Windows versions is for the example:
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog
H:\PST\My Outlook Data File 1.pst REG_SZ whatever the
H:\PST\My Outlook Data File 2.pst REG_SZ data value is
C:\PST\My Outlook Data File 3.pst REG_SZ of each value
There is output the registry key and next the registry values each indented with 4 spaces and with 4 spaces between value name and value type and 4 spaces between value type and data value.
But on Windows XP the output is for the example:
! REG.EXE VERSION 3.0
HKEY_CURRENT_USER\Software\Microsoft\Office\15.0\Outlook\Search\Catalog
H:\PST\My Outlook Data File 1.pst REG_SZ whatever the
H:\PST\My Outlook Data File 2.pst REG_SZ data value is
C:\PST\My Outlook Data File 3.pst REG_SZ of each value
So there are first two header lines before the registry key. The registry values are also indented with 4 spaces. But there are 1 or more tabs instead of spaces between the value name and the value type and there are also 1 or more tabs instead of spaces between value type and data value.
Note: I don't know if REG_SZ is the right registry value type. I don't have this registry key at all in my Windows registry and therefore just added the 3 registry values as string values with the dummy strings.
So the tricky part is how to get the registry value name containing also spaces to get just the name of the *.pst files independent on file name.
This is done by assigning each output line with the exception of first line because of skip=1 to environment variable RegData and get next from this line everything after .pst assigned to environment variable DelData.
If the line contains .pst in any case at all resulting in value of DelData being not equal value of RegData, the subroutine OutputFileName is called for further processing and printing the file name of the *.pst file.
In the subroutine OutputFileName first the string right of *.pst file name is removed from RegData using a string substitution. Next *.pst file name is output without the 4 indent spaces at beginning.
If the number of indent spaces would not be always exactly 4 spaces, the line echo !RegData:~4! could be replaced by following code to work independent on number of indent spaces/tabs.
for /F "tokens=1*" %%I in ("%RegData%") do (
if "%%J" == "" (
echo %%I
) else (
echo %%I %%J
)
)
The usage of REG instead of REGEDIT has the advantage that no elevated privileges of an administrator is necessary for running this batch code.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /?
echo /?
for /?
goto /?
reg /?
reg query /?
set /?
setlocal /?
Nothing is output if the registry key does not exist. The error message output to handle STDERR is suppressed here by redirecting it with 2^>nul to device NUL. See the Microsoft article Using command redirection operators for details. The redirection operator > must be escaped here with caret character ^ to be interpreted as literal character on parsing the FOR command line and being interpreted as redirection operator on execution of the REG command line by FOR.

How to check in command-line if a given file or directory is locked (used by any process)?

I need to know that before any attempt to do anything with such file.
Not sure about locked directories (does Windows have that?)
But detecting if a file is being written to by another process is not difficult.
#echo off
2>nul (
>>test.txt echo off
) && (echo file is not locked) || (echo file is locked)
I use the following test script from another window to place a lock on the file.
(
>&2 pause
) >> test.txt
When I run the 2nd script from one window and then run the 1st script from a second window, I get my "locked" message. Once I press <Enter> in the 1st window, I get the "unlocked" message if I rerun the 1st script.
Explanation
Whenever the output of a command is redirected to a file, the file of course must be opened for write access. The Windows CMD session will attempt to open the file, even if the command does not produce any output.
The >> redirection operator opens the file in append mode.
So >>test.txt echo off will attempt to open the file, it writes nothing to the file (assuming echo is already off), and then it closes the file. The file is not modified in any way.
Most processes lock a file whenever they open a file for write access. (There are OS system calls that allow opening a file for writing in a shared mode, but that is not the default). So if another process already has "test.txt" locked for writing, then the redirection will fail with the following error message sent to stderr - "The process cannot access the file because it is being used by another process.". Also an error code will be generated upon redirection failure. If the command and the redirection succeed, then a success code is returned.
Simply adding 2>nul to the command will not prevent the error message because it redirects the error output for the command, not the redirection. That is why I enclose the command in parentheses and then redirect the error output to nul outside of the parens.
So the error message is effectively hidden, but the error code is still propagated outside of the parens. The standard Windows && and || operators are used to detect whether the command inside the parens was successful or failed. Presumably echo off will never fail, so the only possible reason for failure would be the redirection failed. Most likely it fails because of a locking issue, though technically there could be other reasons for failure.
It is a curious "feature" that Windows does not set the %ERRORLEVEL% dynamic variable to an error upon redirection failure unless the || operator is used. (See File redirection in Windows and %errorlevel%). So the || operator must read the returned error code at some low level, not via the %ERRORLEVEL% variable.
Using these techniques to detect redirection failure can be very useful in a batch context. It can be used to establish locks that allow serialization of multiple events in parallel processes. For example, it can enable multiple processes to safely write to the same log file at the "same" time. How do you have shared log files under Windows?
EDIT
Regarding locked folders. I'm not sure how Windows implements this, perhaps with a lock. But if a process has an active directory involving the folder, then the folder cannot be renamed. That can easily be detected using
2>nul ren folderName folderName && echo Folder is NOT locked || echo folder is LOCKED
EDIT
I have since learned that (call ) (with a space) is a very fast command without side effects that is guaranteed to succeed with ERRORLEVEL set to 0. And (call) (without a space) is a fast command without side effects that is guaranteed to fail with ERRORLEVEL 1.
So I now use the following to check if a file is locked:
2>nul (
>>test.txt (call )
) && (echo file is not locked) || (echo file is locked)
In addition to great answer from dbenham, the following form finally help me understand used technique:
( type nul >> file.txt ) 2>nul || echo File is locked!
type nul command gives an empty output and does not affect the current echo setting like echo off command in orginal.
If you want to use if–then–else condition remember of correct order - success statement (&&) is going first and alternate statement (||) is going second:
command && (echo Command is successful) || (echo Command has failed)
If you download and install the Windows Server 2003 Resource Kit Tools there is a utility called oh.exe that will list open file handles for a given file:
http://www.microsoft.com/en-us/download/details.aspx?id=17657
Once you install it, reboot your machine and you'll be able to use the utility. You can see all the options in the Help and Support center as well as by typing oh /? in the command prompt.
(Info from : http://windowsxp.mvps.org/processlock.htm )
Note, the writing of a message stating the file status was less helpful than a batch command that set a return code. For example, return code 1 if file is locked.
#echo off
2>nul (
>>test.tmp echo off
) && (EXIT /B 0) || (EXIT /B 1)
Other answers resulted in side-effects for me. For instance, the following from this answer will cause file watchers to trigger:
COPY /B app.exe+NUL app.exe
And the following from the top answer here would overwrite any changes made to the target file:
2>nul (
>>test.txt (call )
) && (echo file is not locked) || (echo file is locked)
On modern version of Windows, you can call into Powershell to accomplish this task with zero side-effects:
powershell -Command "$FileStream = [System.IO.File]::Open('%FILE%', 'Open', 'Write'); $FileStream.Close(); $FileStream.Dispose()" && (echo File is not locked) || (echo File is locked)
This will not modify the file or its metadata at all, even when it isn't locked.
Example usage
I use this method in my custom git mergetool script for merging Excel files. The way a git mergetool works is that it waits for the script shell to exit, then checks if the target file was modified, prompting with "XX.yyy seems unchanged. Was the merge successful [y/n]?" if it wasn't. However, Excel (at least the version I'm using) does not spawn a new process for each file it opens. So if Excel is already open, the script will exit immediately, and git will detect no changes to the file, resulting in that prompt.
So I devised the method above, and I use it like below:
REM block until MERGED is closed
:loop
powershell -Command "$FileStream = [System.IO.File]::Open('%MERGED%', 'Open', 'Write'); $FileStream.Close(); $FileStream.Dispose()" >NUL 2>NUL || (goto :loop)
Incidentally, dbenham's solution also seems to be an effective way to find out if a process is running. It was the best solution I found for the following application:
start /b "job1.exe >> job1.out"
start /b /wait "job2.exe >> job2.out"
::wait for job1 to finish using dbenham's code to check if job1.out is in use
comparejobs.exe
Just i want to share with you an example of my script based on #dbenham's trick
Description of this script : Check_Locked_Files.bat :
This script can scan and check for locked files on a set of folders that can be modified into the script; for example, i have chosen those set of folders to be scanned :
Set Folders=^
^ "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%ProgramFiles%\Internet Explorer"^
^ "%ProgramFiles%\Skype"^
^ "%ProgramFiles%\TeamViewer"^
^ "%WinDir%\system32\drivers"^
^ "%Temp%"
The output result is in HTML format for more readability.
If the file is locked we show it in red color otherwise we show it in green color.
And the whole script is : Check_Locked_Files.bat
#echo off
Rem This source is inspired from here
Rem hxxps://stackoverflow.com/questions/
Rem 10518151/how-to-check-in-command-line-if-a-given-file-or-directory-is-locked-used-by-any?answertab=active#tab-top
Rem Thanks for dbenham for this nice trick ;)
Mode con cols=90 lines=5 & color 9E
Title Scan and Check for Locked Files by Hackoo 2017
set "LogFile=%~dp0%~n0.html"
(
echo ^<html^>
echo ^<title^> Scan and Check for locked files by Hackoo 2017^</title^>
echo ^<body bgcolor^=#ffdfb7^>
echo ^<center^>^<b^>Log Started on %Date% # %Time% by the user : "%username%" on the computer : "%ComputerName%"^</b^>^</center^>
)> "%LogFile%"
echo(
echo --------------------------------------------------------------------------
echo Please Wait a while ....... Scanning for locked files is in progress
echo --------------------------------------------------------------------------
Rem We Play radio just for fun and in order to let the user be patient until the scan ended
Call :Play_DJ_Buzz_Radio
Timeout /T 3 /nobreak>nul
cls
Set Folders=^
^ "%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%UserProfile%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"^
^ "%ProgramFiles%\Internet Explorer"^
^ "%ProgramFiles%\Skype"^
^ "%ProgramFiles%\TeamViewer"^
^ "%WinDir%\system32\drivers"^
^ "%Temp%"
#For %%a in (%Folders%) Do (
( echo ^<hr^>^<font color^=DarkOrange^>^<B^>Folder : %%a^</B^>^</font^>^<hr^>) >> "%LogFile%"
#for /f "delims=" %%b in ('Dir /A-D /s /b "%%~a\*.*"') do (
Call :Scanning "%%~nxb"
Call:Check_Locked_File "%%~b" "%LogFile%"
)
)
(
echo ^<hr^>
echo ^<center^>^<b^>Log ended on %Date% # %Time% on the computer : "%ComputerName%"^</b^>^</center^>
echo ^</body^>
echo ^</html^>
)>> "%LogFile%"
Start "" "%LogFile%" & Call :Stop_Radio & exit
::***********************************************************************************
:Check_Locked_File <File> <LogFile>
(
2>nul (
>>%1 (call )
) && ( #echo ^<font color^=green^>file "%~1"^</font^>^<br^>
) || (
#echo ^<font color^=red^>file "%~1" is locked and is in use^</font^>^<br^>
)
)>>%2 2>nul
exit /b
::***********************************************************************************
:Scanning <file>
cls
echo(
echo --------------------------------------------------------------------------
echo Please Wait a while... Scanning for %1
echo --------------------------------------------------------------------------
exit /b
::***********************************************************************************
:Play_DJ_Buzz_Radio
Taskkill /IM "wscript.exe" /F >nul 2>&1
Set "vbsfile=%temp%\DJBuzzRadio.vbs"
Set "URL=http://www.chocradios.ch/djbuzzradio_windows.mp3.asx"
Call:Play "%URL%" "%vbsfile%"
Start "" "%vbsfile%"
Exit /b
::**************************************************************
:Play
(
echo Play "%~1"
echo Sub Play(URL^)
echo Dim Sound
echo Set Sound = CreateObject("WMPlayer.OCX"^)
echo Sound.URL = URL
echo Sound.settings.volume = 100
echo Sound.Controls.play
echo do while Sound.currentmedia.duration = 0
echo wscript.sleep 100
echo loop
echo wscript.sleep (int(Sound.currentmedia.duration^)+1^)*1000
echo End Sub
)>%~2
exit /b
::**************************************************************
:Stop_Radio
Taskkill /IM "wscript.exe" /F >nul 2>&1
If Exist "%vbsfile%" Del "%vbsfile%"
::**************************************************************
:: Create the file Running.tmp
ECHO %DATE% > Running.tmp
ECHO %TIME% >> Running.tmp
:: block it and do the work
(
>&2 CALL :Work 30
) >> Running.tmp
:: when the work is finished, delete the file
DEL Running.tmp
GOTO EOF
:: put here the work to be done by the batch file
:Work
ping 127.0.0.1 -n 2 -w 1000 > NUL
ping 127.0.0.1 -n %1 -w 1000 > NUL
:: when the process finishes, the execution go back
:: to the line after the CALL
In case you want to use this in a Cygwin Bash, here are the one-liners:
# To lock a file: (in a different window)
cmd.exe /C "( >&2 pause ) >> test.txt"
#Press any key to continue . . .
# To test if a file is locked (with text)
cmd.exe /C "2>nul ( >>test.txt (call ) ) && (echo ok) || (echo locked)"
#locked
# To test if a file is locked (with POSIX exit code)
cmd.exe /C "2>nul ( >>test.txt (call ) ) && (exit /b 0) || (exit /b 1)"
echo $?
#1
In case of windows network share you can try powershell command:
Get-SmbOpenFile
For example execute on file server command as administrator:
Get-SmbOpenFile | Where-Object -Property Path -match "file.txt"

How to launch Windows' RegEdit with certain path?

How do I launch Windows' RegEdit with certain path located, like "HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0", so I don't have to do the clicking?
What's the command line argument to do this? Or is there a place to find the explanation of RegEdit's switches?
Use the following batch file (add to filename.bat):
REG ADD HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit /v LastKey /t REG_SZ /d Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Veritas\NetBackup\CurrentVersion\Config /f
START regedit
to replace:
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Veritas\NetBackup\CurrentVersion\Config
with your registry path.
There's a program called RegJump, by Mark Russinovich, that does just what you want. It'll launch regedit and move it to the key you want from the command line.
RegJump uses (or at least used to) use the same regedit window on each invoke, so if you want multiple regedit sessions open, you'll still have to do things the old fashioned way for all but the one RegJump has adopted. A minor caveat, but one to keep note of, anyway.
From http://windowsxp.mvps.org/jumpreg.htm (I have not tried any of these):
When you start Regedit, it automatically opens the last key that was viewed. (Registry Editor in Windows XP saves the last viewed registry key in a separate location). If you wish to jump to a particular registry key directly without navigating the paths manually, you may use any of these methods / tools.
Option 1
Using a VBScript: Copy these lines to a Notepad document as save as registry.vbs
'Launches Registry Editor with the chosen branch open automatically
'Author : Ramesh Srinivasan
'Website: http://windowsxp.mvps.org
Set WshShell = CreateObject("WScript.Shell")
Dim MyKey
MyKey = Inputbox("Type the Registry path")
MyKey = "My Computer\" & MyKey
WshShell.RegWrite "HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit\Lastkey",MyKey,"REG_SZ"
WshShell.Run "regedit", 1,True
Set WshShell = Nothing
Double-click Registry.vbs and then type the full registry path which you want to open.
Example: HKEY_CLASSES_ROOT\.MP3
Limitation: The above method does not help if Regedit is already open.
Note: For Windows 7, you need to replace the line MyKey = "My Computer\" & MyKey with MyKey = "Computer\" & MyKey (remove the string My). For a German Windows XP the string "My Computer\" must be replaced by "Arbeitsplatz\".
Option 2
Regjump from Sysinternals.com
This little command-line applet takes a registry path and makes Regedit open to that path. It accepts root keys in standard (e.g. HKEY_LOCAL_MACHINE) and abbreviated form (e.g. HKLM).
Usage: regjump [path]
Example: C:\Regjump HKEY_CLASSES_ROOT\.mp3
Option 3
12Ghosts JumpReg from 12ghosts.com
Jump to registry keys from a tray icon! This is a surprisingly useful tool. You can manage and directly jump to frequently accessed registry keys. Unlimited list size, jump to keys and values, get current key with one click, jump to key in clipboard, jump to same in key in HKCU or HKLM. Manage and sort keys with comments in an easy-to-use tray icon menu. Create shortcuts for registry keys.
I'd also like to note that you can view and edit the registry from within PowerShell. Launch it, and use set-location to open the registry location of your choice. The short name of an HKEY is used like a drive letter in the file system (so to go to HKEY_LOCAL_MACHINE\Software, you'd say: set-location hklm:\Software).
More details about managing the registry in PowerShell can be found by typing get-help Registry at the PowerShell command prompt.
Here is one more batch file solution with several enhancements in comparison to the other batch solutions posted here.
It sets also string value LastKey updated by Regedit itself on every exit to show after start the same key as on last exit.
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "RootName=Computer"
set "RegKey=%~1"
if defined RegKey goto PrepareKey
echo/
echo Please enter the path of the registry key to open.
echo/
set "RegKey="
set /P "RegKey=Key path: "
rem Exit batch file without starting Regedit if nothing entered by user.
if not defined RegKey goto EndBatch
:PrepareKey
rem Remove double quotes and square brackets from entered key path.
set "RegKey=%RegKey:"=%"
if not defined RegKey goto EndBatch
set "RegKey=%RegKey:[=%"
if not defined RegKey goto EndBatch
set "RegKey=%RegKey:]=%"
if not defined RegKey goto EndBatch
rem Replace hive name abbreviation by appropriate long name.
set "Abbreviation=%RegKey:~0,4%"
if /I "%Abbreviation%" == "HKCC" set "RegKey=HKEY_CURRENT_CONFIG%RegKey:~4%" & goto GetRootName
if /I "%Abbreviation%" == "HKCR" set "RegKey=HKEY_CLASSES_ROOT%RegKey:~4%" & goto GetRootName
if /I "%Abbreviation%" == "HKCU" set "RegKey=HKEY_CURRENT_USER%RegKey:~4%" & goto GetRootName
if /I "%Abbreviation%" == "HKLM" set "RegKey=HKEY_LOCAL_MACHINE%RegKey:~4%" & goto GetRootName
if /I "%RegKey:~0,3%" == "HKU" set "RegKey=HKEY_USERS%RegKey:~3%"
:GetRootName
rem Try to determine automatically name of registry root.
if not exist %SystemRoot%\Sysnative\reg.exe (set "RegEXE=%SystemRoot%\System32\reg.exe") else set "RegEXE=%SystemRoot%\Sysnative\reg.exe"
for /F "skip=2 tokens=1,2*" %%K in ('%RegEXE% QUERY "HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit" /v "LastKey"') do if /I "%%K" == "LastKey" for /F "delims=\" %%N in ("%%M") do set "RootName=%%N"
rem Is Regedit already running?
%SystemRoot%\System32\tasklist.exe /NH /FI "IMAGENAME eq regedit.exe" | %SystemRoot%\System32\findstr.exe /B /I /L regedit.exe >nul || goto SetRegPath
echo/
echo Regedit is already running. Path can be set only when Regedit is not running.
echo/
set "UserChoice=N"
set /P "UserChoice=Terminate Regedit (y/N): "
if /I "%UserChoice:"=%" == "y" %SystemRoot%\System32\taskkill.exe /IM regedit.exe >nul 2>nul & goto SetRegPath
echo Switch to running instance of Regedit without setting entered path.
goto StartRegedit
:SetRegPath
rem Add this key as last key to registry for Regedit.
%RegEXE% ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit" /v "LastKey" /d "%RootName%\%RegKey%" /f >nul 2>nul
:StartRegedit
if not exist %SystemRoot%\Sysnative\cmd.exe (start %SystemRoot%\regedit.exe) else %SystemRoot%\Sysnative\cmd.exe /D /C start %SystemRoot%\regedit.exe
:EndBatch
endlocal
The enhancements are:
Registry path can be passed also as command line parameter to the batch script.
Registry path can be entered or pasted with or without surrounding double quotes.
Registry path can be entered or pasted or passed as parameter with or without surrounding square brackets.
Registry path can be entered or pasted or passed as parameter also with an abbreviated hive name (HKCC, HKCU, HKCR, HKLM, HKU).
Batch script checks for already running Regedit as registry key is not shown when starting Regedit while Regedit is already running. The batch user is asked if running instance should be terminated to restart it for showing entered registry path. If the batch user chooses not to terminate all instances of Regedit, Regedit is started without setting entered path resulting (usually) in just getting Regedit window to foreground.
The batch file tries to automatically get name of registry root which is on English Windows XP My Computer, on German Windows XP, Arbeitsplatz, and on Windows 7 and newer Windows just Computer. This could fail if the value LastKey of Regedit is missing or empty in registry. Please set the right root name in third line of the batch code for this case.
The batch file runs on 64-bit Windows always Regedit in 64-bit execution environment even on batch file being processed by 32-bit %SystemRoot%\SysWOW64\cmd.exe on 64-bit Windows which is important for registry keys affected by WOW64.
Copy the below text and save it as a batch file and run
#ECHO OFF
SET /P "showkey=Please enter the path of the registry key: "
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit" /v "LastKey" /d "%showkey%" /f
start "" regedit
Input the path of the registry key you wish to open when the batch file prompts for it, and press Enter. Regedit opens to the key defined in that value.
I thought this C# solution might help:
By making use of an earlier suggestion, we can trick RegEdit into opening the key we want even though we can't pass the key as a parameter.
In this example, a menu option of "Registry Settings" opens RegEdit to the node for the program that called it.
Program's form:
private void registrySettingsToolStripMenuItem_Click(object sender, EventArgs e)
{
string path = string.Format(#"Computer\HKEY_CURRENT_USER\Software\{0}\{1}\",
Application.CompanyName, Application.ProductName);
MyCommonFunctions.Registry.OpenToKey(path);
}
MyCommonFunctions.Registry
/// <summary>Opens RegEdit to the provided key
/// <para><example>#"Computer\HKEY_CURRENT_USER\Software\MyCompanyName\MyProgramName\"</example></para>
/// </summary>
/// <param name="FullKeyPath"></param>
public static void OpenToKey(string FullKeyPath)
{
RegistryKey rKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(#"SOFTWARE\Microsoft\Windows\CurrentVersion\Applets\Regedit", true);
rKey.SetValue("LastKey",FullKeyPath);
Process.Start("regedit.exe");
}
Of course, you could put it all in one method of the form, but I like reusablity.
Here is a simple PowerShell function based off of this answer above https://stackoverflow.com/a/12516008/1179573
function jumpReg ($registryPath)
{
New-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit" `
-Name "LastKey" `
-Value $registryPath `
-PropertyType String `
-Force
regedit
}
jumpReg ("Computer\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run") | Out-Null
The answer above doesn't actually explain very well what it does. When you close RegEdit, it saves your last known position in HKCU:\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit, so this merely replaces the last known position with where you want to jump, then opens it.
Create a BAT file using clipboard.exe and regjump.exe
to jump to the key in the clipboard:
clipboard.exe > "%~dp0clipdata.txt"
set /p clipdata=input < "%~dp0clipdata.txt"
regjump.exe %clipdata%
( %~dp0 means "the path to the BAT file" )
Building on lionkingrafiki's answer, here's a more robust solution that will accept a reg key path as an argument and will automatically translate HKLM to HKEY_LOCAL_MACHINE or similar as needed. If no argument, the script checks the clipboard using the htmlfile COM object invoked by a JScript hybrid chimera. The copied data will be split and tokenized, so it doesn't matter if it's not trimmed or even among an entire paragraph of copied dirt. And finally, the key's existence is verified before LastKey is modified. Key paths containing spaces must be within double quotes.
#if (#CodeSection == #Batch) #then
:: regjump.bat
#echo off & setlocal & goto main
:usage
echo Usage:
echo * %~nx0 regkey
echo * %~nx0 with no args will search the clipboard for a reg key
goto :EOF
:main
rem // ensure variables are unset
for %%I in (hive query regpath) do set "%%I="
rem // if argument, try navigating to argument. Else find key in clipboard.
if not "%~1"=="" (set "query=%~1") else (
for /f "delims=" %%I in ('cscript /nologo /e:JScript "%~f0"') do (
set "query=%%~I"
)
)
if not defined query (
echo No registry key was found in the clipboard.
goto usage
)
rem // convert HKLM to HKEY_LOCAL_MACHINE, etc. while checking key exists
for /f "delims=\" %%I in ('reg query "%query%" 2^>NUL') do (
set "hive=%%~I" & goto next
)
:next
if not defined hive (
echo %query% not found in the registry
goto usage
)
rem // normalize query, expanding HKLM, HKCU, etc.
for /f "tokens=1* delims=\" %%I in ("%query%") do set "regpath=%hive%\%%~J"
if "%regpath:~-1%"=="\" set "regpath=%regpath:~0,-1%"
rem // https://stackoverflow.com/a/22697203/1683264
>NUL 2>NUL (
REG ADD "HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit"^
/v "LastKey" /d "%regpath%" /f
)
echo %regpath%
start "" regedit
goto :EOF
#end // begin JScript hybrid chimera
// https://stackoverflow.com/a/15747067/1683264
var clip = WSH.CreateObject('htmlfile').parentWindow.clipboardData.getData('text');
clip.replace(/"[^"]+"|\S+/g, function($0) {
if (/^\"?(HK[CLU]|HKEY_)/i.test($0)) {
WSH.Echo($0);
WSH.Quit(0);
}
});
This seems horribly out of date, but Registration Info Editor (REGEDIT) Command-Line Switches claims that it doesn't support this.
You can make it appear like regedit does this behaviour by creating a batch file (from the submissions already given) but call it regedit.bat and put it in the C:\WINDOWS\system32 folder. (you may want it to skip editting the lastkey in the registry if no command line args are given, so "regedit" on its own works as regedit always did) Then "regedit HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0" will do what you want.
This uses the fact that the order in PATH is usually C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem; etc
If the main goal is just to avoid "the clicking", then in Windows 10 you can just type or paste the destination path into RegEdit's address bar and hit enter.
The Computer\ prefix here is added automatically. It will also work if you simply type or paste a path starting with e.g. HKEY_CURRENT_USER\....
PowerShell code:
# key you want to open
$regKey = "Computer\HKEY_LOCAL_MACHINE\Software\Microsoft\IntuneManagementExtension\Policies\"
# set starting location for regedit
Set-ItemProperty "HKCU:\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit" "LastKey" $regKey
# open regedit (-m allows multiple regedit windows)
regedit.exe -m
This is the best answer overall, as it's quick, simple and there's no need to install any program.
By Byron Persino, improved by Matt Miller. (Many thanks to both of them!)
I'm rewording more correctly and clearly to help other readers like me, as I had a lot of trouble getting it clear and make it working.
Make a .bat file, eg. 'GoToRegEditPath.bat' , write the following code inside and save it:
CODE:
#echo off
set /p regPath="Open regedit at path: "
REG ADD HKCU\Software\Microsoft\Windows\CurrentVersion\Applets\Regedit /v LastKey /t REG_SZ /d "%regPath%" /f
START regedit
exit
:: source:
https://stackoverflow.com/questions/137182/how-to-launch-windows-regedit-with-certain-path?answertab=modifieddesc#tab-top
Maybe this .bat use must "Run as Administrator"
To use it, Just run it and paste (R-Click) in it the copied RegEdit Path.
Tip: if R-click does not work inside command prompt:
R-click on title bar > Properties > check both under "Edit Options"