CMD/Batch help with Var Expansion.


  1. Posts : 3
    Windows 7 Ultimate x64
       #1

    CMD/Batch help with Var Expansion.


    I have a little problem of a batch,
    Justa sootch, for some hooch, will you help a Paisano?
    parameter's im slighting, variables im fighting! me!

    HelpMeYo, HelpMeYo,
    HelpMeYo, HelpMeYo,
    HelpMe~ YouGotaHelpaBro!


    So I've got some problems getting Batch, to allow me to parameter substitution on my own vars.
    It normally works with command line parameters. which are given the var names 0 1 2 3 4 and so on at the start of a batch environment.
    so something like "C:/Freddy Mercury/Bohemian/Rhapsody.exe" "C:/reload/rob zombie.ogg" "N:/ever/gona/give/u.up" "I:/love/ewe/u/love.me"
    would result in the environment of the running batch having the vars 0 1 2 3 being the 4 above quoted elements.
    Then you can use parameter expansion/substitution on them, to get just the path or file name or extension.
    so for example with the above parameters passed...

    echo %%~n3
    echo %%~x3
    echo %%~x2
    echo %%~n2

    would result in

    love
    me
    up
    rob zombie

    eew... but anyway, i want to insert my own vars through this process inside the running batch file.
    somehow that sounds more seedy now then its meant to be... but moving on..

    here is my code.. which does not work.

    Code:
    @echo Off
    echo %~nx0 running.
    set uhray[0]=A:\BatchPlayground\NoFile.exe
    set uhray[1]=B:\CmdBrainStorming\NonExistantFile.doh
    set uhray[2]=C:\SomeOtherPlace\FictionalFile.lalala
    SETLOCAL ENABLEDELAYEDEXPANSION
    set z=0
    :SymLoop
    if defined uhray[%z%] (
        echo uhray[%z%]= !uhray[%z%]!
        echo %%~x!uhray[%z%]!
        set /a "z+=1"
        GOTO :SymLoop
    )
    set z=
    ENDLOCAL
    
    REM .
    REM .
    REM .
    REM  everything below here causes a substitution invalid error in the script even when its in a REMARK. @,@?
    REM    echo %%~x!uhray[%z%]!
    REM    set q=%uhray[!z!]%...
    REM    call echo %%~xq
    REM    echo %%~x!uhray[%z%]!
    REM    call echo %~x!uhray[%z%]!
    REM    call echo %%~x!uhray[%z%]!
    REM    set Q=!uhray[%z%]!
    REM    echo %%~x%Q%
    Output:
    Code:
    C:\BatchPlayground>C:\BatchPlayground\Substitutetutelage2.bat
    Substitutetutelage2.bat running.
    uhray[0]= A:\BatchPlayground\NoFile.exe
    %~xA:\BatchPlayground\NoFile.exe
    uhray[1]= B:\CmdBrainStorming\NonExistantFile.doh
    %~xB:\CmdBrainStorming\NonExistantFile.doh
    uhray[2]= C:\SomeOtherPlace\FictionalFile.lalala
    %~xC:\SomeOtherPlace\FictionalFile.lalala
    The following usage of the path operator in batch-parameter
    substitution is invalid: %~x!uhray[%z%]!
    
    
    For valid formats type CALL /? or FOR /?
    The syntax of the command is incorrect.
    
    C:\BatchPlayground>

    Expected Output:
    Code:
    C:\BatchPlayground>C:\BatchPlayground\Substitutetutelage2.bat
    Substitutetutelage2.bat running.
    uhray[0]= A:\BatchPlayground\NoFile.exe
    exe
    uhray[1]= B:\CmdBrainStorming\NonExistantFile.doh
    doh
    uhray[2]= C:\SomeOtherPlace\FictionalFile.lalala
    lalala
    
    C:\BatchPlayground>
    I've posted this problem over on "stack overflow" too. but immediately got downvoted into oblivion for not knowing batch code.
    i mean.. that is kinda the point, if your asking for help, your admitting you need help learning it better. Maybe its just troll'y over there.

    TLDR: trying to get var.expansion/substitution operational with array Vars, and not just the typical %1 %2 %3 it seems to be restricted to.
    The definitions for things like %~n and %~nx and %%~p are inside the FOR /? help sheet oddly enough. Though they can clearly be used without a CALL or FOR itself.

    Please assist?
      My Computer


  2. Posts : 17,001
    Windows 10 Home x64 Version 22H2 Build 19045.4170
       #2

    Do yourself a favour and delete the line
    @echo Off
    so you can see the responses to each command and hence have half a chance of working out what is happening.


    Your question seems like it might be about the topic of Delayed expansion of variables.
    my ditty - useful Delayed expansion sources - TenForums
    Delayed expansion and arrays - TenForums
    but you've chucked in so much else that I'm not at all sure.
    Your specific example of use within an If statement is addressed in Variables in batch file not being set when inside IF - Super User
    Delayed expansion is, in my opinion, quite an advanced topic and best avoided for now.
    I always avoid Delayed expansion but others find it useful.


    If you want to learn about arrays then you might like
    Batch Script Arrays - TutorialsPoint


    I wrote some general scripting advice in
    my ditty Batch file and PowerShell guides [post #7] - ElevenForum


    Best of luck,
    Denis



    Welcome to TenForums.

    It's really worth making time to browse through the Tutorial index - there's a shortcut to it at the top of every page.
    - At the foot of the Tutorial index is a shortcut to download it as a spreadsheet.
    - I download a new copy each month.
    - By downloading it as a spreadsheet I can benefit from Excel's excellent filtering capabilities when I search for topics of interest.
    - Tutorials are also listed by category at Tutorials - there's also a shortcut to that at the top of every page.
    - Both tutorial lists are searchable.
    - You can also search for TenForumsTutorials in many general search engines, such as Google, by adding site:tenforums.com/tutorials after your search term. For example,
    taskbar toolbars site:tenforums.com/tutorials

    You can search TenForums using the search box in the top-right corner of all TenForums webpages or using Advanced Search - TenForums
    - You can also search TenForums threads in many general search engines, such as Google, by adding site:tenforums.com after your search term. For example,
    Search for drivers by HardwareID site:tenforums.com
    - [This is what the search box in the top-right corner of TenForums webpages does automatically]
    Last edited by Try3; 05 Jun 2023 at 01:58.
      My Computer


  3. Posts : 3
    Windows 7 Ultimate x64
    Thread Starter
       #3

    I suppose the script was too advanced to be understood that way. Ill cut out all but 2 of the working lines, to focus on that which isn't.

    Code:
    echo %~nx0 running.
    set uhray[0]=B:\CmdBrainStorming\NonExistantFile.doh
    echo %~x%uhray[0]%
    Output:
    Code:
    C:\BatchPlayground>C:\BatchPlayground\Substitutetutelage3.bat
    
    C:\BatchPlayground>echo Substitutetutelage3.bat running.
    Substitutetutelage3.bat running.
    
    C:\BatchPlayground>set uhray[0]=B:\CmdBrainStorming\NonExistantFile.doh
    The following usage of the path operator in batch-parameter
    substitution is invalid: %~x%uhray[0]%
    
    
    For valid formats type CALL /? or FOR /?
    
    C:\BatchPlayground>echo %~x%uhray[0]%
    
    C:\BatchPlayground>

    Expected output:
    Code:
    C:\BatchPlayground>C:\BatchPlayground\Substitutetutelage3.bat
    
    C:\BatchPlayground>echo Substitutetutelage3.bat running.
    Substitutetutelage3.bat running.
    
    C:\BatchPlayground>set uhray[0]=B:\CmdBrainStorming\NonExistantFile.doh
    
    C:\BatchPlayground>echo %~x%uhray[0]%
    doh
    
    C:\BatchPlayground>
    maybe this output vs expected output will make it more clear.
    again, the problem is related to doing expansion substitution tasks such as %~n and %~nx or %~p on variables that are 'not' labeled %1 %2 %3 and so on.


    The same problem exists even if i don't use an array for the var.
    Code:
    echo %~nx0 running.
    set I=B:\CmdBrainStorming\NonExistantFile.doh
    echo %~xI
    Output:
    Code:
    C:\BatchPlayground>C:\BatchPlayground\Substitutetutelage3.bat
    
    C:\BatchPlayground>echo Substitutetutelage3.bat running.
    Substitutetutelage3.bat running.
    
    C:\BatchPlayground>set I=B:\CmdBrainStorming\NonExistantFile.doh
    The following usage of the path operator in batch-parameter
    substitution is invalid: %~xI
    
    
    For valid formats type CALL /? or FOR /?
    
    C:\BatchPlayground>echo %~xI
    
    C:\BatchPlayground>
    Expected Output:
    Code:
    C:\BatchPlayground>C:\BatchPlayground\Substitutetutelage3.bat
    
    C:\BatchPlayground>echo Substitutetutelage3.bat running.
    Substitutetutelage3.bat running.
    
    C:\BatchPlayground>set I=B:\CmdBrainStorming\NonExistantFile.doh
    
    C:\BatchPlayground>echo %~xI
    doh
    
    C:\BatchPlayground>
    I hope these 2 examples help further illustrate what i am trying to do. im running out of lines to cut away to make it easier to understand for others.
      My Computer


  4. Posts : 17,001
    Windows 10 Home x64 Version 22H2 Build 19045.4170
       #4

    You can only use such syntax as your
    echo %~xI
    with variables that have been passed to the code. You cannot just use it for variables that you have defined in the code.
    See the examples in my ditty and demo for Standard passable variables [post #47] - TenForums [which is already listed in one of the links given in my first reply]

    In your code, the script does not know that B:\CmdBrainStorming\NonExistantFile.doh is supposed to be a file object. All it sees is that I has been set to a string value.
    To trick your code into letting you treat your variable the way you want to, you can use For commands [as das10 has illustrated above] or subroutines [as illustrated in Extract variable elements without For - SS64Forum]


    Denis
      My Computer


  5. Posts : 818
    Windows 7
       #5

    Use nested for's to expand the "array" references, and use %1 to allow ~x to work.
    Code:
    @echo Off
    echo %~nx0 running.
    
    set uhray[0]=A:\BatchPlayground\NoFile.exe
    set uhray[1]=B:\CmdBrainStorming\NonExistantFile.doh
    set uhray[2]=C:\SomeOtherPlace\FictionalFile.lalala
    
    setlocal enabledelayedexpansion
    
    set z=0
    :SymLoop
    if defined uhray[%z%] (
        for %%s in (uhray[%z%]) do (
            for %%1 in (!%%s!) do (
                echo %%s = !%%s! %%~x1
            )
        )
        set /a "z+=1"
        GOTO :SymLoop
    )
    set z=
    
    endlocal
    Code:
    Thumpie.bat running.
    uhray[0] = A:\BatchPlayground\NoFile.exe .exe
    uhray[1] = B:\CmdBrainStorming\NonExistantFile.doh .doh
    uhray[2] = C:\SomeOtherPlace\FictionalFile.lalala .lalala
      My Computer


  6. Posts : 3
    Windows 7 Ultimate x64
    Thread Starter
       #6

    Das10 you nailed it thank you.
    You made it easier to understand, offered the simple example,
    and thanks to that I've got it working with an array!

    Code:
    @echo Off
    echo %~nx0 running.
    set uhray[0]=A:\BatchPlayground\NoFile.exe
    set uhray[1]=B:\CmdBrainStorming\NonExistantFile.doh
    set uhray[2]=C:\SomeOtherPlace\FictionalFile.lalala
    set uhray[3]=D:\ont\you\wish\this\was.over
    set uhray[4]=E:\urika\das10\helped\me\get.it
    SETLOCAL ENABLEDELAYEDEXPANSION 
    set z=0
    :SymLoop
    if defined uhray[%z%] (
    For %%a in (!uhray[%z%]!) do (
            echo %%~xa
            )
        set /a "z+=1"
        GOTO :SymLoop
    )
    set z=
    ENDLOCAL
    Output:
    Code:
    C:\BatchPlayground>C:\BatchPlayground\Substitutetutelage4.bat
    Substitutetutelage4.bat running.
    .exe
    .doh
    .lalala
    .over
    .it
    
    C:\BatchPlayground>
    Working!

    - - - Updated - - -

    for some reason das10 removed his post.
    he was the first to show me an operational example i could learn directly from.
    Thank you garlin. you also provided a more complicated solution with more examples there in.


    I have since expanded on this experimentation to put it into the intended use i have for it which ill share.

    I tend to have the occasional gpu or sound-card failure when gaming. perhaps its ram or heat or some physics error over on the cpu. but in these cases i can barely access anything beyond the task manager to begin a task.

    In-light of this i have turned to a few batch files to kill the process associated with the lockup, which usually fixes things.

    However its happened with enough Unity games, that its become advantageous to have a simple copy-paste'able script, where in i enter all the games running executables.

    Not every game obeys gracefully a task kill, so I've created a few forceful methods. Some games have multiple executables associated with them.

    so, with everyone help here, I've made this:

    Code:
    @echo Off
    echo %~nx0 running.
    set uhray[0]=C:\Games\utilities\Steam\steamapps\common\Grounded\Grounded.exe
    set uhray[1]=C:\Games\utilities\Steam\steamapps\common\Grounded\Maine\Binaries\Win64\Maine-Win64-Shipping.exe
    SETLOCAL ENABLEDELAYEDEXPANSION
    set debug=true
    set z=0
    :SymLoop
    	if defined uhray[%z%] (
    	For %%a in (!uhray[%z%]!) do (
    	    if %debug% equ true echo operating on uhray[%z%] containing: %%a
    rem		echo full path name and extension  %%a
    rem		echo %%~pa
    rem		echo %%~na
    rem		echo %%~xa
    rem		echo name and extension: %%~nx
    
    		if %debug% equ true echo  @Taskkill
    		Taskkill /T /F /IM "%%~nxa" > nul
    		Taskkill /T /F /IM "%%a" > nul
    		Taskkill /T /F /IM "%%~pa" > nul
    		if %debug% equ true echo @wmic
    rem		wmic process where "name='%%a'" delete > nul     Error: description = invalid query
    		wmic process where "name='%%~nxa'" delete > nul
    		if %debug% equ true echo  @Task_List-Find-Kill
    		set "$process=%%~nxa*"
    		for %%b in (%$process%) do tasklist >nul | find "%%b" && taskkill /F /IM %%b /T > nul
    		if %debug% equ true echo @Killed
    		echo.	
    		echo %%~na should be closed now.
    		echo.
    		echo.
    		echo.
    		echo.
    		)
    	
        set /a "z+=1"
        GOTO :SymLoop
    )
    set z=
    set "$process="
    ENDLOCAL
    echo %~nx0 closing in 10 seconds.
    Timeout /T 10 >NUL
    Output:
    [As Expected]

    I could have used a shortcut link to pass vars to the batch environment under %1 %2 %3 %4
    but for -me- that method is actually more difficult to look into with links that point to 1 batch.
    Id never used non-environment variable expansion substitution before. nor array based.
    I've used FOR often enough.
    But im always a little rusty when i try to mess with the complexity and power of Batch FOR functions.
    For in other languages tends to be a bit simple by comparison.

    I really wanted to accomplish this task with arrays rather then command line parameters this time.
    Thank you all for putting in the effort to address my question.

    [SOLVED]
      My Computer


 

  Related Discussions
Our Sites
Site Links
About Us
Windows 10 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 10" and related materials are trademarks of Microsoft Corp.

Designer Media Ltd
All times are GMT -5. The time now is 18:53.
Find Us




Windows 10 Forums