0

I've been trying to make a program (.bat which then I will convert to a .exe) which copies and run software installers to get a specific program installed on a ton of computers, but I also what to make it work with any file and making a .txt file to tell the .bat file how to execute the xcopy command...

So... I need help with reading from .txt files in a BATCH file

This is part of my code without the run and deleting thing:

@echo off

echo Running...

for /f "Delims=1" %%a in (settings.txt) do (
set settings1=%%a
)
set file_org=%settings1%

for /f "Delims=2" %%b in (settings.txt) do (
set settings2=%%b
)
set file_dest=%settings2%

echo Copying %file_org% to %file_dest% ...
xcopy /y %file_org% %file_dest% >nul
echo Copied %file_org% to %file_dest% succesfuly!
pause

And this is how the .txt file should be when correct:

F:\test
C:\Users\%username%\Desktop

The first line is the origin of the file it will copy The second line is the destination the file it will be copied to

Yes, this is ment to be run on an USB stick, in fact like I said earlier it's to transfer, run, delete an Installation program of a USB stick to make mass software installation a lot faster.

Let me tell you how the whole thing works:

  1. Configure the settings.txt file
  2. Plug the stick into a PC with the desired program and my little .bat file
  3. Run it!
  4. Continue the installation process with the program
  5. My software deletes the intaller
  6. Remove the stick from the PC (For safety don't forget to eject the USB ;) )
  7. Repeat this very short process on another computer

All of that saves time because you don't have to go get the Installer every time, just configure everything once and keep installing... :)

Also I like making things pretty so... don't give something me messy please... :)

Thank you and advance, Love from France, ILTP -_-

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
boons
  • 1
  • 2
  • I was going to add this to my answer, but it technically isn't relevant to the question or answer. In your `settings.txt` file example, if you're using the environment variable for the users `Desktop` location, I would suggest, `%UserProfile%\Desktop`, not `C:\Users\%username%\Desktop`. – Compo Jan 08 '19 at 23:31
  • Also, if the source file, `%file_org%`, is on the same USB drive as the batch file, you don't need to hard code the drive letter. You could instead look at modifiers, e.g. `%~d0\test`, which should reference the drive regardless of the letter it is allocated to. – Compo Jan 08 '19 at 23:41
  • Final advice, do not use some pointless wrapper to pretend your batch file is anything other than a batch file. Not only will it extract your batch file to a temporary location, probably on the users PC, _which could interfere with the advice I provided in my previous comment_, it could also cause issues with their antivirus/antimalware software. – Compo Jan 08 '19 at 23:56

2 Answers2

0

The main issue you're having with your code is the misuse of Delims=. In summary, this will tell the for loop to loop for as part of separation between tokens. An example of this will be take Hello1My1Name1Is1John... Delims=1 Will remove the 1 and allow you to separate them based on tokens=1,2,3,4,5 so %%A = Hello, %%B = My, Exc.

The thing that will actually help you on this one would be an operator called skip=. This will limit the results by skipping the x amount of first results. So..

for /f "Tokens=*" %%a in (settings.txt) do (
    set file_org=%%a
)

for /f "Tokens=* Skip=1" %%a in (settings.txt) do (
    set file_dest=%%a
)

However, there is a much easier way to do this. Being that you have control of how you format your text file, we can limit the code and make it much more professional by rather grabbing the string name and data from one line of the text file.

To do this, we can use an file_org=F:\test format. To call these in a loop a very simple for loop with tokens=1,2* delims== will be used. Keep in mind that especially for folder/file locations, you quote your set statements. Example, set "file_dest=%settings2%". Further note, don't be afraid to set your main string inside the loop it's self. I see why you did this as you wanted to grab the latest result, but with a proper loop set-up you will not need to do this!

Copy.Bat:

@ECHO OFF

Rem | Set strings based of whats in config
for /F "tokens=1,2* delims==" %%A in (Settings.ini) do (
    Set "%%A=%%B"
)

echo Copying %file_org% to %file_dest% ...
xcopy /y %file_org% %file_dest% >nul
echo Copied %file_org% to %file_dest% succesfuly!

pause

Settings.ini: (Named .ini for self-preferences. .txt will work too)

file_org=F:\test
file_dest=C:\Users\%username%\Desktop

For help on any of the commands do the following:

  • call /?
  • set /?
  • for /?
  • if /?
  • find /?
  • So on.
John Kens
  • 1,615
  • 2
  • 10
  • 28
  • Your `for /F` examples demonstrating the `skip` option would give the second line for both loops (given there are two lines), unless you leave the loop with a `goto` after the applicable line being read or you'd do `if not defined file_org set file_org=%%a`... – aschipfl Jan 09 '19 at 12:05
  • @aschipfl Yeah you will need to exit the loop once your result was found or use an if statement. It was pure demonstration and I hope the OP can put two and two together. – John Kens Jan 09 '19 at 16:05
0

I would try to perform the task of reading the first and second lines of the file into variables like this:

@Echo Off
Echo Running ...
(Set /P "file_org="
    Set /P "file_dest=")<"settings.txt"
Echo Copying %file_org% to %file_dest% ...
XCopy "%file_org%" "%file_dest%" /Y >Nul 2>&1 && (
    Echo Copied %file_org% to %file_dest% succesfully!)
Pause

Hope it helps you out.

Compo
  • 36,585
  • 5
  • 27
  • 39