Access is denied when use del /f in windows 10 64bit - windows

I'm going to delete 1.mp3 but it gives me the error "Access is denied".
More info about file's perms:
attrib 1.mp3
A C:\Users\Alipour\Desktop\1\1.mp3
I also used attrib -s -h 1.mp3
but still it can not be deleted by
del /f/s/q 1.mp3 > NUL
or
del /f/s/q 1.mp3
or
del /f 1.mp3

There are several methods to remove such a file:
1. Process Explorer if the file is in use:
You can use ProcessExplorer from Windows Sysinternals to identifiy which program locks the file. Download and start ProcessExplorer and go to Find|Find Handle or DLL... Ctrl+F and enter the name of the locked file: 1.mp3.
ProcessExplorer will show you the process that is responsible for the lock because of accessing the file. If you've got the proccess kill that one and delete the file.
Example with MS Word accessing a file called LockedFile.docx:
2. Safe mode boot:
Another possibility is to boot into safe mode. In pre Windows 8 era this was done by pressing F8 before Windows boots.
In Windows 8 and higher you can press Shift+F8 before Windows boots or more easily you can hold Shift and click Restart in the login screen or even in Windows. If this was too short, look here how to get into safe mode.
Once you're in the safe mode you can try again deleting that file.
3. Remove file on Windows boot via PendingFileRenameOperations:
With PendingFileRenameOperations you can rename and even delete a file on Windows boot procedure when nothing else can access and block that file.
PendingFileRenameOperations will be entered in the Windows registry and consists of pairs of file paths.
You can do it manually as described below or again with a Windows Sysinternals program called MoveFile. Download that program and use it in a console window (Start -> Run or Windows-Key+R, type cmd and press ENTER).
Type movefile foo.exe "" to delete a file on reboot.
Manual method via registry:
The 1st path is the file to be renamed.
The 2nd path is the new file path.
If the 2nd path is empty (0x0000) the file get's removed.
Start -> Run or Windows-Key+R
Type in regedit, and press ENTER
Goto HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager
Create a new Multi-String value: PendingFileRenameOperations
Enter \??\filepath as the data (e.g. \??\C:\Users\xyz\Desktop\foo.exe)
Press OK
Right-click on the key, click Modify Binary Data
At the end of the hex string, add 0000 (4 zeros which represent an empty string)
Press OK
Restart your computer

