Is it possible (in a non-kludgy way) ?
Two notes:
1) The 4NT (originally 4DOS) language allows this - there is a INIREAD
function. I seem to remember seeing something similar in the CMD
language, but can't find it now.
2) I googled this and found a really hacky/kludgy way to do it, that
involved using find and piped through about 6 other commands (including,
believe it or not, the DATE command). I'm not interested in anything kludgy
like this.
Can you provide details about what you need to find and do?
I thought it was pretty clear, but here's an example.
If you look in your WIN.INI file (on an XP system, for example), you
might find these lines:
[Mail]
MAPI=1
So, in my CMD.EXE batch file, I would like to be able to retrieve the
value stored in Section "Mail", key "MAPI", which happens to be "1".
Does that help?
Will "MAPI=" exist anywhere else in the ini file?
To some extent. Batch is sensitive to some characters, but for the mostpart,
Where - parameter 1 is the filename, parameter 2 is the section name and
parameter 3 the key, each of which may be quoted.
----- batch begins -------
[1]@echo off
[2]setlocal enabledelayedexpansion
[3]set yrd=
[4]set yrs=
[5]for /f "usebackq tokens=1*delims==" %%i in ("%~1") do set yc1=%%i&set
yc1=!yc1:~0,1!&if !yc1!==[ (if "%%i"=="[%~2]" (set yrs=Y) else (set yrs=))
else (
[6] if defined yrs if /i "%~3"=="%%i" set yrd=%%j
[7])
[8]endlocal&set "yrd=%yrd%"
[9]set y
------ batch ends --------
Lines start [number] - any lines not starting [number] have been wrapped and
should be rejoined. The [number] that starts the line should be removed
%varname% will be evaluated as the value of VARNAME at the time that the
line is PARSED. The ENABLEDELAYEDEXPANSION option to SETLOCAL causes
!varname! to be evaluated as the CURRENT value of VARNAME - that is, as
modified by the operation of the FOR
This is intended to work by splitting each line into the part before the "="
and the rest of the line. If the first token has a first character of "["
then it checks that you are in Your Required Section by doing a
case-insensitive match on the bracketed second parameter. After the section
name is detected, and until the next section is detected, if the third
parameter matches the key found then Your Required Data is set to the data
portion of the line.
[9] is just to show the value returned.
> I thought it was pretty clear, but here's an example.
> If you look in your WIN.INI file (on an XP system, for example), you
> might find these lines:
>
> [Mail]
> MAPI=1
>
> So, in my CMD.EXE batch file, I would like to be able to retrieve the
> value stored in Section "Mail", key "MAPI", which happens to be "1".
>
> Does that help?
>
From command line (one line)
for /f "tokens=2 delims==" %A in ('find /i "mapi=" %systemroot%/win.ini')
do @echo %A
On my system there is also a mapix entry, so you need to search for "mapi="
In a batch to restrict to keys in the section Mail:
@echo off&setlocal enabledelayedexpansion&set CurrSect=[TopOfFile]
for /F "tokens=1,* delims==" %%A in ('Type "%systemroot%\win.ini'
) do (set Line=%%A
If "!Line:~0,1!" EQU "[" set CurrSect=!Line!
If /I !CurrSect! EQU [Mail] if /I %%A EQU MAPI set MyMail=%%B
)
echo.[Mail]Mapi=%MyMail%
--
Greetings
Matthias
There are command line utilities specifically made for manipulating INI
files. I seem to recall that 4DOS works on NT systems also. Are you trying
to avoid using 4DOS or other utilities?
By "not interested in anything kludgy", shall we assume that includes
VBScript/Qbasic code in a batch wrapper? Does one of the posted batch
examples do what you need?
--
Todd Vargo
(Post questions to group only. Remove "z" to email personal messages)
It could. Obviously, a good solution would only find it in the
specified section. I've noticed a lot of the kludgy solutions presented
assume that you can simply "find" the line one line, ignoring the
section aspect.
While I admire the skill involved in putting something like this
together, this is clearly a "kludgy" solution.
What it boils down is this: If there isn't any built in support for it
(and, so far, it seems there is not), then the only real solution is to
do it in some other Windows programming language, that has access to the
IniRead WPI, and then somehow transmit that information back to the
batch file. The later part is the tricky part.
Yes, where this came from is trying to port a 4NT script to CMD.
>By "not interested in anything kludgy", shall we assume that includes
>VBScript/Qbasic code in a batch wrapper?
No. I think that is the only sensible way to do it. It seems you need
to write something in some higher level language (such as, well, just
about anything that has access to the needed API function) and then have
that program construct a batch file containing:
set somevar=<value from INI file>
Then the calling batch file "CALL"s the constructed batch file.
This is kludgy, but at least manageable.
>Does one of the posted batch examples do what you need?
So far, they are all what I would call "kludgy".
Basically, anything you have to write yourself (because no intrinsic
function exists) is a kludge. http://en.wikipedia.org/wiki/Kludge
VBScript does not have an intrinsic INIread function nor access to
equivalent API functions. You could write a VBScript or Qbasic program that
does exactly what INIread or an API function does. i.e. Read the file line
by line until the particular section is reached. Then check it's keys for a
particular key until another section is reached. Unfortunately, that would
not fit the "non-kludgy" requirement set forth, but if that is what you want
to do, then you will have to rephrase your question (it would help if you
lighten up with the attitude a bit too).
> >>[Mail]
> >>MAPI=1
> >>
> >>So, in my CMD.EXE batch file, I would like to be able to retrieve the
> >>value stored in Section "Mail", key "MAPI", which happens to be "1".
> >>
> >>Does that help?
> >
> >Will "MAPI=" exist anywhere else in the ini file?
> >
>
> It could. Obviously, a good solution would only find it in the
> specified section. I've noticed a lot of the kludgy solutions presented
> assume that you can simply "find" the line one line, ignoring the
> section aspect.
@echo off
find /v /n "" <win.ini >_.1
for /f "tokens=1 delims=[]" %%i in ('find "[Mail]" ^<_.1') do set n=%%i
for /f "tokens=1* delims=[]" %%i in ('more +%n% ^<_.1^|find "MAPI="') do (
set %%j & goto :exit)
:exit
echo MAPI has the value: %MAPI%
del _.1
>So far, they are all what I would call "kludgy".
So you don't want to do it using native batch commands, so be it:
ChangeINI - INI File Changer - Copyright 1997 Robert L. Bogue
Rob....@Cyber-Wizard.Com;Phone (317) 844-5310; FAX (317) 846-3892
Usage : ChangeINI <INI File> <Heading> <Entry> <Value>
Where : <INI File> is the file you want to change
<Heading> is the heading the entry falls under
<Entry> is the entry name
<Value> is the value to set the entry to, or *DELETE* to delete
the entry.
Returns: 0 - Sucessful Completion
1 - Invalid Number of arguments (this message)
2 - Unable to open INI file
3 - Unable to open temporary file
4 - Error writing to temporary file
5 - Heading Name too long
6 - Entry Name too long
Found it at
http://dl.winsite.com/bin/downl?500000027109
(30k download, 8k chgini16.exe though!)
This will suffice in most cases, but, [Mail]/MAPI=1 was referred to as "for
example" not 'I'm actually trying to do this'. If the key sought does not
exist within the specified section, the code above could conceivably locate
one of the same name within a subsequent section therefore OP will likely
balk at even this brilliant solution.
That looks like it will *write* the INI file, not read it.
As I said elsethread, *accessing* (1) the INI file is easy; the hard
part is getting the info gleaned back into the batch script (2).
(1) I.e., either reading or writing.
(2) Absent built-in support, such as the INIREAD[] function in 4NT.
P.S. I have solved this problem, by writing a short program in a
language that has access to the IniReadPvt() API. The program writes
out a batch file that contains a "set" command. The batch file then
CALLs and then DELs the created batch file.
> > @echo off
> > find /v /n "" <win.ini >_.1
> > for /f "tokens=1 delims=[]" %%i in ('find "[Mail]" ^<_.1') do set n=%%i
> > for /f "tokens=1* delims=[]" %%i in ('more +%n% ^<_.1^|find "MAPI="') do (
> > set %%j & goto :exit)
> > :exit
> > echo MAPI has the value: %MAPI%
> > del _.1
>
> This will suffice in most cases, but, [Mail]/MAPI=1 was referred to as "for
> example" not 'I'm actually trying to do this'. If the key sought does not
> exist within the specified section, the code above could conceivably locate
> one of the same name within a subsequent section therefore OP will likely
> balk at even this brilliant solution.
@echo off
setlocal enabledelayedexpansion
for /f "tokens=1* delims=:" %%i in ('findstr /b /n "[" ^<win.ini') do (
set n1=!n2!
set n2=%%i
if "!s!"=="[Mail]" goto :exit
set s=%%j)
:exit
set /a n2=n2-n1-1
for /f "tokens=1* delims=[]" %%i in ('more +%n1% ^<win.ini^|find /n "MAPI="') do (
set n1=%%i & set %%j & goto :exit2)
:exit2
if %n1% GTR %n2% (echo MAPI not found) else (echo MAPI has the value: %MAPI%)
All the other things alle the others has said sounds hard so try
nircmd.exe a commandline utillity form nirsoft.net
Hope you like it
> All the other things alle the others has said sounds hard so try
> nircmd.exe a commandline utillity form nirsoft.net
>
> Hope you like it
In case OP's post did not propagate well:
On 18 Oct, 2007, OP posted, "I have solved this problem...".
True, but I am curious about this "nircmd" util. I'm going to assume
that it is "yet another" utility for getting access to INI files from a
command line. So, question: How does it transmit the information back
to the batch file? (As noted in my other posts, that's the tricky part)
> command line. So, question: How does it transmit the information back
> to the batch file? (As noted in my other posts, that's the tricky part)
Write it to stdout and use:
for /f %%i in ('myprogram.exe') do set var=%%i
Yes, that's not bad. I assume those are backticks (`) not quotes (').
Is that how the nircmd utility works?
I'm not interested in nircmd, but when interested in learning how something
works, I typically download it, RTFM, and perform my own testing. Actually,
I was going to post a simple (IMO) VBScript powered batch, but owing to your
kludge remarks (and since you already created your own utility), I figured
my time was better spent elsewhere.
I wasn't interested in it enough to go to his website, increase his hit
count, and possibly pick up some viruses, either. But I was inviting him
to discuss it here, should he so desire.
>I was going to post a simple (IMO) VBScript powered batch, but owing to your
>kludge remarks (and since you already created your own utility), I figured
>my time was better spent elsewhere.
Fair enough. As I said, all solutions that boil down to either writing
a batch file that the calling script calls (or, equivalently, writing to
stdout and using the backtick notation) are equivalent, and are,
apparently, the best you can do. I'm OK with that; I was just curious
if anyone had come up with anything better.