Archive: Closing DOS boxes


Closing DOS boxes
  I have created a DOS batch file that calls (and passes the parameter %0 - the batch file name) to a utility created by NSIS, this utility does not stay open after finishing what it is doing, but in some systems the DOS box stays open. I have been including a PIF file that basically just has the "Close on Exit" option selected. Is there any way my NSIS-created utility can close the DOS box since it already knows the name of the batch file? I want to have a total of two files instead of three.


since you know the name of the batch file you can do a findwindow for that name. It will return the hwnd. You can then use SendMessage to send the WM_CLOSE command. I'll put together an example


Thanks dselkirk. By the way, the name of the batch file is not always the same (just in case you are working on an example).

Also someone told me if I have an exe (ie myapp.exe %0) as the last line of the batch file, the batch file won't close until the exe has closed. Is this always true? I made a test batch file which calls an exe, I then added a message box in the exe and when the batch file was run, the message box popped up, after a couple of seconds the DOS box closed by itself.


how much work is this batch file doing?


Here is what the batch file may look like:
====================
@echo off
cls

goto batchcode
[inisettings]
configfile=config4.ini
configtype=1
configname=testing.123

:batchcode
copy %1 test.123
utility.exe %0

:end
====================

A third-party program calls this batch file and passes it some data as a parameter (copy %1 test.123). Then utility.exe is called passing it the name of the batch filename (with the %0 parameter). Utility.exe (made with NSIS 1.98) then reads the batch file values in the inisettings section. Finally utility.exe detects our application directory and launches our application passing it as parameters the values it read from the inisettings section.

I have been dropping a Pif file with the "Close on exit" flag enabled. I want to close the DOS box without using a Pif file.

I hope my explanation makes sense. Thanks.


do you need any return from the batch file?


What do you mean?


do you need to wait for the dos box to close to complete the task?


was just checking CVS and found a new contrib. nsExec. Heres the description.

nsExec will execute command-line based programs and capture the output
without opening a dos box.

This could solve your problem.


But it is the batch program that executes NSIS here ;)
If you ask me, there is nothing you can do with a batch file and can't do with NSIS. I think you should just move it all into the NSIS utility.exe file.


the other option is to use an executer program which sets the title of the window. Then he can us findwindow to close it.
Here's one: http://www.naughter.com/shelexec.html

The best solution would be to have it in the utility.exe. No need to close anything.


Here's a smaller one. 14.5kb.

shellexec file.bat

it will launch the batch file. the window title will be that same as what you passed as the batch file. Now you can use findwindow.


I still need to give it a try. The reason I don't just have NSIS do everything is because some of the third-party software requires us to use a batch file. I want the exe to be the same across all products, that means whatever changes between the products must come from a batch or ini file. My goal is to just use 2 files instead of 3.


a little dll could be interessant to develop that would allow us to launch a DOS app without making a DOS windows visible ! I mean, if we want to use DOS commands that do not show anything, that could be great !
does anyone knows how to do that ?



nsExec::Exec "cmd /C copy c:\*.* d:\"

nsExec::ExecToLog "
cmd /C dir c:"
>

If I understand correctly, using shellexec.exe would mean having to use 3 files: The batch file, the NSIS exe and shellexec. The whole idea was being able to close the DOS box (if possible) from within the NSIS executable.


try

start utility.exe %0
in your batch file

Does this work in all Win32 Systems?

start utility.exe %0

I just found something that may do the trick, it only mentions Win 95 so some testing under other operating systems is needed:

Microsoft Knowledge Base Article - Q122514

Here is the relevant part:
If you are running a batch file, you can close the MS-DOS window by adding the following lines to the end of the batch file:
echo off
cls

Originally posted by cchian
Does this work in all Win32 Systems?
afaik yes
test.bat
notepad
test2.bat
start notepad
in the first example the box closes after you close notepad, in the second example the box closes immediately

the msdn example is for 16 bit dos commandline apps that write output to the screen, command.com in win9x doesn't close the box in this case - that's why the fix
cmd.exe always closes the box for both 16 and 32 bit commandline apps (fix unneeded)

I suggest you use ShellExec instead of start, it is the same and ShellExec doesn't show a dos command box for everything.


kichik, does the ExecShell support SW_HIDE? If it does then that cab solve the problem right there. no third file required.


Sure, you can use SW_SHOWMINIMIZED with ExecShell. Same as Sw_HIDE.


But doesn't SW_SHOWMINIMIZED still display the window. From what i understand the issue is that a dos window has just hasn't self closed. If we hide the window using SW_HIDE it won't matter if it hasn't closed yet. The simplest solution to the problem.


You can't hide the window completly with WS_*, nsExec is the best solution.


does nsExec support environment variables


What do you mean by "support environment variables"? If you mean nsExec::Exec "%HOME%\asd.exe" ExpandEnvStrings should do the trick.
Just to make it clear:
To run a DOS program use nsExec.
To run every other program that doesn't have any dos box opened for it just use Exec, ExecWait or ExecShell.


but, what about batch files.


batch files are dos programs, where's the problem?


How about reading the batch file using FileRead and execing each line if you don't create the batch file yourself.


unfortunately that will only work if there are no tests/branches/other batch file specific commands in the batch file... nice idea tho, wouldn't have thought of it myself