Lean and mean batch-file only alternatives for PendingFileRenameOperations:
~ Scripts will add an entry to right-click -- "SendTo" menu
~ Accepting a single parameter, either File or Folder
~ Confirmation prompt ([Cancel] to Clear previous entries)
~ Basic idiot proofing (don't process %Windir% for example)
Rename_On_Boot.bat
goto="Batch" /* Rename_On_Boot by AveYo v1
:RenOnBoot
set "input=%*" & call set "input=%%input:?=%%" &rem line below adds entry to right-click -- "SendTo" menu
if /i "_%~dp0"=="_%APPDATA%\Microsoft\Windows\SendTo\" (set .=) else copy /y "%~f0" "%APPDATA%\Microsoft\Windows\SendTo\" >nul 2>nul
if "_%1"=="_" color 4f & echo ERROR! No input provided & ping -n 6 localhost >nul & exit /b
for %%# in ("C:\" "C:\Boot" "C:\Recovery" "%WINDIR%" "%WINDIR%\system32" "%ProgramData%" "%ProgramFiles%" "%USERPROFILE%") do (
if /i "_%input%"=="_%%~#" color 4f & echo ERROR! %%# is not safe to delete & ping -n 6 localhost >nul & exit /b
)
color 0B & echo Please wait, folders might take a while .. & call cscript /nologo /e:JScript "%~f0" RenOnBoot "%input%" & exit /b
:RenOnBoot_Run_As_Admin
color 4f & echo Asking permission to run as Admin.. & call cscript /nologo /e:JScript "%~f0" RunAsAdmin "%~f1???" & exit /b
:"Batch"
#echo off & setlocal disabledelayedexpansion & mode 96,4 & echo. & title %~nx0 by AveYo & if not exist "%~f1" goto :RenOnBoot
reg query HKEY_USERS\S-1-5-20\Environment /v temp 1>nul 2>nul && goto :RenOnBoot || goto :RenOnBoot_Run_As_Admin
:"JScript" */
function RenOnBoot(f){
var HKLM=0x80000002, k='SYSTEM\\CurrentControlSet\\Control\\Session Manager', v='PendingFileRenameOperations';
var reg=GetObject('winmgmts:{impersonationLevel=impersonate}!//./root/default:StdRegProv'), ws=WSH.CreateObject('WScript.Shell');
var confirmation=ws.Popup(" Rename on next boot? [OK]\n Clear previous entries? [Cancel]\n\n "+f,0,'Rename_On_Boot by AveYo',33);
if (confirmation == 2) { reg.DeleteValue(HKLM, k, v); WSH.quit(); } // Clear existing entries on Cancel press and quit script
var mtd=reg.Methods_('GetMultiStringValue').InParameters.SpawnInstance_(); mtd.hDefKey=HKLM; mtd.sSubKeyName=k; mtd.sValueName=v;
var query=reg.ExecMethod_('GetMultiStringValue', mtd), regvalue=(!query.ReturnValue) ? query.SValue.toArray():[,], entries=[];
var fso=new ActiveXObject('Scripting.FileSystemObject'), fn=fso.GetAbsolutePathName(f);
entries.push('\\??\\'+fn,'\\??\\'+fn+'.ren');
reg.CreateKey(HKLM, k); reg.SetMultiStringValue(HKLM, k, v, entries.concat(regvalue));
}
if (WSH.Arguments.length>=2 && WSH.Arguments(0)=='RenOnBoot') RenOnBoot(WSH.Arguments(1));
function RunAsAdmin(self, arguments) { WSH.CreateObject('Shell.Application').ShellExecute(self, arguments, '', 'runas', 1) }
if (WSH.Arguments.length>=1 && WSH.Arguments(0)=='RunAsAdmin') RunAsAdmin(WSH.ScriptFullName, WSH.Arguments(1));
//
Delete_On_Boot.bat
goto="Batch" /* Delete_On_Boot by AveYo v1
:DelOnBoot
set "input=%*" & call set "input=%%input:?=%%" &rem line below adds entry to right-click -- "SendTo" menu
if /i "_%~dp0"=="_%APPDATA%\Microsoft\Windows\SendTo\" (set .=) else copy /y "%~f0" "%APPDATA%\Microsoft\Windows\SendTo\" >nul 2>nul
if "_%1"=="_" color 4f & echo ERROR! No input provided & ping -n 6 localhost >nul & exit /b
for %%# in ("C:\" "C:\Boot" "C:\Recovery" "%WINDIR%" "%WINDIR%\system32" "%ProgramData%" "%ProgramFiles%" "%USERPROFILE%") do (
if /i "_%input%"=="_%%~#" color 4f & echo ERROR! %%# is not safe to delete & ping -n 6 localhost >nul & exit /b
)
color 0B & echo Please wait, folders might take a while .. & call cscript /nologo /e:JScript "%~f0" DelOnBoot "%input%" & exit /b
:DelOnBoot_Run_As_Admin
color 4f & echo Asking permission to run as Admin.. & call cscript /nologo /e:JScript "%~f0" RunAsAdmin "%~f1???" & exit /b
:"Batch"
#echo off & setlocal disabledelayedexpansion & mode 96,4 & echo. & title %~nx0 by AveYo & if not exist "%~f1" goto :DelOnBoot
reg query HKEY_USERS\S-1-5-20\Environment /v temp 1>nul 2>nul && goto :DelOnBoot || goto :DelOnBoot_Run_As_Admin
:"JScript" */
function DelOnBoot(f){
ListDir=function(src, _root,_list) {
_root=_root || src, _list=_list || [];
var root=fso.GetFolder(src), files=new Enumerator(root.Files), dirs=new Enumerator(root.SubFolders);
while (!files.atEnd()) { _list.push(files.item()); files.moveNext(); }
while (!dirs.atEnd()) { _list=ListDir(dirs.item().path, _root,_list); _list.push(dirs.item()); dirs.moveNext(); }
return _list;
};
var HKLM=0x80000002, k='SYSTEM\\CurrentControlSet\\Control\\Session Manager', v='PendingFileRenameOperations';
var reg=GetObject('winmgmts:{impersonationLevel=impersonate}!//./root/default:StdRegProv'), ws=WSH.CreateObject('WScript.Shell');
var confirmation=ws.Popup(" Delete on next boot? [OK]\n Clear previous entries? [Cancel]\n\n "+f,0,'Delete_On_Boot by AveYo',33);
if (confirmation == 2) { reg.DeleteValue(HKLM, k, v); WSH.quit(); } // Clear existing entries on Cancel press and quit script
var mtd=reg.Methods_('GetMultiStringValue').InParameters.SpawnInstance_(); mtd.hDefKey=HKLM; mtd.sSubKeyName=k; mtd.sValueName=v;
var query=reg.ExecMethod_('GetMultiStringValue', mtd), regvalue=(!query.ReturnValue) ? query.SValue.toArray():[,], entries=[];
var fso=new ActiveXObject('Scripting.FileSystemObject'), fn=fso.GetAbsolutePathName(f);
if (fso.FolderExists(fn)) { var list=ListDir(fn); for (var i in list) entries.push('\\??\\'+list[i],''); }
entries.push('\\??\\'+fn,'');
reg.CreateKey(HKLM, k); reg.SetMultiStringValue(HKLM, k, v, entries.concat(regvalue));
}
if (WSH.Arguments.length>=2 && WSH.Arguments(0)=='DelOnBoot') DelOnBoot(WSH.Arguments(1));
function RunAsAdmin(self, arguments) { WSH.CreateObject('Shell.Application').ShellExecute(self, arguments, '', 'runas', 1) }
if (WSH.Arguments.length>=1 && WSH.Arguments(0)=='RunAsAdmin') RunAsAdmin(WSH.ScriptFullName, WSH.Arguments(1));
//

You can find out which program is locking a certain file with “Process Explorer → Find → Find handles or DLLs.”
For example, if the locker is explorer.exe, the Windows explorer, you can delete the file after killing Windows explorer in Task manager.

When del /f <FILE> producing an Access Denied error, you need to firstly take owner and grant access using takeown and icacls command line utilities, Please see an example: Delete a specific file on Windows.

Related

The VBScript Command Line Conundrum?

I have an HTA where I can pass an IP (user input in an HTML text box as txtIP.value) to a vendor's management software - all that works. However, sometimes the device won't respond to a GUI request, but will respond to a ping request. I have a really nice ping command I use which passes what the ping command returns to another cmd which changes the prompt to show the times for each reply which allows me to watch multiple devices and coordinate lost or high pings. I cannot for the life of me get this command to pass to the command line. Any and all help is appreciated.
'********************************************************************
'Trying to run the following command:
'* ping -t 172.17.100.33|cmd /q /v /c "(pause&pause)>nul & for /l %a in () do (set /p "data=" && echo(!time! !data!)&ping -n 2 localhost>nul"
'********************************************************************
Sub TimedPing
'Set the HTML Field value - for testing purposes
txtIP.value = "172.17.100.33"
strIP1 = "ping -t "
strIP2 = txtIP.value
strIP3 = "|cmd /q /v /c "
strIP4 = """(pause&pause)>nul & "
strIP5 = "for /l %a in ()"
strIP6 = "do (set /p "
strIP7 = " ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul"""
Set objShell = CreateObject ("WScript.Shell")
MsgBox("Step 1: " & strIP1 & strIP2 & strIP3 & strIP4 & strIP5 & strIP6 & strIP7)
txtCmd1.value = strIP1 & strIP2 & strIP3 & strIP4 & strIP5 & strIP6 & strIP7
objShell.Run strIP1 & strIP2 & strIP3 & strIP4 & strIP5 & strIP6 & strIP7
MsgBox("Step 2: " & "ping -t 172.17.100.33|cmd /q /v /c ""(pause&pause)>nul & for /l %a in () do (set /p ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul""")
txtCmd2.value = "ping -t 172.17.100.33|cmd /q /v /c ""(pause&pause)>nul & for /l %a in () do (set /p ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul"""
objShell.Run "ping -t 172.17.100.33|cmd /q /v /c ""(pause&pause)>nul & for /l %a in () do (set /p ""data="" && echo(!time! !data!)&ping -n 2 localhost>nul"""
MsgBox("Step 3: " & strIP1 & strIP2)
objShell.Run strIP1 & strIP2
MsgBox("Step 4: CMD")
objShell.Run "cmd"
End Sub
Step 1 compiles (HTA refreshes without an error message) and run without visible error. The DOS screen opens and closes instantly, without showing anything. I have tried to put a pause in there, but it doesn't work either.
Step 2 does the same thing.
Step 3 works fine.
Step 4 works fine.
I dumped the values I am sending the objShell.Run command to separate text boxes to compare how they match up to the original. After getting the results identical to the original command, I can copy the text from the HTA and run it in a command window without error for both step one and two, but I get nothing but a quickly closing command window from the Run command. Any ideas?
Maybe one day, someone will find an answer to this. Until then, the only way I could execute this command was to use a bat file (after hours of trying to not make one - I got this working with variable IP address and colors in a couple hours). Funny enough, like Geert Bellekens mentioned, I had to start the bat file with some other command (I used #echo off), and then I had to double up on the percent sign in the command itself. For completeness sake, below is the code to run call the bat file, pass some variables (IP Address and Color Theme) and then the bat file working. FYI, I used an If-Then-Else statement to check which Theme the user has selected and the second variable in the VBS script change according to the color they selected. I'll show the default.
VBScript in HTA triggered by HTML button click.
Sub TimedPing
Set objShell = CreateObject ("WScript.Shell")
objShell.Run "TimedPing.bat " & txtIP.value & " " & 07
End Sub
Bat file stored in the same directory as the HTA:
#echo off
title Timed Ping
color %2
#ping -t %1|cmd /q /v /c "(pause&pause)>nul & for /l %%a in () do (set /p "data=" && echo(!time! !data!)&ping -n 2 localhost>nul"

How to close all sub folders of one folder?

For example I have this folder "C:\Series" and I have this script below which closes this folder when it is opened
#echo off
cd /d C:\ start C:\Windows\explorer.exe CD_Restored
rem Terminate process: taskkill /F /FI "WINDOWTITLE eq Music" /IM explorer.exe > nul
It works successfully, but when I open any folder inside it, this code surely doesn't work, and I need to close any opened folder inside it. I have over 15 subfolders inside it, so I can't make a script line for each of them, especially that I am always updating it.
So could any one tell me how to make a script which closes a folder and its subfolders?
Just give a try for this batch file that use a vbscript :
#echo off
Title Close Opened Folders
Set "MainFolderName=series"
Call :CloseAllOpenedFolders "%MainFolderName%"
Pause & Exit
::---------------------------------------------------------------------------------------
:CloseAllOpenedFolders <MainFolderName>
Set "VBSFILE=%Temp%\CloseAllOpenedFolders.vbs"
(
echo Dim MainFolder,shell,oWindows,W
echo MainFolder = "%~1"
echo Set shell = CreateObject("Shell.Application"^)
echo set oWindows = shell.windows
echo For Each W in oWindows
echo If InStr(LCase(W.document.folder.self.Path^),LCase(MainFolder^)^)^> 0 Then
echo wscript.echo W.document.folder.self.Path
echo W.Quit
echo End If
echo Next
)>"%VBSFILE%"
Cscript //NoLogo "%VBSFILE%"
Exit /B
::---------------------------------------------------------------------------------------
EDIT : Powershell Solution
$mainFolder= "c:\series"
$shell = New-Object -ComObject Shell.Application
$window = $shell.Windows() | ? { $_.LocationURL -like "$(([uri]$MainFolder).AbsoluteUri)*" }
$window.document.Folder.Self.Path
$window | % { $_.Quit() }

Is it possible to output the current color code on the command prompt using batch programming?

I am making a tutorial program for a friend of mine using batching programming. I would like to know if it is possible if there is code I can write in the file that will display the current color code.
Example being the color is currently set to 0A and I want be displayed on the line saying:
echo The color is currently set to 0A.
I want my file to read the code that is set to and display it to help them remember what changes they have made as this is an example program for color codes in the command prompt/batch.
Thank you for your help!
It is easy to make your own command to do this. Copy both below text files into GetConsoleColour.bat and GetConsoleColour.vb in the same folder. Double click the batch file and it will create GetConsoleColour.exe.
PS Colour is spelt right for my culture. As I'm writing it I don't see any need to use American spelling which in programming you usually have to do.
See https://learn.microsoft.com/en-us/windows/console/getconsolescreenbufferinfo
GetConsoleColour.exe prints the current console colour in hex and returns an errorlevel with the value
To use
C:\PathToFile\GetConsoleColour
I have a program here that sets text color line by line. It is the only technique that will work on all Windows computers.
Command Prompt Scripting: Problem with multiple colors in a batch file.
Also a similar program saying how many processes are in this console window - ListConsole.exe list the processes in the current console and returns an errorlevel saying how many
. https://winsourcecode.blogspot.com/2019/05/listconsoleexe-list-processes-in.html
REM GetConsoleColour.bat
REM This file compiles GetConsoleColour.vb to GetConsoleColour.exe
REM GetConsoleColour.exe prints the current console colour and returns an errorlevel with the value
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe" /target:exe /out:"%~dp0\GetConsoleColour.exe" "%~dp0\GetConsoleColour.vb"
pause
Note: There is only 4 lines of code here. The rest is just information the program needs to do those 4 lines. In a big program they would be hidden away in a separate file.
'GetConsoleColour.vb
Imports System
Imports System.IO
Imports System.Runtime.InteropServices
Imports Microsoft.Win32
Public Module MyApplication
Public Declare Function GetStdHandle Lib "kernel32" Alias "GetStdHandle" (ByVal nStdHandle As Long) As Long
Public Declare Function SetConsoleTextAttribute Lib "kernel32" Alias "SetConsoleTextAttribute" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
Public Declare Function GetConsoleScreenBufferInfo Lib "kernel32" (ByVal hConsoleOutput As Integer, ByRef lpConsoleScreenBufferInfo As CONSOLE_SCREEN_BUFFER_INFO) As Integer
Public Const STD_ERROR_HANDLE = -12&
Public Const STD_INPUT_HANDLE = -10&
Public Const STD_OUTPUT_HANDLE = -11&
<StructLayout(LayoutKind.Sequential)> _
Public Structure COORD
Public x As Short
Public y As Short
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure SMALL_RECT
Public Left As Short
Public Top As Short
Public Right As Short
Public Bottom As Short
End Structure
<StructLayout(LayoutKind.Sequential)> _
Public Structure CONSOLE_SCREEN_BUFFER_INFO
Public dwSize As COORD
Public dwCursorPosition As COORD
Public wAttributes As Integer
Public srWindow As SMALL_RECT
Public dwMaximumWindowSize As COORD
End Structure
Sub Main()
Dim hOut as IntPtr
Dim Ret as Integer
Dim CSBI as Console_Screen_Buffer_Info
hOut = GetStdHandle(STD_OUTPUT_HANDLE)
Ret = GetConsoleScreenBufferInfo(hOut, CSBI)
Console.Writeline(Hex(CSBI.wAttributes))
Environment.ExitCode = CSBI.wAttributes
End Sub
End Module
As already indicated in another answer, you can use powershell from your batch-file to show you the current color sequence:
#(Set/P "=The color is currently set to "<NUL&For /F %%# In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "$Console=(Get-Host).UI.RawUI;Switch($Console.BackgroundColor,$Console.ForegroundColor){'Black'{'0'}'DarkBlue'{'1'}'DarkGreen'{'2'}'DarkCyan'{'3'}'DarkRed'{'4'}'DarkMagenta'{'5'}'DarkYellow'{'6'}'Gray'{'7'}'DarkGray'{'8'}'Blue'{'9'}'Green'{'A'}'Cyan'{'B'}'Red'{'C'}'Magenta'{'D'}'Yellow'{'E'}'White'{'F'}}" 2^>NUL^"')Do #Set/P=%%#<NUL)&Echo(&Pause
You should also be able to do it from the command-prompt thus:
(Set/P "=The color is currently set to "<NUL&For /F %# In ('^""%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP "$Console=(Get-Host).UI.RawUI;Switch($Console.BackgroundColor,$Console.ForegroundColor){'Black'{'0'}'DarkBlue'{'1'}'DarkGreen'{'2'}'DarkCyan'{'3'}'DarkRed'{'4'}'DarkMagenta'{'5'}'DarkYellow'{'6'}'Gray'{'7'}'DarkGray'{'8'}'Blue'{'9'}'Green'{'A'}'Cyan'{'B'}'Red'{'C'}'Magenta'{'D'}'Yellow'{'E'}'White'{'F'}}" 2^>NUL^"')Do #Set/P=%#<NUL)&Echo(
By making a compromise and using setlocal EnableDelayedExpansion, you can do so using the following:
#ECHO OFF
Setlocal enableDelayedExpansion
Set "Color=Color 02" && !color!
ECHO Color is currently %color%
pause
The downside of this approach being changing console Color becomes a 2 Step process
(depending on how your displaying information).
Updated based in comments from #phuclv
#echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
#set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White"" && cd/d "%~dp0" && title %0
;for /f %%I in ('powershell echo "$([console]::ForegroundColor) $([console]::BackgroundColor)"
')do for %%# in (!_color!)do set "_Hex=%%~#"&& for /f %%a in ('cd')do if "%%~I"=="!_Hex:~2!" (
if not "!_FB!"=="!_Hex:~1,1!" ( set "_FB=!_Hex:~0,1!!_FB!" && set "_L= !_Hex:~2!!_L!"))
set "_L=!_L:~1!"&& cmd/v/c echo The color is currently set to !_FB! (!_L: =/!^)&&endlocal
Output:
The color is currently set to 0A (Black/Green)
rem :: powershell command ::
echo "$([console]::BackgroundColor) $([console]::ForegroundColor)"
#echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
;set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White"" && cd/d "%~dp0" && title %0
for /f %%I in ('powershell echo "$Host.UI.RawUI.BackgroundColor $Host.UI.RawUI.ForegroundColor"
')do for %%# in (!_color!)do set "_Hex=%%~#"&& for /f %%a in ('cd')do if "%%~I"=="!_Hex:~2!" (
if not "!_FB!"=="!_Hex:~1,1!" ( set "_FB=!_Hex:~0,1!!_FB!" && set "_L= !_Hex:~2!!_L!" ))
set "_L=!_L:~1!"&& cmd/v/c echo The color is currently set to !_FB! (!_L: =/!^)&&endlocal
Output:
The color is currently set to 0A (Black/Green)
rem :: powershell command ::
echo "$Host.UI.RawUI.BackgroundColor $Host.UI.RawUI.ForegroundColor"
Generate C# .exe in Run Time
This bat file that generate a file cFB.cs (colorForegroundBackground.C#) and in run time, will build the executable cFB.exe for execute them using ConsoleColor Enum
#echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
#set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White"" && cd/d "%~dp0" && title %0
for %%D in (.exe,.cs) do if exist "%temp%\cFB%%~D" (2>nul >nul del /q /f "%temp%\cFB%%~D")
set "_csc=%windir%\Microsoft.NET"&& set "_where=%__appdir__%where.exe" && set "_cs=cFB.cs"
set "_arg=/t:exe /out:"%tmp%\!_cs:~,-3!.exe" "%tmp%\!_cs!" /platform:x86 /unsafe+ /w:0 /o"
set "_c=!_where! /r "!_csc!" "csc.exe" "&& set "_#=%temp%\!_cs!" && cmd/v/c echo=&>"!_#!"^
(
echo/ using System; namespace cFB ^{class Program ^{public static void Main(^)^{
echo/ ConsoleColor currentForeground=Console.ForegroundColor;
echo/ ConsoleColor currentBackground=Console.BackgroundColor;
echo/ Console.WriteLine("{0}\n{1}",Console.ForegroundColor,Console.BackgroundColor^);^}^}^}
) && (pushd "%temp%" & goto :run)||echo=Well, something is really wrong here^!! & goto :Err
:run
for /f tokens^=* %%i in ('!_c!^|find "k\v2"')do "%%~i" /nologo !_arg!&& if exist "!_#:~0,-3!.exe" (
for /f ^delims^=^ ^eol^= %%r in ('"!_#:~0,-3!.exe"')do set "_Hex=%%r") else (popd && cls 2>nul && (
echo=File: "!_#:~0,-3!.exe" not found, something is really wrong here^^!!& timeout -1& goto :Err) )
for /f tokens^=^*^delims^= %%I in ('"!_#:~0,-3!.exe"')do for %%# in (!_color!)do set "_h=%%~#" && (
if "%%~I"=="!_h:~2!" if not "!_fb!"=="!_h:~0,l!" (set "_fb=!_h:~0,1!!_fb!"&&set "_l= !_h:~2!!_l!"))
set "_l=!_l:~1!" && for %%D in (.exe,.cs) do if exist "%temp%\cFB%%~D" >nul del /q "%temp%\cFB%%~D"
cmd /v /c echo The color is currently set to: !_fb! (!_l: =/!^) && endlocal && exit /b || goto :EOF
:Err
endlocal & exit /b || goto :EOF
This is C# code without escaping:
using System;
namespace CBF
{
class Program
{
public static void Main()
{
ConsoleColor currentBackground=Console.BackgroundColor;
ConsoleColor currentForeground=Console.ForegroundColor;
Console.WriteLine("{0}\n{1}",Console.ForegroundColor,Console.BackgroundColor);
}
}
}
Bat Run C# Commmand Output:
The color is currently set to: 0A (Black/Green)
Command line to build executable:
"C:\Windows\Microsoft.NET\Framework\v2.0.50727\csc.exe" /nologo /t:exe /out:"%temp%\cFB.exe" "%temp%\cFB.cs" /platform:x86 /w:0 /o
You also, can try get some help with $Host.UI.RawUI in powershell?
#echo off && setlocal EnableDelayedExpansion
set "_color="0 Black","1 DarkBlue","2 DarkGreen","3 DarkCyan","4 DarkRed","
#set "_color=!_color!"5 DarkMagenta","6 DarkYellow","7 Gray","8 DarkGray","
set "_color=!_color!"9 Blue","A Green","B Cyan","C Red","D Magenta","
set "_color=!_color!"E Yellow","F White""&& cd/d "%~dp0" && title %~0
for /f tokens^=2^delims^=^:^ %%I in ('powershell -nOp $Host.UI.RawUI^|find "Color"')do (
for %%# in (!_color!)do set "_Hex=%%~#"&& for /f %%a in ('cd')do if "%%~I"=="!_Hex:~2!" (
if not "!_FB!"=="!_Hex:~1,1!" ( set "_FB=!_Hex:~0,1!!_FB!" && set "_L= !_Hex:~2!!_L!" )))
set "_L=!_L:~1!"&& cmd/v/c echo The color is currently set to !_FB! (!_L: =/!^)&&endlocal
Bat File Output:
The color is currently set to A3 (Green/DarkCyan)
rem :: just type ::
powershell -nop -c "$Host.UI.RawUI"|find "Color"
rem :: or -nop -c
powershell "$Host.UI.RawUI"|find "Color"
$Host.UI.RawUI Output:
ForegroundColor : White
BackgroundColor : Blue
$Host.UI.RawUI Full output:
ForegroundColor : White
BackgroundColor : Blue
CursorPosition : 0,108
WindowPosition : 0,90
CursorSize : 25
BufferSize : 99,770
WindowSize : 89,48
MaxWindowSize : 99,50
MaxPhysicalWindowSize : 174,50
KeyAvailable : False
WindowTitle : Q59449889v2.cmd - powershell $Host.UI.RawUI
Sorry my limited English
As a riff on all the powershell answers, you can also pull just the color descriptors by embedding the PS command in a FOR /f command, for example, (where the color is token 3)
setlocal enabledelayedexpansion
#for /f "tokens=3" %%i in ('powershell "$Host.UI.RawUI"^|find "Color"') do (
set /a _cnt+=1
IF !_cnt! equ 1 set _colorF=%%i
IF !_cnt! equ 2 set _colorB=%%i
)
setlocal disabledelayedexpansion
echo %_colorF%
echo %_colorB%

Windows Filename & Path Validator batch tool

I'm developing a pure Windows batch tool FileNameValidator that checks if supplied with batch arguments or typed by a user file paths & names are absolute & valid under current Windows version, before user code is run using these paths\names. The tool is different from snippets posted on this topic on SO, as it presents an automated user input validator for multiple path & file names entered either as batch arguments or typed manually. Other threads solutions are based on manual single path or name check by using regex. This tool checks path & file validity by test-writing a target folder to disk. So far the tool can check up to 9 local or network filepath & name arguments. "Local drives only" limitation was lifted.
I ask, how to a) check more than 9 arguments, b) lift user input requirements stated in code comments. None of these questions were addressed in a few SO threads on this topic. The tool is purely batch based, while other topics discuss C++ regex, or powershell related techniques, or limited batch regex supported by FINDSTR.
#echo off
setlocal EnableExtensions EnableDelayedExpansion
:: Checks if files name.ext or path entered as arguments or typed are absolute & valid in installed Windows version
:: by trying to create a new directory with a given path\name, if not exists already and target disk is accesible
:: If missing in batch arguments or invalid, user can type new or add to ":default" & choose default file names or paths
:: File variable names must use matching 3-letter ID with "save to" directory path variables (i.e. esd_dir\esd_file)
:: Default values, path & name variables, and arguments numbering must match ([arg1 & dir1 & pat1],[var.iso & file.iso])
:default
set "mes1= Invalid dir path or file name" & set "mes2= The dir or file already exists"
set "mes3=Use (d)efault, e(x)isting, or (r)e-enter value?" & set "mes4= Entered name is a directory"
set "mes5=value used:" & set "mes6= No default value exists" & set "mes7=is empty or invalid"
set "mes8=All arguments are entered" & set "mes9=C(o)ntinue, (r)e-enter arguments, or e(x)it?"
set "pat1=winsource_dir" & set "pat2=iso_dir" & set "pat3=esd_dir" & set "pat4=esd_file.iso"
set "dir1=K:\Temp\Tests\Windows_files" & set "dir2=K:\Temp\Tests\Modified_iso"
set "dir3=K:\Temp\Tests\Esd_files" & set "dir4=Final.iso" & set "i=1" & echo/
:input
if not defined pat%i% (echo/ & echo %mes8% & echo/ & set /a "i-=1
(for /l %%k in (1,1,!i!) do (echo !pat%%k! = !path%%k!)) & echo/
choice /c orx /n /m "%mes9%" /t 20 /d o & echo/
if errorlevel 3 (goto :end) else if errorlevel 2 (set "i=1" & set "ver=" & goto :input) else (goto :core)
) else if not defined ver (call set "path%i%=%%~%i%"
if not defined path%i% (echo Batch arg%i% %mes7% & set "ver=1"
) else (echo Read arg%i% = !path%i%!))
if defined ver (set "ver=" & set /p "path%i%=Enter !pat%i%! > " 2>nul)
set "!pat%i%!=!path%i%!" & set "cho="
if "!pat%i%:~-4,1!"=="." (
if not "!path%i%:~-4!"=="!pat%i%:~-4!" (echo %mes1% & set "cho=1"
) else ( set "break=" & for /l %%j in (1,1,9) do (
if not defined break if "!pat%%j:~0,3!"=="!pat%i%:~0,3!" (set "break=TRUE"
set "pathf%i%=!path%i%!" & set "path%i%=!path%%j!\!path%i%!"
if not exist !path%%j! set "pathp%i%=!path%%j!")))
) else if not exist "!path%i%:~0,3!" if not "!path%i%:~0,2!"=="\\" (echo %mes1% & set "cho=1")
if exist "!path%i%!" if not defined cho (
if exist "!path%i%!\*" if "!pat%i%:~-4,1!"=="." (echo %mes4% & set "cho=1"
) else (echo %mes2% & set "cho=2"))
if not defined cho (md "!path%i%!" 2>nul
if errorlevel 1 (echo %mes1% & set "cho=1"
) else ( rmdir /s /q "!path%i%!" & set "cho="
(if "!pat%i%:~-4,1!"=="." set "path%i%=!pathf%i%!") & echo Entered %mes5% !path%i%!)
if defined pathp%i% rmdir /s /q "!pathp%i%!")
if defined cho (choice /c dxr /n /m "%mes3%" /t 20 /d d
if errorlevel 3 (set "ver=1") else if errorlevel 2 (
if !cho! equ 2 (set "ver=" & echo Existing %mes5% !path%i%!) else (set "ver=1" & echo %mes1%)
) else (if not "!dir%i%!"=="" (set "path%i%=!dir%i%!" & set "ver=" & echo Default %mes5% !dir%i%!
) else (set "ver=1" & echo %mes6%)))
(if not defined ver set /a "i+=1") & goto :input
:core
:: add your code here that uses pat# variable values as path\file variable names
:end
echo/ & echo Exiting program...
timeout /t 1 /nobreak >nul
exit /b
Here's a sample use case:
K:\Temp\Tests>test.bat "K:\Temp\Tests1" "K:\Temp\Tests]>" "" "Final:.iso"
Read arg1 = K:\Temp\Tests1
Entered value used: K:\Temp\Tests1
Read arg2 = K:\Temp\Tests]>
Invalid dir path or file name
Use (d)efault, e(x)isting, or (r)e-enter value? R
Enter iso_dir > K:\Temp\Tests2
Entered value used: K:\Temp\Tests2
Batch arg3 is empty or invalid
Enter esd_dir > \\MyNetworkDrive\Test
Invalid dir path or file name
Use (d)efault, e(x)isting, or (r)e-enter value? D
Default value used: K:\Temp\Tests\Esd_files
Read arg4 = Final:.iso
Invalid dir path or file name
Use (d)efault, e(x)isting, or (r)e-enter value? R
Enter esd_file.iso > Final.txt
Invalid dir path or file name
Use (d)efault, e(x)isting, or (r)e-enter value? R
Enter esd_file.iso > Final.iso
Entered value used: Final.iso
All arguments are entered
winsource_dir = K:\Temp\Tests1
iso_dir = K:\Temp\Tests2
esd_dir = K:\Temp\Tests\Esd_files
esd_file.iso = Final.iso
C(o)ntinue, (r)e-enter arguments, or e(x)it?
Exiting program...
K:\Temp\Tests>

