reg.exe stays on process list after executing by WinExec() - c++

I have a problem similar to:
Using Java runtime to add registry key, cause process reg.exe to run forever
But I'm using C++ and WinExec() and I don't know how to use the solution that has been given there for Java in my code.
My code is:
int result =
WinExec("CMD.EXE /C REG ADD HKEY_LOCAL_MACHINE\... /v Data1 /t Reg_SZ
/d \"cmd.exe /C ...\"", SW_HIDE);
I have tried to change it to:
int result =
WinExec("CMD.EXE /C REG ADD HKEY_LOCAL_MACHINE\... /v Data1 /t Reg_SZ
/d \"cmd.exe /C ...\" > 0", SW_HIDE);
But it gives me the same result.
So how to "consume" the process' output and close all streams in proper way? I guess CMD.EXE stays alive as well after executing (0% CPU, egists forever).

Basing on comments under my post, I checked if reg.exe is sitting a prompt and that was the point!
I added /f option for REG to confirm silently:
int result =
WinExec("CMD.EXE /C REG ADD HKEY_LOCAL_MACHINE\... /v Data1 /t Reg_SZ /f
/d \"cmd.exe /C ...\"", SW_HIDE);
Thank you Marc B and Raymond Chen :)
I am using existing code with about 1k lines that contains WinExec("...") so I did not really wanted to rewrite them all to RegSetValueEx and others (not only REG is called that way).

Related

Batch File If Statements causing close of CMD and not working

I am creating a should-be-simple batch file that will allow me to input a class name and it will take me to the correct google classroom. However, my if statement doesn't work, even when I input the word "Social Studies". It does not take me to my classroom, and on top of that, the CMD is just closed. When I remove the If Statement line, the code works fine and the cmd just stays open after inputting a class.
set /p class="Enter Class: "
IF "%class%" /I EQU "Social Studies" (START https://classroom.google.com)
cmd /k
IF /I "%class%" EQU "Social Studies"...
The parsing logic for an if statement is very specific; if [/i][NOT] arg1 op arg2 where /i and not are optional, but must if used, be used in that order.
Your code sees /i where it expects a comparison-operator and generates a syntax-error.
When you use the point-click-and-giggle method of executing a batch, the batch window will often close if a syntax-error is found. You should instead open a 'command prompt' and run your batch from there so that the window remains open and any error message will be displayed.
You can write #echo off whice prevents the prompt and contents of the batch file from being displayed.
I replaced the your EQ with == and now it works:
#echo off
set /p class="Enter Class: "
IF "%class%"=="Social Studies" (START https://classroom.google.com)
PAUSE
The PAUSE at the end will make the CMD remain open after it's done

Using batch to read a certain section of a file and create a variable

I've read a lot of things and I can't find away of doing this that I understand. This might be because I'm a wee newbie though.
What I'm trying to do is:
I have a file called start.txt with the contents
..\dll | toapp.exe "..\posdata\filename.xml" "..\OUT" "..\TEMP"
I want to read the contents of that in a batchfile and take only filename.xml as a variable. From device to device inside the network it changes.
I'm then going to use that variable to copy a file from 1 machine to another but I only want that one file and I can't be sure what it's called without looking in the start.txt. I can do all the copy and checks to make sure it's looking in the correct places but just not the findstr section.
Any idea of what to do to understand would be fantastic
#echo off
set "start_file=start.txt"
for /f tokens^=5^ delims^=\^" %%# in ('type "%start_file%"^|find /i "..\posdata"') do set "xml_file=%%#"
echo %xml_file%
Your question is a little bit unclear.Is this the only line in the file? Is this the exact content? How can I recognize the line with the file?
The script above will work in case there's only one line wwith "..\postdata" string and the content is exact as described in question.
Edit Covering the both cases:
#echo off
setlocal
set "start_file=start.txt"
set "xml_file="
for /f tokens^=5^ delims^=\^" %%# in ('type "%start_file%"^|find /i "..\posdata"^|find /i /v "-storedbpath"') do set "xml_file=%%#"
if not defined xml_file (
for /f "usebackq tokens=9" %%# in ("%start_file%") do (
set "xml_file=%%~#"
)
)
echo %xml_file%
Text this:
for /f "usebackq tokens=4" %%a in ("start.txt") do echo %%~nxa

Batch Script Input Problems

I have two questions regarding a batch script I'm working on. I realize that batch script questions are common but haven't found an answer to my exact question so I thought I'd try asking. The problematic areas are the user input sections on the menus.
There are two problems: 1) Input entered that is not one of the specified choices will cause the script to jump to random areas. And 2) some sections that use external programs are not taking the user %input% even when I know the syntax and flag use would normally be correct (as in, I can run them manually... so for some reason the input isn't capturing on them).
First issue example:
:MenuOne
echo Select one of the following options:
echo 1) x
echo 2) y
echo Q) Quit
set INPUT=
set /P INPUT=[1,2,Q]: %=%
If "%INPUT%"=="1" goto xoption
If "%INPUT%"=="2" goto yoption
If /I "%INPUT%"=="Q" goto Quit
:xoption
#REM Here goes a lot more submenus and/or options that actually run tools via cmd.
:yoption
#REM Again, menus and/or tools being invoked, in a listed menu, designed like above.
:Quit
echo Quitting...
exit
If a user types "b" at the selection prompt, I would love for the script to give an error and repeat the menu. Instead it jerks around other menus. I'm guessing that I need some ELSE statements? Does anyone have an example that I can use to accomplish this?
Second issue of some commands not using the %input% properly and returning an error as though it never received the %input%.
set /P INPUT=[Testone Input]: %testone%
set /P INPUT=[Testtwo Input]: %testtwo%
commandtorun.exe -f %testone% -h %testtwo%
Thanks!
Better to use choice (http://ss64.com/nt/choice.html) because it will persist until you set the correct input
CHOICE /C XYQ /M "Select of the following options [X,Y,Q]"
if errorlevel 1 goto :x
if errorlevel 2 goto :y
uf errorlevel 3 goto :q
Yet it's still possible to be done with IFs
set INPUT=
set /P INPUT=[1,2,Q]: %=%
If "%INPUT%"=="1" goto xoption
If "%INPUT%"=="2" goto yoption
If /I "%INPUT%"=="Q" goto Quit
rem -- will be executed only if the all the above are not true
goto :eof
For the second problem..You are not using SET /P correctly (the name of the variable should be in the front) , or you are trying something that I don't understand (where input variable is used):
set /P testone=[Testone Input]:
set /P testtwo=[Testtwo Input]:
commandtorun.exe -f %testone% -h %testtwo%
In your program as written, all your choices will fall through to the next one. If no relevant choice is entered, it will run :xoption and :yoption. Each of those should probably return to the menu after executing:
:MenuOne
echo Select one of the following options:
echo 1) x
echo 2) y
echo Q) Quit
set INPUT=
set /P INPUT=[1,2,Q]: %=%
If "%INPUT%"=="1" goto xoption
If "%INPUT%"=="2" goto yoption
If /I "%INPUT%"=="Q" goto Quit
echo Invalid selection.
echo.
goto MenuOne
:xoption
#REM Here goes a lot more submenus and/or options that actually run tools via cmd.
goto MenuOne
:yoption
#REM Again, menus and/or tools being invoked, in a listed menu, designed like above.
goto MenuOne
A real simple way to ensure a valid selection is made is to use the choice command instead of set /P. That will force the user to enter a value:
choice -c 12Q
echo %errorlevel%
The choice command will return the index of the selected character (1, 2 or 3 in the above example). A bonus is that it is case-insensitive, so you don't have to worry about checking both Q and q.

