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 2,319 other followers

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 »

 
<span>%d</span> bloggers like this: