• Announcements

    • xper

      MSFN Sponsorship and AdBlockers!   07/10/2016

      Dear members, MSFN is made available via subscriptions, donations and advertising revenue. The use of ad-blocking software hurts the site. Please disable ad-blocking software or set an exception for MSFN. Alternatively, become a site sponsor and ads will be disabled automatically and by subscribing you get other sponsor benefits.
Sign in to follow this  
Followers 0
Geej

Read ini file using batch

21 posts in this topic

I'm trying to test a cmd script that read a simple ini file. The ini file stores a folder path. However if folder path has space, it can't work properly.

folderstore.ini contains 3 lines

[Directory]
Cabfolder1=C:\Documents and Settings\user name\My Documents
Cabfolder2=C:\Documents_and_Settings\user_name\My_Documents

my batch is

Set inifile=folderstore.ini
Set txt1=%~n011.txt
type %inifile% | find "Cabfolder1=">%txt1%
:: Note: Current script unable to work with space
FOR /F "tokens=2* eol=; delims== " %%i in (%txt1%) do (set value1=%%i)
if %value1%==0 color 1A && echo Folder path not defined.
If not %value1%==0 Echo %value1% ^<---is the preset folder.
echo.
del %txt1%
pause

0

Share this post


Link to post
Share on other sites

Try this:

Set inifile=folderstore.ini
Set txt1=%~n011.txt
rem :: Note: Current script unable to work with space
FOR /F "delims== tokens=2* usebackq" %%i in (`type %inifile% ^| find "Cabfolder1="`) do (set value1="%%i")
if %value1%=="" (color 1A && echo Folder path not defined.) else (Echo %value1%)
echo.
pause

0

Share this post


Link to post
Share on other sites

Try this vbs script to see if it does what you want.

Updated Code Fix Save as Read_Ini_2.vbs


'-> Object For Runtime
Dim Fso :Set Fso = CreateObject("Scripting.FileSystemObject")
'-> File To Open, Place Full Path If Script Not Is Ame Folder as Ini
Dim Ini :Ini = "folderstore.ini"
'-> Varibles For Run Time
Dim Chk, Loc, Obj, Ts
'-> Check For File Exists
If Fso.FileExists(Ini) Then
'-> Open And Read All Into One Varible
Set Ts = Fso.OpenTextFile(Ini,1)
Chk = Ts.ReadAll
Ts.Close
'-> Split The Varible By Line And Loop Threw It
For Each Obj In Split(Chk,vbCrLf)
'-> Filfter Out Cabfolder1
If InStr(1,Obj,"Cabfolder1",1) Then
'-> Split The Line Into Separate Objects
Loc = Split(Obj,"=")
End If
Next
Else
'-> File Not Found
MsgBox "Error 1 Missing : " & Ini
WScript.Quit(0)
End If
'-> Checks For Results
If Not Loc(1) = "" Then
MsgBox "Confirm : " & Loc(1),4128,"Confirmed Folder"
Else
MsgBox "Error 2 : Folder path not defined.",4128,"Error 2"
End if

Updated Code Fix

0

Share this post


Link to post
Share on other sites

.....delims==HERE_NO_SPACE"

Set inifile=folderstore.ini
Set txt1=%~n011.txt
type %inifile% | find "Cabfolder1=">%txt1%
:: Note: Current script able to work with space
FOR /F "tokens=2 eol=; delims==" %%i in (%txt1%) do (set value1=%%i)
if not defined VALUE1 (color 1A && echo Folder path not defined.) else (Echo %value1% ^<---is the preset folder.)
echo.
del %txt1%
pause

Edited by Schiiwa
0

Share this post


Link to post
Share on other sites

If I may :unsure:, both the wheel and hot water have been invented. :whistle:

OT, but not much ;):

http://en.wikipedia.org/wiki/AK-47

http://en.wikipedia.org/wiki/AK-47#Design_concept

A lot of [soviet Army soldiers] ask me how one can become a constructor, and how new weaponry is designed. These are very difficult questions. Each designer seems to have his own paths, his own successes and failures. But one thing is clear: before attempting to create something new, it is vital to have a good appreciation of everything that already exists in this field. I myself have had many experiences confirming this to be so.

http://www.robvanderwoude.com/vbstech_files_ini.php

http://www.robvanderwoude.com/battech.php#Files

http://www.robvanderwoude.com/files/readini_nt.txt

jaclaz

0

Share this post


Link to post
Share on other sites

Something like this should do what you need:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION
(SET VAL1=)
FOR /F "TOKENS=1* DELIMS==" %%# IN (
'FIND "Cabfolder1"^<FOLDERSTORE.INI 2^>NUL') DO SET "VAL1=%%$"
IF NOT DEFINED VAL1 (COLOR 1A
ECHO= Folder path not defined
COLOR
PAUSE
GOTO :EOF)
ECHO= %VAL1% ^<---is the preset folder.
PAUSE

0

Share this post


Link to post
Share on other sites

While I'm not a fan of the particular coding style used, it's surprisingly well thought out/designed. That really could have came in handy back then. But yet again, it's even shorter/more concise in PowerShell using regex pattern matching and hash tables. Yes, the syntax is different (it's really one switch statement, with 3 short regular expressions for matches) but on the other hand the program flow is much simpler.

0

Share this post


Link to post
Share on other sites

Thanks for all the suggestions. I tested them using 3 scenarios

(1. Folder with space, 2. Folder no space, 3. Empty folder (ie. empty string))

I changed folderstore.ini to below so that I can easily modify the seach key to test all 3 situations.

[Directory]
Cabfolder1=C:\Documents and Settings\user name\My Documents
Cabfolder2=C:\Documents_and_Settings\user_name\My_Documents
Cabfolder3=

@allen2

Appreciate your input. Notice the output string is always quoted.

(I hope not to have it quoted.). If I change

(set value1="%%i")

to

(set value1=%%i) and rerun, the script terminate abnormally.

I wonder why terminate abnormally? Perhaps this line is causing problem:- if %value1%==""

Also if cabfolder3= (contains empty entry), the script terminate abruptly.

(I presume you did not check this part for empty folder)

You have remove the need for temp file : %txt1%. (I couldn't figure out how to do it w/o temp file.)

@gunsmokingman

Thanks for the alternative. Although your script looks for "Cabfolder1", it returns the value of Cabfolder2.

Suppose I add an extra line to folderstore.ini to test for empty string/path,

and I specify "Cabfolder2" within the script, it return Cabfolder3 value. Or do I miss out something?

Normally the expected output is the string on the right only. The script rtn the whole line, including strings on the left.

@Schiiwa

Achieve what I set out to do in all 3 scenarios (Folder with space, folder no space, empty string).

Thanks. I didn't know how to use If not defined syntax. I guess the scenario illustrate how to use this syntax.

Combining allen2's & Schiiwa's input, (because %txt1% is not required and Schiiwa fixed the problem by using If not defined rather than if %value1%=="",

so the final script I adopt is

@echo off
Set inifile=folderstore.ini
FOR /F "delims== tokens=2* usebackq" %%i in (`type %inifile% ^| find "Cabfolder3="`) do (set value1=%%i)
If not defined VALUE1 (color 1A && echo Folder path not defined.) else (Echo %value1%)
echo.
pause

@jaclaz

Thanks for the link. Will read up on For /F [option] parameters.

If you have other useful links, do pass on.

Also it's not that I'm re-inventing the wheel but the script out there are fairly advanced for my humble knowledge to

easily adapt for my use.

I believe if I code it first I will appreciate and learn better the batch language.

@Yzowl

Thanks, yes, fits what I need. Perfect.

I could have easily script using Autoit but I just wish to experience using pure batch to see how difficult or easy to do such simple task.

Apparently, looking at the solution .... doesn't look easy after all.

But it's all for the sake of knowledge, esp For loop command.

They are the bread and butter of cmd syntax to be really useful.

Thank you all.

Best regards

0

Share this post


Link to post
Share on other sites

@jaclaz

Thanks for the link. Will read up on For /F [option] parameters.

If you have other useful links, do pass on.

Also it's not that I'm re-inventing the wheel but the script out there are fairly advanced for my humble knowledge to

easily adapt for my use.

I believe if I code it first I will appreciate and learn better the batch language.

Yep :), the idea was not to somehow discourage you from writing it yourself from scratch, only to let you know what has already been done and allow you to (hopefully) manage to EITHER:

  • save time by using something pre-made (with any customization you may need)
  • invent a rounder wheel (or hotter water)

If the target is just like the example:

[Directory]
Cabfolder1=C:\Documents and Settings\user name\My Documents
Cabfolder2=C:\Documents_and_Settings\user_name\My_Documents
Cabfolder3=

You can also use directly Environment variables, example oneliner:

Like:

@echo off&FOR /F "delims=" %%A IN ('TYPE folderstore.ini ^|FIND /V "["') DO SET %%A

Will make environment variables Cabfolder1 and Cabfolder2 with the correspondent values, but not Cabfolder3 (and it will actually reset the variable).

But I miss the actual "final goal that you are looking for.

I mean, do you need to "choose" among the various Cabfoldern or you want to selct last "defined" one or you just want to list the values (i.e. SET Cabfolder ) or what?

jaclaz

0

Share this post


Link to post
Share on other sites

But I miss the actual "final goal that you are looking for.

I mean, do you need to "choose" among the various Cabfoldern or you want to selct last "defined" one or you just want to list the values (i.e. SET Cabfolder ) or what?

jaclaz

No need to choose among the various Cabfolder. Script should be able to read in just one cabfolder value

Actually all I need in folderstore.ini is just 1 entry cabfolder1=Some path with space

Of couse, I will manually change to cabfolder1=SomePathWithoutSpace if need to.

It also caters to cabfolder1= where there is no folder path at all. Hence Empty folder scenario may comes in.

But to make testing easier, instead of modifying folderstore.ini value, I inserted cabfolder2= & cabfolder3= to test all 3 possible situations.

If cabfolder1= actually has no path (which I will set it manually), then the script must be able to tell me "no folder defined".

0

Share this post


Link to post
Share on other sites

No need to choose among the various Cabfolder. Script should be able to read in just one cabfolder value

Actually all I need in folderstore.ini is just 1 entry cabfolder1=Some path with space

Of couse, I will manually change to cabfolder1=SomePathWithoutSpace if need to.

It also caters to cabfolder1= where there is no folder path at all. Hence Empty folder scenario may comes in.

But to make testing easier, instead of modifying folderstore.ini value, I inserted cabfolder2= & cabfolder3= to test all 3 possible situations.

If cabfolder1= actually has no path (which I will set it manually), then the script must be able to tell me "no folder defined".

Then two/three lines might do:

Given this

[Directory]

Cabfolder1=C:\a long path including a few spaces

@echo off
FOR /F "delims=" %%A IN ('TYPE folderstore.ini ^|FIND /V "["') DO SET %%A
IF NOT DEFINED Cabfolder1 SET /P Cabfolder1=Path to your cabfolder:

jaclaz

0

Share this post


Link to post
Share on other sites

I wouldn't use Jaclaz method as it might be dangerous if the ini file contains entries that are already environment variables and might cause some strange behavior is the script doesn't end:

[Directory]
Path=
USERNAME=

@Geej

I did add the double quote on purpose to be able to use properly the variable after.

0

Share this post


Link to post
Share on other sites

@gunsmokingman

Thanks for the alternative. Although your script looks for "Cabfolder1", it returns the value of Cabfolder2.

Suppose I add an extra line to folderstore.ini to test for empty string/path,

and I specify "Cabfolder2" within the script, it return Cabfolder3 value. Or do I miss out something?

Normally the expected output is the string on the right only. The script rtn the whole line, including strings on the left.

My bad here is a Script that will do what you want.

Contents of the folderstore.ini I used


[Directory]
Cabfolder1=C:\Documents and Settings\user name\My Documents
Cabfolder2=C:\Documents_and_Settings\user_name\My_Documents

post-5386-0-99507900-1320699651_thumb.pn

Save As Read_Ini_2.vbs


'-> Object For Runtime
Dim Fso :Set Fso = CreateObject("Scripting.FileSystemObject")
'-> File To Open, Place Full Path If Script Not Is Ame Folder as Ini
Dim Ini :Ini = "folderstore.ini"
'-> Varibles For Run Time
Dim Chk, Loc, Obj, Ts
'-> Check For File Exists
If Fso.FileExists(Ini) Then
'-> Open And Read All Into One Varible
Set Ts = Fso.OpenTextFile(Ini,1)
Chk = Ts.ReadAll
Ts.Close
'-> Split The Varible By Line And Loop Threw It
For Each Obj In Split(Chk,vbCrLf)
'-> Filfter Out Cabfolder1
If InStr(1,Obj,"Cabfolder1",1) Then
'-> Split The Line Into Separate Objects
Loc = Split(Obj,"=")
End If
Next
Else
'-> File Not Found
MsgBox "Error 1 Missing : " & Ini
WScript.Quit(0)
End If
'-> Checks For Results
If Not Loc(1) = "" Then
MsgBox "Confirm : " & Loc(1),4128,"Confirmed Folder"
Else
MsgBox "Error 2 : Folder path not defined.",4128,"Error 2"
End if

Rename Read_Ini_2.vbs.txt to Read_Ini_2.vbs to make active

Read_Ini_2.vbs.txt

0

Share this post


Link to post
Share on other sites

@jaclaz

Instead of finding the actual string of cabfolder1, you inverted it via Find /V. Hence result returns the cabfolder1.

Nice trick.

@gunsmokingman

Works fine now. Thanks for the fix.

0

Share this post


Link to post
Share on other sites

You don't even need to use find if you only have one line under a single section heading.

Type this single line into a console window to see what I mean:

FOR /F "USEBACKQ EOL=[ TOKENS=*" %# IN ("X:\PATH TO\DIRECTORY\FOLDERSTROE.INI") DO @ECHO=%#

Obviously you'll need to change the path accordingly.

0

Share this post


Link to post
Share on other sites

You don't even need to use find if you only have one line under a single section heading.

Type this single line into a console window to see what I mean:

FOR /F "USEBACKQ EOL=[ TOKENS=*" %# IN ("X:\PATH TO\DIRECTORY\FOLDERSTROE.INI") DO @ECHO=%#

Obviously you'll need to change the path accordingly.

Yep :thumbup

But, since we are going to read a very simple file, made of two lines, of which we are interested in the second only, we can also skip the first one.

@allen2

Of course it is presumed that no Cabfolder1 environment variable is present, please note how your remark also applies to the original "value1" or, for that matter, for any variable name, theoretically you need to do error checking EVERY time you define a variable to see if it is already defined or use a LOCAL statement (or use XSET for an opposite behaviour), etc., etc.

@echo off
SETLOCAL
FOR /F "USEBACKQ skip=1 tokens=1,2 delims==" %%A IN ("folderstore.ini") DO IF NOT DEFINED %%A SET "%%A=%%B"&IF NOT DEFINED %%A SET /P %%A=Path to your cabfolder:

the above won't touch a pre-existing variable, but obviously IF the variable is already defined, it won't be of ANY use.

This might be more effective ;) (just an idea):

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
SET #a_h1ghl1_1mprob@bl3_v@r1@bl3_n@m3=NO
FOR /F "USEBACKQ skip=1 tokens=1,2 delims==" %%A IN ("folderstore.ini") DO (
IF DEFINED %%A (
ECHO Dear demented USER, the variable %%A IS ALREADY DEFINED!
SET %%A
ECHO.
SET /P #a_h1ghl1_1mprob@bl3_v@r1@bl3_n@m3=Type YES - CAPITAL LETTERS - to change it's value to "%%B" or press [ENTER] to leave it alone:
) ELSE (
SET #a_h1ghl1_1mprob@bl3_v@r1@bl3_n@m3=YES
)
IF "!#a_h1ghl1_1mprob@bl3_v@r1@bl3_n@m3!"=="YES" SET "%%A=%%B"&IF NOT DEFINED %%A SET /P %%A=Path to your cabfolder:
)