Changing a registry value with C++? (system command failed)

Well, I have been told time and time again that system command is bad, but I need to change a registry value and my forte is batch so I have a commmand in mind that does it:
system("REG ADD "HKCU\Control Panel\Desktop" /V Wallpaper /T REG_SZ /F /D "C:\background.bmp"");
system("REG ADD "HKCU\Control Panel\Desktop" /V WallpaperStyle /T REG_SZ /F /D 0");
system("REG ADD "HKCU\Control Panel\Desktop" /V TileWallpaper /T REG_SZ /F /D 2");
system("%SystemRoot%\System32\RUNDLL32.EXE user32.dll, UpdatePerUserSystemParameters");
However, using this makes Visual C++ 2010 Express highlight HKCU and the slash betweeen Panel and Desktop as an error and does not allow me to compile or debug my program. I don't want to use the system command so I was wondering how to use a C++ to preform the same registry command?
I DON'T UNDERSTAND WIN32 REGISTRY API???
And is it ok to use the system command for this
system("%SystemRoot%\System32\RUNDLL32.EXE user32.dll, UpdatePerUserSystemParameters");
because I don't know if C++ can preform the same task without it, and if it can how???
Sorry, I know it's a big question but if possible could you please include code, I am just beginning and none of the other forums make any sense and I have been looking for atlease three hours (I am not stupid with computers either)!!!
Thanks in advance
Please use the Win32 Registry API!!!
Some extra work is needed to write string literals that contain special characters. For example, in your code, the " after ADD is the end of the string.
You need to put a backspace before each special character (includes quotes and backspaces) to make sure they are put into the string instead of being processed by the compiler. This is called escaping.
The result will look like this:
system("REG ADD \"HKCU\\Control Panel\\Desktop\" /V Wallpaper /T REG_SZ /F /D \"C:\\background.bmp\"");
Using the Registry API is a better option for your task, of course, but you also needed to know how to write string literals properly.

trying to write if, else statement and detect keypress

Hi I'm trying to write a batch file that when it gets to that area of the code waits for 10 seconds and then if a certain key is pressed exits, otherwise it goes to another area of the code.
Here is what I got so far
SLEEP 10
IF
exit
else if
goto start
sorry, I don't know if this is correct. I'm just learning Lua and while similar to DOS they aren't quite the same. If anyone can fill in the gaps and fix the mistakes I would much appreciate it. The key I want to be pressed is either any or a specific key ID which
You can do this in batch using this
#echo off
choice /c abcd /n /t 5 /d d
if %errorlevel%==1 echo You chose a
if %errorlevel%==2 goto :CONTINUE
if %errorlevel%==3 echo You chose c
if %errorlevel%==4 exit >nul
:CONTINUE
REM Continue code
pause >nul
Usage:
In this script your options are a, b, c, and d.
Use the %errorlevel% with incrementing numbers to get the choice selected.
The /t switch is the timeout in seconds, in this it is 5 seconds.
The /d switch is the default option, use this to automatically make a choice if the command times out. In this case d will be the time out choice, which will exit the script.
Just tweak to fit your needs.