Windows batch for loop sub routines and local variables - windows

At work we use Windows batch files to run jobs off a scheduling tool. It's an old tool and approach but it works. I have to make new jobs fit the existing technology.
For this particular job I need pick up a number of files from a folder and load them into a SQL server database table. For each one I load I then need to run a bit of SQL to update the recently populated table.
So I have a for loop that looks for files in the folder. If one exists I use SQL server's BCP to load the data into a table. I then use SQL server's SQLCMD to perform the update.
The policy is when using BCP or SQLCMD to write any issues out to files. Post call we then check these files to ensure that nothing went wrong.
When dealing with a single file this is fairly straightforward stuff. Using a FOR loop is proving to be impossible.
I envisaged calling a sub routine which would set a variable that code in the for loop could check and if appropriate exit gracefully.
The first thing we do in the batch file is set a global variable to 0. When the batch job returns control to the 'scheduler' if this is not equal to 0 the job shows as failed.
So paraphrasing the code it looks something like the following.
SET g_status=0
SET LOCAL EnableDelayedExpansion
FOR n = 1 to 12
IF FILE(n) EXISTS (
Execute BCP....
Execute SQLCMD....
CALL check_sql_status
IF !l_error_status! NEQ 0 ENDLOCAL & SET g_status=!l_error_status!
IF g_status NEQ 0 GOTO exit_gracefully
)
NEXT
.
.
GOTO END
REM ========
:check_sql_status
REM======
IF something is wrong (
SET l_error_status=123
GOTO EOF
REM ========
:exit_gracefully
REM======
ECHO g_status
:End
.
.
Don't get hung up on the 'code' above. It's only the bit where I am attempting pass the local variable back to the global variable that I am interested in. No matter what I try I cannot get the global variable to accept the value set in the sub routine.
I will try to find this question and post some of the actual code when I get back to work although BCP and SQLCMD use lots of parameters that may just confuse rather than help.

Related

Programming a "Not - Gate" situation into a batch file?

Brand new to coding of any form. Simply put: I have 2 batch files written. 1 loads one configuration into a program (MultiMonitor), the other loads a 2nd configuration. Id like a 3rd file to act as a "light switch" Or a "NOT-Gate." Effectively, if last time it was ran, it launched the bat controlling config 1, this time it should load config 2.
Currently I just launch the appropriate .bat; but id like to simplify this so I only have one file to launch and then it chooses the one not chosen last time.
This is easy:
In option1.bat (in addition to the real work):
echo call option2 > autoselect.bat
In option2.bat
echo call option1 > autoselect.bat
There are a few ways you could do this:
Use a permanent environmental variable using setx - NOT RECOMMENDED
Test which config is currently being used by your program - I am unfamiliar with your program so I do not know if this is even possible.
Use a temporary file
This example shows how to do this with a temp file:
if not exist file.ext (
rem load config #1
echo.>file.ext
) else (
rem load config #2
del file.ext
)
The file can be named whatever you want.

Windows MessageQueue trigger and rule: Batch-File doens't work on first call

I've realized today a really strange problem. I am writing a batch-file that uses the trigadm.exe to generate a rule and a trigger on a specific Windows Message Queue.
Now the creation of the trigger and the rule is not the problem, because i have tested it several times and it works.
What i want is, to check first if the rule and the trigger is already existing. If they dont existing, then i will create them. When they are already existing, i wont do anything and exit the batch-script.
When I generate the rule and the trigger via trigadm.exe, I get always an GUID for the rule and one for the trigger. To check them later, I save these rules into textfiles. So when I check if they are existing, i just read out these GUID's from the textfiles and use the method of trigadm.exe if a rule or trigger with the specific GUID is existing. When a rule or trigger is existing, i get a message as output like: Details for the rule with the ID: b5ea975a-efd6-444a-9ae5-2a366e723980.... If a rule or trigger is not existing, i get also a message like: Failed : The specific rule doesn't exist. So I save this message also into a file and check if the contet contains the word: Details. If it contains that word, i wont create the rule or trigger.
So the main problem is; when i try to call the batch-file from the windows command prompt, it doesn't work on the first call. I have to call the batch-file about 4 times, till it works.
Does anyone have an idea what the problem here could be?
#ECHO OFF
IF EXIST C:\temp\WarehouseOrder\Installation\ruleId.txt (
SET /p rId=<C:\temp\WarehouseOrder\Installation\ruleId.txt
trigadm /request:GetRule /ID:%rId% > C:\temp\WarehouseOrder\Installation\msg.txt
SET /p msg=<C:\temp\WarehouseOrder\Installation\msg.txt
SET result=%msg:~0,7%
IF "%result%" == "Details" (
ECHO rule already exists > result.txt
)
)
If you don't wish to use delayed expansion you could just restructure your script.
#ECHO OFF
IF NOT EXIST C:\temp\WarehouseOrder\Installation\ruleId.txt GOTO :EOF
SET /P "rId=<C:\temp\WarehouseOrder\Installation\ruleId.txt"
(trigadm /request:GetRule /ID:%rId%)>C:\temp\WarehouseOrder\Installation\msg.txt
SET /P "msg=<C:\temp\WarehouseOrder\Installation\msg.txt"
IF /I "%msg:~,7%"=="Details" ECHO=rule already exists>result.txt

Windows 10 command line/script - for or loop filename(1), filename(2)

I am writing a script (batch file) currently to run at Windows Command Line. The task is I have a variable number of files in a folder. The files are named in the format of filename(1), filename(2) ... etc.
I am trying to set a FOR loop or using a IF ... GOTO to move filenames(1 to 9) to one folder, then filenames (10 to 99) to another folder and so on so I can deal with them separately.
So, easy way would be to copy in sequence to join to source files into a single target file. Alternatively a way to construct a filename for a copy and/or move command that looked at files such as test(1), test(2), ... test(9) in order and then stop.
Files are sorted in folder in following order - test(1).txt test(2).txt test(3).txt test(4).txt test(5).txt test(6).txt test(7).txt test(8).txt test(9).txt
There may only be two or three files however, or there maybe 1000 files in the folder to be dealt with.
I have been trying to set something like this up:
set count1=9
set count2=99
set count_loop=1
:while_loop1
echo "count_loop = " %count_loop%
move test(%count_loop%) proto\9\
set /a "count_loop = count_loop + 1"
if %count_loop% leq %count1% (
echo test(%count_loop%) moved
goto while_loop1)
I could do with some advice here.
Cheers, Thomo the Lost

Registry Edit From Batch

I would like to change the registry path's value from 0 to 1:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI\Background\OEMBackground
Is there any possible way of doing this within a batch file using the "reg" command? You can grab the syntax here. I searched it, but can not find a way to modify it. Any help would be greatly appreciated. Thanks!
I would stay away from reg.exe, it can be blocked by a policy. I suggest to use wmic.exe.
In your case it should works like this:
setlocal
:: $KEY broken for better readability
set "$KEY=SOFTWARE\Microsoft\Windows\CurrentVersion"
set "$KEY=%$KEY%\Authentication\LogonUI\Background"
set "$VALNAME=OEMBackground"
set "VAL=1"
set "HIVE=&H80000001" &:: "&H80000001 = HKEY_LOCAL_MACHINE"
wmic.exe /NAMESPACE:\\root\default Class StdRegProv Call^
SetDWORDValue^
hDefKey="%HIVE%"^
sSubKeyName="%$KEY%"^
sValueName="%$VALNAME%"^
uValue="%VAL%"^
&& echo Success.||echo failed.
endlocal
To select another registry-hive, the value of hDefKey must be changed accordingt to this MSDN-Article.
Other Methods for different value types which can be used instead of SetDWORDValue can be found there as well.

windows batch sqlite backup firefox history

Not familiar with windows stuffs.. , I'm trying to write a little MS Windows batch in order to backup firefox history but I'm not getting the expected result, eg the firefox history dump into a file (not implemented here), and can't figure out why and how to solve. Instead I get a dump of the database in a new window. Here is what I've done till now :
cmd windows terminal
start "TEST" sqlite.cmd
sqlite.cmd
REM backup firefox history
setlocal
set DB_src=places.sqlite
set DB_dest=places1.sqlite
set FF_profile=C:\Documents and Settings\User_A\Application Data\Mozilla\Firefox\Profiles\1e6xxxxx.default
set SQLITE_EXE=C:\Documents and Settings\Admin_User\SoftWare\sqlite3.exe
set SQLITE_SQL=C:\Documents and Settings\Admin_User\Bureau\sqlite.sql
copy "%FF_profile%\%DB_src%" "%FF_profile%\%DB_dest%"
#echo off
start "%SQLITE_EXE%" "%FF_profile%\%DB_dest%" < "%SQLITE_SQL%"
endlocal
sqlite.sql
.dump html
.output moz_places.html
SELECT moz_places.visit_count, moz_places.url FROM moz_places ORDER by visit_count DESC LIMIT 20;
[EDIT]:
Worked around :
- using the right sqlite query (updated in sqlite.sql below)as for these examples.
- using the sql html output "moz_places.html" as I could not get the redirection work.
linux stuffs are easier for me...
This question is lame, because it involves three completely unrelated domains: firefox, sqlite, and batch files. You should have isolated the problem by determining whether this is a firefox issue or an sqlite issue or a batch file issue and then you should have come up with a question regarding the domain in which the issue lies, with absolutely no mention to the other domains.
I am going to give you an answer as best as I can regarding batch files:
First of all, you need to stop needlessly using the start command and just invoke things directly. So, instead of:
start "%SQLITE_EXE%" "%FF_profile%\%DB_dest%" < "%SQLITE_SQL%"
You need this:
"%SQLITE_EXE%" "%FF_profile%\%DB_dest%" < "%SQLITE_SQL%"
Then, you need to redirect the output of the above command into a file of your choice. For this, you need to make use of the '>' operator. So:
"%SQLITE_EXE%" "%FF_profile%\%DB_dest%" < "%SQLITE_SQL%" > myfile.txt
That should do it, as far as batch files are concerned. If it does not do it, then it is a firefox or sqlite issue.

Resources