Usually we delete the recycle bin contents by right-clicking it with the mouse and selecting "Empty Recycle Bin". But I have a requirement where I need to delete the recycle bin contents using the command prompt. Is this possible? If so, how can I achieve it?
You can effectively "empty" the Recycle Bin from the command line by permanently deleting the Recycle Bin directory on the drive that contains the system files. (In most cases, this will be the C: drive, but you shouldn't hardcode that value because it won't always be true. Instead, use the %systemdrive% environment variable.)
The reason that this tactic works is because each drive has a hidden, protected folder with the name $Recycle.bin, which is where the Recycle Bin actually stores the deleted files and folders. When this directory is deleted, Windows automatically creates a new directory.
So, to remove the directory, use the rd command (r​emove d​irectory) with the /s parameter, which indicates that all of the files and directories within the specified directory should be removed as well:
rd /s %systemdrive%\$Recycle.bin
Do note that this action will permanently delete all files and folders currently in the Recycle Bin from all user accounts. Additionally, you will (obviously) have to run the command from an elevated command prompt in order to have sufficient privileges to perform this action.
I prefer recycle.exe from Frank P. Westlake. It provides a nice before and after status. (I've been using Frank's various utilities for well over ten years..)
C:\> recycle.exe /E /F
Recycle Bin: ALL
Recycle Bin C: 44 items, 42,613,970 bytes.
Recycle Bin D: 0 items, 0 bytes.
Total: 44 items, 42,613,970 bytes.
Emptying Recycle Bin: ALL
Recycle Bin C: 0 items, 0 bytes.
Recycle Bin D: 0 items, 0 bytes.
Total: 0 items, 0 bytes.
It also has many more uses and options (output listed is from /?).
Recycle all files and folders in C:\TEMP:
RECYCLE C:\TEMP\*
List all DOC files which were recycled from any directory on the C: drive:
RECYCLE /L C:\*.DOC
Restore all DOC files which were recycled from any directory on the C: drive:
RECYCLE /U C:\*.DOC
Restore C:\temp\junk.txt to C:\docs\resume.txt:
RECYCLE /U "C:\temp\junk.txt" "C:\docs\resume.txt"
Rename in place C:\etc\config.cfg to C:\archive\config.2007.cfg:
RECYCLE /R "C:\etc\config.cfg" "C:\archive\config.2007.cfg"
nircmd lets you do that by typing
nircmd.exe emptybin
http://www.nirsoft.net/utils/nircmd-x64.zip
http://www.nirsoft.net/utils/nircmd.html
You can use a powershell script (this works for users with folder redirection as well to not have their recycle bins take up server storage space)
$Shell = New-Object -ComObject Shell.Application
$RecBin = $Shell.Namespace(0xA)
$RecBin.Items() | %{Remove-Item $_.Path -Recurse -Confirm:$false}
The above script is taken from here.
If you have windows 10 and powershell 5 there is the Clear-RecycleBin commandlet.
To use Clear-RecycleBin inside PowerShell without confirmation, you can use Clear-RecycleBin -Force. Official documentation can be found here
I use this powershell oneliner:
gci C:\`$recycle.bin -force | remove-item -recurse -force
Works for different drives than C:, too
You can use this PowerShell command.
Clear-RecycleBin -Force
Note: If you want a confirmation prompt, remove the -Force flag
To stealthily remove everything, try :
rd /s /q %systemdrive%\$Recycle.bin
I know I'm a little late to the party, but I thought I might contribute my subjectively more graceful solution.
I was looking for a script that would empty the Recycle Bin with an API call, rather than crudely deleting all files and folders from the filesystem. Having failed in my attempts to RecycleBinObject.InvokeVerb("Empty Recycle &Bin") (which apparently only works in XP or older), I stumbled upon discussions of using a function embedded in shell32.dll called SHEmptyRecycleBin() from a compiled language. I thought, hey, I can do that in PowerShell and wrap it in a batch script hybrid.
Save this with a .bat extension and run it to empty your Recycle Bin. Run it with a /y switch to skip the confirmation.
<# : batch portion (begins PowerShell multi-line comment block)
:: empty.bat -- http://stackoverflow.com/a/41195176/1683264
#echo off & setlocal
if /i "%~1"=="/y" goto empty
choice /n /m "Are you sure you want to empty the Recycle Bin? [y/n] "
if not errorlevel 2 goto empty
goto :EOF
:empty
powershell -noprofile "iex (${%~f0} | out-string)" && (
echo Recycle Bin successfully emptied.
)
goto :EOF
: end batch / begin PowerShell chimera #>
Add-Type shell32 #'
[DllImport("shell32.dll")]
public static extern int SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath,
int dwFlags);
'# -Namespace System
$SHERB_NOCONFIRMATION = 0x1
$SHERB_NOPROGRESSUI = 0x2
$SHERB_NOSOUND = 0x4
$dwFlags = $SHERB_NOCONFIRMATION
$res = [shell32]::SHEmptyRecycleBin([IntPtr]::Zero, $null, $dwFlags)
if ($res) { "Error 0x{0:x8}: {1}" -f $res,`
(New-Object ComponentModel.Win32Exception($res)).Message }
exit $res
Here's a more complex version which first invokes SHQueryRecycleBin() to determine whether the bin is already empty prior to invoking SHEmptyRecycleBin(). For this one, I got rid of the choice confirmation and /y switch.
<# : batch portion (begins PowerShell multi-line comment block)
:: empty.bat -- http://stackoverflow.com/a/41195176/1683264
#echo off & setlocal
powershell -noprofile "iex (${%~f0} | out-string)"
goto :EOF
: end batch / begin PowerShell chimera #>
Add-Type #'
using System;
using System.Runtime.InteropServices;
namespace shell32 {
public struct SHQUERYRBINFO {
public Int32 cbSize; public UInt64 i64Size; public UInt64 i64NumItems;
};
public static class dll {
[DllImport("shell32.dll")]
public static extern int SHQueryRecycleBin(string pszRootPath,
out SHQUERYRBINFO pSHQueryRBInfo);
[DllImport("shell32.dll")]
public static extern int SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath,
int dwFlags);
}
}
'#
$rb = new-object shell32.SHQUERYRBINFO
# for Win 10 / PowerShell v5
try { $rb.cbSize = [Runtime.InteropServices.Marshal]::SizeOf($rb) }
# for Win 7 / PowerShell v2
catch { $rb.cbSize = [Runtime.InteropServices.Marshal]::SizeOf($rb.GetType()) }
[void][shell32.dll]::SHQueryRecycleBin($null, [ref]$rb)
"Current size of Recycle Bin: {0:N0} bytes" -f $rb.i64Size
"Recycle Bin contains {0:N0} item{1}." -f $rb.i64NumItems, ("s" * ($rb.i64NumItems -ne 1))
if (-not $rb.i64NumItems) { exit 0 }
$dwFlags = #{
"SHERB_NOCONFIRMATION" = 0x1
"SHERB_NOPROGRESSUI" = 0x2
"SHERB_NOSOUND" = 0x4
}
$flags = $dwFlags.SHERB_NOCONFIRMATION
$res = [shell32.dll]::SHEmptyRecycleBin([IntPtr]::Zero, $null, $flags)
if ($res) {
write-host -f yellow ("Error 0x{0:x8}: {1}" -f $res,`
(New-Object ComponentModel.Win32Exception($res)).Message)
} else {
write-host "Recycle Bin successfully emptied." -f green
}
exit $res
while
rd /s /q %systemdrive%\$RECYCLE.BIN
will delete the $RECYCLE.BIN folder from the system drive, which is usually c:,
one should consider deleting it from any other available partitions since there's an hidden $RECYCLE.BIN folder in any partition in local and external drives (but not in removable drives, like USB flash drive, which don't have a $RECYCLE.BIN folder).
For example, I installed a program in d:, in order to delete the files it moved to the Recycle Bin I should run:
rd /s /q d:\$RECYCLE.BIN
More information available at Super User at Empty recycling bin from command line
i use these commands in a batch file to empty recycle bin:
del /q /s %systemdrive%\$Recycle.bin\*
for /d %%x in (%systemdrive%\$Recycle.bin\*) do #rd /s /q "%%x"
Yes, you can Make a Batch file with the following code:
cd \Desktop
echo $Shell = New-Object -ComObject Shell.Application >>FILENAME.ps1
echo $RecBin = $Shell.Namespace(0xA) >>FILENAME.ps1
echo $RecBin.Items() ^| %%{Remove-Item $_.Path -Recurse -Confirm:$false} >>FILENAME.ps1
REM The actual lines being writen are right, exept for the last one, the actual thigs being writen are "$RecBin.Items() | %{Remove-Item $_.Path -Recurse -Confirm:$false}"
But since | and % screw things up, i had to make some changes.
Powershell.exe -executionpolicy remotesigned -File C:\Desktop\FILENAME.ps1
This basically creates a powershell script that empties the trash in the \Desktop directory, then runs it.
Create cmd file with line:
for %%p in (C D E F G H I J K L M N O P Q R S T U V W X Y Z) do if exist "%%p:\$Recycle.Bin" rundll32.exe advpack.dll,DelNodeRunDLL32 "%%p:\$Recycle.Bin"
I use EmptyRecycleBin.py python script
You will need to pip install winshell
#!python3
# Empty Windows Recycle Bin
import winshell
try:
winshell.recycle_bin().empty(confirm=False, show_progress=True, sound=False)
print("Recycle Bin emptied")
except:
print('Recycle Bin is already empty')
You can change the Boolean False and True statements to either turn on or off the following:
Confirm yes\no dialog, progress bar, sound effect.
If you don't use python, this one-liner for powershell is great.
I actually have it in EmptyRecycleBin.ps1, and use it in Git Bash.
Clear-RecycleBin -Force
All of the answers are way too complicated. OP requested a way to do this from CMD.
Here you go (from cmd file):
powershell.exe /c "$(New-Object -ComObject Shell.Application).NameSpace(0xA).Items() | %%{Remove-Item $_.Path -Recurse -Confirm:$false"
And yes, it will update in explorer.
Related
I can't delete Cygwin in my Windows 10 setup. I narrowed it down and the file that's causing trouble is
C:\cygwin\usr\share\avogadro\crystals\zeolites\CON.cif
In my case why the cywin directory (folder) cannot be deleted was due to "access privilege". To delete the folder, the user needs to "take ownership" of this folder. It cannot be done easily in Windows GUI. It is, however, fairly easy to achieve in a command prompt window using three command lines.
I followed the steps posted in this link. Remeber to be very sure what you are doing. Take note that the command prompt DOS window must be opened as "administrator". What this link says:
Open DOS Window "cmd.exe" as "administrator". Issue to the command prompt the following lines:
takeown /f "c:\cygwin" /r /d Y
The last parameter makes takeown assume "yes" to all questions and depends on locale. In the author's locale he/she had to answer "J" to make it work.
icacls "c:\cygwin" /T /Q /C /reset
Finally, to delete the files after we got the relevant permissions:
rd "c:\cygwin" /s /q
This method should work as intended in Windows 7 and above. I tried it in Windows7-x64 and Windows10-x64.
Running the following in command prompt as Administrator helped me:
C:\>del \\?\C:\cygwin64\usr\share\avogadro\crystals\zeolites
\\?\C:\cygwin64\usr\share\avogadro\crystals\zeolites\*, Are you sure (Y/N)? Y
I know this is a bit late but I like it:
If you have Linux subsystem installed (I have Ubuntu 18.04), you can remove that file via bash without any of the above. Just do,
Win+r -> bash -> cd /mnt/c/cygwin64/usr/share/avogadro/crystals/zeolites -> rm CON.cif.
Problem with cmd.exe and explorer.exe are that they are Windows' programs, whereas bash is not. In a way, this is the same as Lucian's answer because it makes the computer consider the file as a regular file.
Here it worked referring to PowerShell To Set Folder Permissions:
replace <User_with_administrator>
$mypath = ".\cygwin64--TO-BE-DELETED"
$myacl = Get-Acl $mypath
$myaclentry = "<User_with_administrator>","FullControl","Allow"
$myaccessrule = New-Object System.Security.AccessControl.FileSystemAccessRule($myaclentry)
$myacl.SetAccessRule($myaccessrule)
Get-ChildItem -Path "$mypath" -Recurse -Force | Set-Acl -AclObject $myacl -Verbose
Then the .\cygwin64--TO-BE-DELETED can be deleted.
So I've got this pretty basic powershell script to backup files to our network drive:
Function Backup {
param ($backupSource)
#Define backup location
$backupTarget = '\\192.168.0.247\Public'
#Make sure we're targeting a folder
If (!(Test-Path $backupSource -pathtype container)) {
[System.Windows.Forms.MessageBox]::Show("Target must be a folder" , "Error", 0)
Exit
}
#Make sure we have access to the backup location
DO {
$test = Test-Path $backupTarget
If (!$test) {
$loop = [System.Windows.Forms.MessageBox]::Show("Is the WiFi on? I can't reach the public drive. Maybe try again in a second." , "Internet Connection Unavailable" , 5)
If ($loop -eq 'Cancel') {
Exit
}
}
} WHILE (!$test)
Copy-Item $backupSource $backupTarget -recurse
}
I'm trying to get it to work in a right click menu, making it show up is no problem, and it executes, but I can't figure out how to successfully feed it the $backupSource parameter.
I'm working out of HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command with my default key. I've tried every combination of "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -File "C:\Windows\System32\Backup.ps1" "%1" I can think of. Can someone please help me out with the syntax here?
The script as provided doesn't work with command line arguments. i.e. calling the script as is doesn't work.
Try adding the call to the function passing the command line arguments.
At the end of your script add:
Backup $args[0]
I do it like this.
First I start cmd.exe from inside the registry. CMD window will appear briefly while it sends the powershell command.
Second I call powershell with the hidden switch so the rest of it runs invisibly.
Below is a working .reg file.
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command]
#="cmd /c start /b /wait powershell.exe -nologo -WindowStyle Hidden -file C:\\Windows\\System32\\Backup.ps1"
;
Here is a powershell snip to set the same bits in the registry.
If ( -Not ( Test-Path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command")){New-Item -Path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command" -ItemType RegistryKey -Force}
Set-ItemProperty -path "Registry::HKEY_CLASSES_ROOT\Directory\shell\NASBackup\command" -Name "(Default)" -Type "String" -Value "cmd /c start /b /wait powershell.exe -nologo -WindowStyle Hidden -file C:\Windows\System32\Backup.ps1"
#
I need to write a script .bat that give me the free space of a certain disk and the detail of all folders with the relative dimension and write it in a simple text file (just to check the distribution of used space).
Thanks a lot in advance!
dir /a /s | findstr /b /c:" " > file.txt
The FileSystemObject can do this for you. It is accessible from PowerShell (among other sources).
PowerShell -NoProfile -Command "$fso = New-Object -COMObject Scripting.FileSystemObject; Get-ChildItem YOUR_ROOT_DIRECTORY -Recurse -Directory | %% { $f = $fso.GetFolder($_.FullName); '{0},{1}' -f $f.Size,$_.FullName };"
::Stop Windows service
sc query MyWinService | find "STOPPED" & if errorlevel 1 net stop MyWinService
::delete the dll
del /q E:\MyWinService\\*
for /d %%x in (E:\MyWinService\\*) do #rd /s /q "%%x"
But some of the dlls not get deleted and the output comes as ----"ACCESS DENIED"---- if I re-run the same command after 5 minutes it executes. I know because the dll is still associated with the windows service so error is coming but I want to delete the dlls without re-running the command again after 5 min. :(
Batch file way
:Repeat
del "del /q E:\MyWinService\*"
if exist "E:\MyWinService\sampledll.dll" goto Repeat
Powershell way:
do
{
$a = stop-service MyWinService -PassThru
}while ($a.status -ne "Stopped")
do
{
remove-item e:\MyWinService\* -recurse -force -ea silentlycontinue
} untill ( (dir e:\mywinservice).count -gt 0 )
anyone know how to install font files (.ttf, .TTF, .otf, .OTF, etc etc) through the command prompt on windows?
as i understand it, it requires moving the text file to the correct folder and then also creating a registry value i think? but I havent been able to find one that is confirmed working.
a note: I am using windows 8 so that might make a difference.
another note: what I am trying to do is batch install fonts that I ripped from MKV files. (so this will be a function that is part of a larger .bat file, i can post the code if needed)
maybe this is needed too:
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "FontName (TrueType)" /t REG_SZ /d FontName.ttf /f
You'll need to use a PowerShell or VB script. They basically re-use the shell components that do the same thing in Windows Explorer, and they don't need a reboot.
See here for a PowerShell script that installs all fonts from a directory for Windows 8.1 or earlier:
https://social.technet.microsoft.com/Forums/fr-FR/winserverpowershell/thread/fcc98ba5-6ce4-466b-a927-bb2cc3851b59
Here is a similar script for Windows 10 (Windows Server 2019) that also updates the Windows Registry:
https://social.technet.microsoft.com/Forums/en-US/0c94dcf5-b89d-42e5-a499-06313f46f88b/can-no-longer-install-fonts-via-script-in-windows-10-1809?forum=win10itprogeneral
Also, you'll need to run the script in admin mode. So if the PowerShell script is InstallFonts.ps1, your batch file needs to look like:
powershell -command "Set-ExecutionPolicy Unrestricted" 2>> err.out
powershell .\InstallFonts.ps1 2>> err.out
Any powershell errors will appear in 'err.out' on the same folder as the script.
When you install a font all it does is copy the .ttf file to %systemroot%\fonts and add an entry in HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts. This can be automated with a batch file as follows
Rem fontinst.bat
copy akbar.ttf %systemroot%\fonts
regedit /s font.reg
The font.reg would contain the following:
REGEDIT4
\[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts\]
"Akbar Plain (TrueType)"="akbar.ttf"
Source: m.windowsitpro.com
So a colleague and I found a powershell solution that requires no admin rights, and does not show any prompts. You can use the name of the font-file to install and uninstall. This makes it especially useful for scripting.
Install:
# Install-Font.ps1
param($file)
$signature = #'
[DllImport("gdi32.dll")]
public static extern int AddFontResource(string lpszFilename);
'#
$type = Add-Type -MemberDefinition $signature `
-Name FontUtils -Namespace AddFontResource `
-Using System.Text -PassThru
$type::AddFontResource($file)
Uninstall:
# Uninstall-Font.ps1
param($file)
$signature = #'
[DllImport("gdi32.dll")]
public static extern bool RemoveFontResource(string lpszFilename);
'#
$type = Add-Type -MemberDefinition $signature `
-Name FontUtils -Namespace RemoveFontResource `
-Using System.Text -PassThru
$type::RemoveFontResource($file)
You can use them like this from cmd or powershell:
> powershell -executionpolicy bypass -File .\Install-Font.ps1 .\myfonts\playfair-display-v22-latin-regular.ttf
> powershell -executionpolicy bypass -File .\Uninstall-Font.ps1 .\myfonts\playfair-display-v22-latin-regular.ttf
The solution is based on https://www.leeholmes.com/powershell-pinvoke-walkthrough/ and uses native Win32 functions (gdi32.dll). https://learn.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-addfontresourcew
Have you tried copying them to the font's folder?
copy font.ttf %windir%\Fonts
I solved the task in this way:
suppose you have to install many fonts in subfolders with the following structure recursively:
\root_folder
Install_fonts.cmd
\font_folder_1
font_1.ttf
font_2.otf
\font_folder_2
font_3.ttf
font_4.otf
\font_folder_3
font_5.ttf
font_6.otf
To do that, I downloaded the FontReg.exe tool on my Desktop (change the path in the Install_fonts.cmd file if it is located somewhere else) and I used it in a Install_fonts.cmd batch script like the following, located in root_folder (change also its name in the Install_fonts.cmd file, if different):
#echo off
set back=%cd%
for /d %%i in (%USERPROFILE%\Desktop\root_folder\*) do (
cd "%%i"
echo current directory:
cd
start /wait %USERPROFILE%\Desktop\fontreg-2.1.3-redist\bin.x86-64\FontReg.exe /move
timeout /t 1 /nobreak >nul
)
cd %back%
echo Process completed!
pause
So, you have to run Install_fonts.cmd into root_folder as administrator, to automate the fonts installation process.
Cheers
if you are a python fan, following script does the job. This script generates a vbscript for font installation. Searches all the sub-folders for ttf fonts and installs it. You don't need to move any font files.
import os
import subprocess
import time
# vb script template
_TEMPL = """
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace("%s")
Set objFolderItem = objFolder.ParseName("%s")
objFolderItem.InvokeVerb("Install")
"""
vbspath = os.path.join(os.getcwd(), 'fontinst.vbs')
for directory, dirnames, filenames in os.walk(os.getcwd()):
for filename in filenames:
fpath = os.path.join(directory, filename)
if fpath[-4:] == ".ttf": # modify this line for including multiple extension
with open(vbspath, 'w') as _f:
_f.write(_TEMPL%(directory, filename))
subprocess.call(['cscript.exe', vbspath])
time.sleep(3) # can omit this
os.remove(vbspath) # clean
Run this python script on the root folder
Batch file sample. It works in the current directory.
IF "%*" NEQ "" SET FONT=%* (
FOR /F %%i in ('dir /b "%FONT%*.*tf"') DO CALL :DEST %%i
) else (
EXIT
)
:DEST
SET FONTFILE=%~n1%~x1
SET FONTNAME=%~n1
IF "%~x1"==".ttf" SET FONTTYPE=TrueType
IF "%~x1"==".otf" SET FONTTYPE=OpenType
ECHO FILE = %FONTFILE%
ECHO NAME = %FONTNAME:-= %
ECHO TYPE = %FONTTYPE%
fontview %~dp0%FONTFILE%
GOTO :EXIT