jaclaz

0

Share this post


Link to post
Share on other sites

FOR /F "TOKENS=1* DELIMS==" %%# IN (
'FIND "Cabfolder1"^<FOLDERSTORE.INI 2^>NUL') DO SET "VAL1=%%$"

Hi, Yzöwl

I was trying to understand your script in post#6 and was wondering what does it means when you use %%#

and %%$

If I tried replacing with normal variable like

%%A for %%# and

%%B for %%$

surprising it returns correctly the result.

And looking at the ascii table,

the next character after # is $,

just like next character after A is B.

Is there other special consideration when you use # and $ as variable?

Will simple character like A and B achieve exactly the same result?

So I can generally use special character as variable, just like you did?

0

Share this post


Link to post
Share on other sites

It's just my personal preference, I use them in exactly the same way as you use A and B, I just find that they stand out better than all of the other A's and B's for example.

0

Share this post


Link to post
Share on other sites

Just for the record:

http://www.robvanderwoude.com/clevertricks.php

scroll down until you find "Carlos M. found a way to increase the number of variables available in a FOR /F loop" that explains partially the thingy.

The real issue :ph34r: wich I can see with using the additional # and $ is that the NEXT characters are %, &, etc. that would need to be escaped, so they are a very nice choice if you only have 2 tokens, but they may become a problem if you need 3 or more. :unsure:

jaclaz

0

Share this post


Link to post
Share on other sites

Thanks for the clarification, Yzowl. I prefer conventional variable.

Jaclaz, thanks for the trick links. Looks pretty interesting.

0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.