The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,862 other subscribers

Archive for the ‘Batch-Files’ Category

Small batch file to recursively compact a directory using NTFS compression

Posted by jpluimers on 2021/04/07

compact-directory-recursively.bat:

if [%1]==[] goto :eof
call compact /s /c %1 %1\*.*

Example usage:

compact-directory-recursively.bat C:\ProgramData\{51D553F1-B483-41C2-B35E-6D461D9E0F9C}

compact-directory-recursively.bat "C:\ProgramData\Package Cache"

@for /d %d in (*.*) do @call compact-directory-recursively.bat "%d"

The @ signs are to get less output clutter.

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »

Mixed JScript/batch file hybrid to create Windows shortcuts

Posted by jpluimers on 2021/03/25

I bumped into this amazing JScript/batch file hybrid. It starts as a batch file, then continues as a JScript script, and creates/updates .lnk files: [WayBack] batch.scripts/shortcutJS.bat at master · npocmaka/batch.scripts · GitHub.

Wow. Just wow.

Not that I would want to be the one maintaining it (:

Via [WayBack] batch file – How do I create a shortcut via command-line in Windows? – Stack Overflow of which I like these answers most:

  • Check the shortcutJS.bat – it is a jscript/bat hybrid and should be used with .bat extension:

    call shortcutJS.bat -linkfile "%~n0.lnk" -target  "%~f0" -linkarguments "some arguments"
    

    With -help you can check the other options (you can set icon , admin permissions and etc.)

  • Nirsoft’s NirCMD can create shortcuts from a command line, too. (Along with a pile of other functions.) Free and available here:

    http://www.nirsoft.net/utils/nircmd.html

    Full instructions here: http://www.nirsoft.net/utils/nircmd2.html#using (Scroll down to the “shortcut” section.)

    Yes, using nircmd does mean you are using another 3rd-party .exe, but it can do some functions not in (most of) the above solutions (e.g., pick a icon # in a dll with multiple icons, assign a hot-key, and set the shortcut target to be minimized or maximized).

    Though it appears that the shortcutjs.bat solution above can do most of that, too, but you’ll need to dig more to find how to properly assign those settings. Nircmd is probably simpler.

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »

reg query and batch file for loop tricks that refreshes the cmd environment from the registry settings: choco/RefreshEnv.cmd at master · chocolatey/choco · GitHub

Posted by jpluimers on 2021/03/04

I bumped into a very interesting [WayBack] choco/RefreshEnv.cmd at master · chocolatey/choco · GitHub.

It allows you to refresh your cmd environment from new settings that were only applied to the registry using the SET command.

Note there is a PowerShell counterpart too: [WayBack] choco/Update-SessionEnvironment.ps1 at master · chocolatey/choco · GitHub

There are many cool tricks in it, most of which you can see in the [WayBack] new commit history, and a few you can find back in the [WayBack] old commit history of the previous repository (I have no idea why those histories have never been merged).

Intermediate batch files

The basic structure is to first create some intermediate batch files, then delete them afterwards:

  • "%TEMP%\_envget.tmp"
    • is used in :GetRegEnv to get all environment variables for the MACHINE or USER level, then loop through them and call :SetFromReg during each iteration (except for the Path environment variable which is skipped).
  • "%TEMP%\_envset.tmp"
    • is used in :SetFromReg to emit one line of SET code to "%TEMP%\_env.cmd".
  • "%TEMP%\_env.cmd"
    • Contains the SET commands for the new environment variable values.

All the above methods use quoting to ensure that environment variables having names or values containing spaces are handled correctly.

Echo without newline

I like the echo | set /p trick to echo a string without a newline allows it to start as this:

C:\>RefreshEnv
Refreshing environment variables from registry for cmd.exe. Please wait...

then finish like this by appending another string to it:

C:\>RefreshEnv
Refreshing environment variables from registry for cmd.exe. Please wait...Finished..

It is explained in the old history at [WayBack] (GH-153)(GH-134) Update PATH on cmd.exe · chocolatey/chocolatey@a09e158 · GitHub.

There is an even more interesting example of this trick in [WayBack] windows – What does /p mean in set /p? – Stack Overflow:

<nul set /p=This will not generate a new line

Spaces, what spaces

One hard thing in scripting is taking into account that path names can contain spaces. This means you need to carefully quote path names, but not overdo the quotes, otherwise the quoting works against you.

Two commits from the commit history show there were two weak spots that had to be changed in [WayBack] (GH-1227) Fix: RefreshEnv doesn’t set path w/spaces · chocolatey/choco@fdfcd06 · GitHub.

The environment has a MACHINE and USER part

Environment variables can come from two places in the registry:

  • HKLM\System\CurrentControlSet\Control\Session Manager\Environment
  • HKCU\Environment

Normally, the second overrides the first.

This means they are grabbed from the registry MACHINE and USER order, then applied to the cmd environment.

Special case PATH

The PATH environment variable is special for two reasons:

  1. In the registry it is called Path, but in the environment it is usually called PATH (this is true for both the MACHINE and USER parts of the registry). New values are applied with the Path environment variable name, so after executing RefreshEnv once, they are called Path in the cmd.exe environment too.
  2. PATH is a combination from two PATH entries in the registry in the MACHINE and USER level, so it needs to be combined as you can see in [WayBack] choco/RefreshEnv.cmd at master · chocolatey/choco · GitHub.:
    :: Caution: do not insert space-chars before >> redirection sign
    echo/set "Path=%%Path_HKLM%%;%%Path_HKCU%%" >> "%TEMP%\_env.cmd"

I am not sure why there is a space before the >>, given there is a comment above it there should not be one.

The SET command however, puts the MACHINE PATH in front of the USER PATH.

Special case USERNAME, and collateral PROCESSOR_ARCHITECTURE

The USERNAME environment variable special too. In the registry, it is only in the MACHINE part, but with a value SYSTEM.

In cmd.exe, it is actually filled with the current username, so it should not be overwritten with the one in the MACHINE part.

Currently this is resolved by storing a copy of the old value of USERNAME and PROCESSOR_ARCHITECTURE in [WayBack] (GH-902) Fix: User changed to SYSTEM during env update · chocolatey/choco@cb6b92c · GitHub.

I am not sure why PROCESSOR_ARCHITECTURE is also stores.

In any case, this means that setting a USERNAME or PROCESSOR_ARCHITECTURE in the USER part of the registry, will not be reflected by RefreshEnv.

I am not sure yet when that can cause problems, so this is a reminder to myself that if ever it does, then this logic needs to be changed.

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »

Batch files: deleting first/middle/ending parts of environment variables

Posted by jpluimers on 2021/01/06

Batch files are often a pain to write, but you cannot always rewrite them in PowerShell.

The pain below is about deleting parts of environment variables in batch files.

I’ll just redirect to and quote from posts that can way better describe this than I do:

  • [WayBack] Check if Batch variable starts with “…” – Stack Overflow made me find
  • [WayBack] windows – Batch – Delete Characters in a String – Super User
  • [WayBack] CMD Variable edit replace – Windows CMD – SS64.com

    The variable _test containing 12345abcabc is used for all the following examples:

    ::Replace '12345' with 'Hello '
       SET _test=12345abcabc
       SET _result=%_test:12345=Hello %
       ECHO %_result%          =Hello abcabc
    
    ::Replace the character string 'ab' with 'xy'
       SET _test=12345abcabc
       SET _result=%_test:ab=xy%
       ECHO %_result%          =12345xycxyc
    
    ::Delete the character string 'ab'
       SET _test=12345abcabc
       SET _result=%_test:ab=%
       ECHO %_result%          =12345cc
    
    ::Delete the character string 'ab' and everything before it
       SET _test=12345abcabc
       SET _result=%_test:*ab=% 
       ECHO %_result%          =cabc
    
    ::Replace the character string 'ab' and everything before it with 'XY'
       SET _test=12345abcabc
       SET _result=%_test:*ab=XY% 
       ECHO %_result%          =XYcabc
    
    
    :: To remove characters from the right hand side of a string is 
    :: a two step process and requires the use of a CALL statement
    :: e.g.
    
       SET _test=The quick brown fox jumps over the lazy dog
    
       :: To delete everything after the string 'brown'  
       :: first delete 'brown' and everything before it
       SET _endbit=%_test:*brown=%
       Echo We dont want: [%_endbit%]
    
       ::Now remove this from the original string
       CALL SET _result=%%_test:%_endbit%=%%
       echo %_result%

    All the examples on this page assume the default Expansion of variables, if you are using DelayedExpansion then you can choose to change the variable references to !_variable! instead of %_variable%

    One advantage of DelayedExpansion is that it will allow you to replace the % character, it will still have to be escaped as %% but the replace action will then treat it like any other character:

    Replace the letter P with a percent symbol:
    Setlocal EnableDelayedExpansion
    _demo=somePdemoPtextP
    _demo=!_demo:P=%%!

    Remove spaces from a text string

    To delete space characters use the same syntax as above:

    SET _no_spaces=%_some_var: =%

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »

Batch file: check for (non-)existence of registry key

Posted by jpluimers on 2021/01/05

Small batch file that only deletes a registry key if it exists:

:DeleteKeyIfItExists
reg query %1 >nul 2>&1
if %errorlevel% equ 0 reg delete %1 /f
goto :eof

It is based on:

  • redirecting both stderr and stdout to nul (the >nul 2>&1 bit)
  • checking reg query with the appropriate errorlevel value for equality (equ operator) for 0 (existence); you can also use 1 for non-existence.

Based on:

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »

Windows command prompt: decrementing loop

Posted by jpluimers on 2020/12/30

I needed a decrementing loop on the Windows command prompt, but that seems very hard from batch files without programming your own kind of while loop:

PowerShell to the rescue to loop back from and including 463 down to and including 290:

PowerShell -Command "for ($i=463; $i -ge 290; $i--) { Write-Host "Value " $i}"

This outputs:

Value 463
Value 462
...
Value 291
Value 290

In a similar way, you can execute a cmd command, but then you need to be careful on how to pass parameters: the \" is important to you can have quotes within quoted strings..

PowerShell -Command "for ($i=463; $i -ge 290; $i--) { & echo \"Value $i\"}"

gives this:

Value 463
Value 462
...
Value 291
Value 290

Read the rest of this entry »

Posted in Batch-Files, CommandLine, Console (command prompt window), Development, PowerShell, PowerShell, Scripting, Software Development, Windows | 1 Comment »

On Windows 7 and 8.x too: Completely disable Windows 10 telemetry collection – twm’s blog

Posted by jpluimers on 2020/12/10

From [WayBack] Completely disable Windows 10 telemetry collection – twm’s blog:

So I don’t forget: According to an article in c’t magazine, disabling the “DiagTrack” service (“Connected User Experience and Telemetry”) will completely disable user tracking in Windows 10. They also say that they did not see any negative effects.

Source: [WayBack] Telefonierverbot in c’t 01/2019 page 172 (in German)

I saw at least one system where the service is not shown when you run Services.msc: it did not list DiagTrack, nor Connected User Experience and Telemetry. How awful is that!

The service can also be installed non older Windows versions: [WayBack] Just found DiagTrack running in Services – Tips and Tricks

Sometimes, it gets re-enabled. I think this happens during major Windows updates.

To inspect, stop and disable

Run all commands from the console the below bold commands. The non-bold text was the output on my system. If instead of the cmd.exe console, you run a PowerShell console, then remove the bits PowerShell -Command " and " at the start and end of each command.

The first command does not require an Administrative (UAC Elevated) command prompt; the last one does.

However, the first command, needs the | Select-Object * bit as otherwise most of the fields will not be displayed, excluding for instance StartType.

powershell -Command "Get-Service -Name DiagTrack | Select-Object *"


Name                : DiagTrack
RequiredServices    : {RpcSs}
CanPauseAndContinue : False
CanShutdown         : True
CanStop             : True
DisplayName         : Connected User Experiences and Telemetry
DependentServices   : {}
MachineName         : .
ServiceName         : DiagTrack
ServicesDependedOn  : {RpcSs}
ServiceHandle       :
Status              : Running
ServiceType         : Win32OwnProcess
StartType           : Automatic
Site                :
Container           :

On an Administrative command-prompt:

powershell -Command "Set-Service -Name DiagTrack -StartUpType Disabled"
powershell -Command "Get-Service -Name DiagTrack | Stop-Service"

Two notes:

Read the rest of this entry »

Posted in Batch-Files, CommandLine, Development, Power User, PowerShell, PowerShell, Scripting, Software Development, Windows | Leave a Comment »

`exit /b #`: set `errorlevel` to `#`, then exit batch file or subroutine – via: Errorlevel – Windows CMD – SS64.com

Posted by jpluimers on 2020/11/25

I seem to always forget how to set an error leve in side a batch file, but [WayBack] Errorlevel – Windows CMD – SS64.com tells how:

  • When ending a [WayBacksubroutine, you can use EXIT /b N to set a specific ERRORLEVEL N.
  • You can make a [WayBackbatch file return a non-zero exit code by using the [WayBackEXIT command.

    Exit 0
    Exit /B 5

    To force an ERRORLEVEL of 1 to be set without exiting, run a small but invalid command like [WayBack]COLOR 00 

    There is a key difference between the way .CMD and .BAT batch files set errorlevels:

    An old .BAT batch script running the ‘new’ internal commands: APPEND, ASSOC, PATH, PROMPT, FTYPE and SET will only set ERRORLEVEL if an error occurs. So if you have two commands in the batch script and the first fails, the ERRORLEVEL will remain set even after the second command succeeds.

    This can make debugging a problem BAT script more difficult, a CMD batch script is more consistent and will set ERRORLEVEL after every command that you run [[archive.is]source].

It looks like I already used a bare EXIT /B without explaining it in Source: stop/start IIS.

Further reading, including the difference between subroutines, blocks and batch files:

Finally saving Google Groups messages in the way back machine:

  1. Convert the URL
  2. Save the latter in archive.is

–jeroen

Posted in Batch-Files, Development, Software Development | Leave a Comment »

windows – Batch-file: undocumented wild card characters to check for file pattern existence – Stack Overflow

Posted by jpluimers on 2020/08/19

I wish I had known these undocumented wildcards exists like two decades ago: [WayBackwindows – Batch-file: Check if file with pattern exist – Stack Overflow, thanks Squashman:

There are undocumented wildcards that you can use to achieve this as well.

IF EXIST "D:\*Backup*.<" (
   ECHO "file exist"
) ELSE (
   ECHO "file not exist"
)

This wildcard option and other were discussed in length at the following two links.

From those links:

The following wildcard characters can be used in the pattern string.

Wildcard character  Meaning

* (asterisk)
Matches zero or more characters

? (question mark)
Matches a single character

" 
Matches either a period or zero characters beyond the name string

>
Matches any single character or, upon encountering a period or end of name string, advances the expression to the end of the set of contiguous >

<
Matches zero or more characters until encountering and matching the final . in the name

–jeroen

Posted in Batch-Files, Development, Scripting, Software Development | Leave a Comment »

How to pin either a Shortcut or a Batch file to the new Windows 7, 8 and 10 Taskbar and start menu? – Super User

Posted by jpluimers on 2020/04/29

This nailed it: way easier than all the alternatives involving VB scripts, registry keys and Group Policy Editors.

  1. Create a shortcut to your batch file.
  2. Get into shortcut property and change target to something like: cmd.exe /C "path-to-your-batch".
  3. Simply drag your new shortcut to the taskbar

Source: [WayBackHow to pin either a Shortcut or a Batch file to the new Windows 7, 8 and 10 Taskbar and start menu? – Super User

The trick is step 2. After that you can modify back your shortcut to just the batch file.

–jeroen

Posted in Batch-Files, Development, Power User, Scripting, Software Development, Windows, Windows 7 | Leave a Comment »