Pulling text from a .txt file to insert into a batch file to run an exe

Im very new to this and would love some help.
Im trying to run a program in command line but i need to add a drive letter that changes and a part number that also changes.
example:
start "" "U:\ISO\fileTool\file_Update.exe /m:(PARTNUMBER) /t:(DRIVELETTER) /v /l:logfile.text"
The program uses what is after m: for the part number I need.
It also uses what comes after T: for the drive letter I want to copy to.
I want to be able to choose if the v (validate) is inserted.
I want to choose if the l (logfile) is inserted.
As part of the prep I have a batch file to ask the user for the part number, drive letter, if they want to validate and if they want a log file. The output of that is a text file that looks like this without the information in the brackets
text file output:
Variable One = 1234 (partnumber)
Variable Two = D (Driveletter)
Variable Three = Y (validate could be N to exclude)
Variable Four = Y (logfile could be N to exclude)
So what i need is a way to have the variable information inserted into the batch file and run the .exe file with the switches
EX:
start "" "U:\ISO\fileTool\file_Update.exe /m:12345 /t:m /v /l:logfile.txt"
As Squashman already noted in his comment, you don't need a file:
#echo off
set /p "VarOne=Enter Part Number: "
set /p "VarTwo=Enter Drive Letter: "
set /p "VarThree=Enter Validate? Y/N: "
if /i "%VarThree%"=="Y" (set "VarThree=/v") else (set "VarThree=")
set /p "VarFour=Use Log File? Y/N: "
if /i "%VarFour%"=="Y" (set "VarFour=/l:logfile.txt") else (set "VarFour=")
start "" "U:\ISO\fileTool\file_Update.exe" /m:%VarOne% /t:%VarTwo% %VarThree% %VarFour%
#ECHO OFF
SETLOCAL
CALL :run %*
:loop
SET "input="
SET /p "input=Part[,Drive[,Verify[,Logfile]]]"
IF DEFINED input CALL :run %input%&GOTO loop
GOTO :EOF
:run
FOR %%a IN (logfile verifyp) DO SET "%%a="
IF "%~4" neq "" SET "logfile=/l:%~4"
IF /i "%~3" equ "Y" SET "verifyp=/v"
IF /i "%~2" equ "" (SET "drive=D") ELSE (SET "drive=%~2")
ECHO(start "" "U:\ISO\fileTool\file_Update.exe /m:%~1 /t:%drive% %verifyp% %logfile%"
GOTO :EOF
This would allow you to run as thisbatch 1234 d y mylogfilename
or simply as thisbatch 1234
to default to drive D with no verify and no logfile.
I misread that you wanted y to specify logfile = logfile.txt
IF /i "%~4" equ "y" SET "logfile=/l:logfile.txt"
in plac of the "~4" processing in the run subroutine should convert that to "use logfile.txt if last parameter is y"

Resources