WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

DOS

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Discussion on Identifying Process IDs of DOS Windows

Keywords: 	   Identifying Process IDs DOS Windows

Question:

I need to control a DOS program with WinBatch. My customer uses a DOS accounting program and has no motivation to switch.

Why doesn't this program work? Why is the Actual Window ID different in the second .WBT file?

How do you control a DOS program with WinBatch? I need to make sure the window is maximized, not iconized. I also need to determine when the DOS window is closed so that I can shut down Windows 95.

The solution must use documented calls and must work in Windows NT. The test below was done with Win 95 OSR2.

The idea of the program below was to find the DOS window ID in the beginning, and use it until the window is closed. This would be useful, since the DOS window title changes each time a line is executed.

But, the ID changes. The behavior of WinIdGet() is not completely explained in the manual.


BATCH FILE SS.BAT:
------------------------------------------------------------------------------
c:\"program files"\winbatch\system\winbatch.exe c:\progra~1\winbatch\gm\FindID01.wbt "SsID"
PAUSE
c:\"program files"\winbatch\system\winbatch.exe c:\progra~1\winbatch\gm\ZoomRemt.wbt "SsID"
PAUSE
EXIT
------------------------------------------------------------------------------


WINBATCH SCRIPT FindId01.WBT:
------------------------------------------------------------------------------
OutputFile = param1
sWinId = WinIdGet( WinName() )
nHandle = FileOpen( OutputFile, "WRITE" )
jj = FileWrite( nHandle, sWinId )
Message( "sWindId in FindId01 = ", sWinId )
Message( "Actual sWindId in FindId01 = ", WinIdGet( WinName() ))


WINBATCH SCRIPT FindId01.WBT:
------------------------------------------------------------------------------
sWinName = WinIdGet( WinName() )
InputFile = param1
nHandle = FileOpen( InputFile, "READ" )
sWinId = FileRead( nHandle )
Message( "sWindId from file in ZoomRemt = ", sWinId )
Message( "Actual sWindId in ZoomRemt = ", sWinName )
YIELDS(1)
WinZoom( sWinId )

Answer:

It seems the main problem you might be having is that you are getting the WinID of the WinBatch window itself, not the DOS window you are trying to control.

There are three parts here. The DOS BAT file that starts the WinBatch program. The WinBatch program that calls the WIL interpreter, and the WIL interpreter itself.

The WinName function is returning the name of the WinBatch window, not your DOS window.

You can set your DOS window title and open properties (full screen ,etc) my making a shortcut to it. (manually)

I suggest using the START /w infront of your calls to the WinBatch scripts to ensure they complete before the BAT file continues.

There is some question about why you are trying to run the whole process controlled by a BAT file rather than a WBT file, but it should be doable in any case.

Anyway once you have a proper WinId


properid=WinIdGet("My ACCOUNTING PROGRAM")
then you can do stuff like WinExist on it and such.

Adding


DEBUG(1)
to the tops of the scripts help, as well as an occassional

whome=WinName()
Message("WhoMe",whome)
which would have shown that WinName was not getting you the desired items.

Question:

Thank you for your very fast reply.

I would like to do everything under WinBatch control, but the DOS window must run full screen. The hardware, software, and customer require this.

Certainly it is correct that I am getting the wrong Window ID. The test program demonstrates that.

However, there seems to be no way to get the correct ID if the program is controlled by a batch file:

When I run the WinBatch script, I will always get the WinBatch script window ID, not the ID of the DOS window.

How can I get the ID of the DOS window? Remember that the title of the window changes every time a new batch statement is executed.

Even if the DOS program is controlled by WinBatch, how do I get the correct DOS ID? I don't necessarily know that a certain program is running; that is what I'm trying to control.

Answer:

Well, a lot of WinBatch works with Window titles. If you window title is essentially random, then it is going to be tricky.

If at some instant - for example immediately after is is run you gan garb the window title with WinGetActive then run it thru a WinIDGet then you should have a valid ID you can use later.

e.g.


Run("command.com","")
TimeDelay(3)
x=WinGetActive()
winid=WinIDGet(x)
Then winid should be valid.

If you have to jump into a place where a DOS window is already running, then it is trickier. If you know *something* about the window. Here are two cases.

  1. Only window with c:\ in the title
    
    ;undebugged code
    list=WinItemize()
    listcount=ItemCount(list,@tab)
    for xx=1 to listcount
    thiswin=strlower(ItemExtract(xx,list,@tab))
    if strindex(thiswin,"C:\",0,@fwdscan)!=0 then break
    next
    
    winid=WinIDGet(thiswin)
    

  2. Only DOS window open
    
    ;undebugged code
    list=WinItemize()
    listcount=ItemCount(list,@tab)
    for xx=1 to listcount
    thiswin=strlower(ItemExtract(xx,list,@tab))
    if WinIsDOS(thiswin) then break
    next
    
    winid=WinIDGet(thiswin)
    
Remember that SendKeys simply DO NOT function properly with full screen DOS windows.

If the whole point is to control a DOS window, sometimes a DOS package (can you find them anymore) works better. ProKey for DOS used to be popular. Depends on exactly what you are trying to do.

Question (cont'd):

None of the solutions given actually work on booting a system.

The first, which isn't numbered, fails because it cannot be assumed when booting that the DOS window is the active window.

The second, numbered 1, makes an assumption about the name of the window, which doesn't work because the name of the window changes when the batch file is run.

The third, numbered 2, makes an assumption that only one DOS window is running.

Is there a sure way of finding the Process ID of a DOS window?

Also, why does the following code, re-written from the last suggestion, fail? WinExist is always false.


; ----------------------------------------------------------------------------
; This loop waits until a DOS program is loaded.
; It assumes that there is only one DOS program 
; loaded at the point it is run.
DEBUG( @ON )
While @TRUE
sWinList = WinItemize()
nListCount = ItemCount( sWinList, @tab )
FOR nn = 1 TO nListCount
sWinName = StrLower( ItemExtract( nn, sWinList, @tab ) )
IF WinExist( sWinName )
IF WinIsDOS( sWinName )
BREAK
ENDIF
ENDIF
NEXT
EndWhile
; ----------------------------------------------------------------------------

Answer:

Window names are case sensitive. There is a strlower in the script forcing the obtained window name to lower case...and thus it fails the WinExist check.

It looks like you are planning to enumerate the DOS windows to eventually find the WinID you need.

If you have multiple DOS windows with random names it is going to be tricky. But it would seem like there would be substrings in the various presented names that would be unique to the application you are trying to control and could be used to identify the window.

Question (cont'd):

It seems to me that WinBatch needs a RUN() command which returns the Process ID. I seem to remember that Win32 has a call called SPAWN() which starts a DOS window and returns the window handle.

You said, "It looks like you are planning..." I don't have any plans, because I don't know how to solve the problem.

You said, "It would seem like there would be substrings in the various presented names that would be unique to the application you are trying to control and could be used to identify the window." This idea doesn't work if for some reason the application doesn't run. In an office environment there are numerous reasons why the application might not load. It would not be sensible to lose control at that point.

It seems to me that this is a matter which requires top management attention. There are many DOS accounting programs which work fine and with which people only do data entry. The customers will not upgrade to a windows version, and sometimes there isn't one available.

Are you in a position to ask that a command be added to WinBatch?

Answer:

I could not find an reference to SPAWN or any other function in the Win32 API that would execute a program and return a window handle.

It would be nice, but the Windows API does not provide an unambigious mapping from an program to a window.

For 32-bit applications we can track back from a window name to an exe, but for 16 bit apps or console (DOS) windows it just stops at some point.

I'm pretty good at relaying suggestions from users to our developers....

Question (cont'd):

Thanks for looking for the API.

You said, "Remember that SendKeys simply DO NOT function properly with full screen DOS windows."

There are references in the help messages to using SENDKEYS() with full screen DOS windows. In what situations does SENDKEYS() work, and when does it fail?

Please help me keep this project out of the research mode. I hoped to have a script in perhaps 2 hours at the most, and many hours later I am still uncertain even how to accomplish the task.

I think that all we have talked about should have been documented. The technical support files definitely give the impression that it is possible.

The possibilities and limitations of working with DOS should be clearly documented, with examples given. As it is, the user is merely led unexpectedly into a maze of problems.

I was counting on the tech support documents as helpful, but the quote above seems to take away any support for what is written.

The tech support files say that it is possible to use SENDKEYS() to write to a full screen DOS window, but only that it is not possible to send the ENTER key.

Answer:

The ENTER key, generally being a fairly important key when attempting to control DOS windows is the usual killer when attempting to control a DOS window and it forces the use of the Windowed DOS application.

I'm not exactly sure what other keys work and don't work, but I seem to recall that all the standard characters, numbers and punctuation work, but that F1-F20 and ALT versions of the keys don't work.

It seems that after seeing *some* important characters can never work, it was simply recommended that you avoid the Full screen DOS windows altogether, and that comprehensive testing of each and every character combination was not performed.


- - - 
I am unaccustomed to the concept of defining a problem 
around the abilities of a tool, but am rather more
used to determining what I want to do then figuring 
out how to force some collections of tools to do the
task.

- - -
It has been my experience that DOS-based TSR macro recorders can often give superior keystroke sending performance to DOS apps. A number of "pacing" problems are also eliminated, as the TSR and DOS program run in lockstep as opposed to the multitasking nature of windows.

There have been cases where users fir off some keystroke like ^P to a DOS app/recorder combination, the recorder sees the ^p and institutes a long serives of keystrokes.

I cannot recall if the DOS programs have the same ENTER and other key limitations.

Question (cont'd):

I don't know what you mean by, "I am unaccustomed to the concept of defining a problem around the abilities of a tool, but am rather more used to determining what I want to do then figuring out how to force some collections of tools to do the task."

I consider this a very serious issue: No one, apparently, has worked out how to reliably determine the process ID of a DOS batch file window using WinBatch. This means that every user who wants to control a DOS window must struggle with this issue separately. Over nine years of the existence of WinBatch, this must have been a lot of struggling.

Apparently it is possible to use WinBatch to take a DOS window from full screen to window and back again. Is that correct?

If that is correct, then there should be a reliable method of determining the process ID. The process ID is all-important, because it is the only handle by which WinBatch can control a DOS batch file.

Suppose, for example, a user tries to use WinBatch to run a DOS program, and the program fails for some reason. The only way to determine what happened under program control is to examine the exit errorlevel. The errorlevel is only available to a DOS batch file. Therefore, reliable identification and control of batch files is important to the use of Winbatch to control DOS programs.

There are many legitimate reasons for using DOS windows. For example, some utilities for windows NT are DOS programs. This is not a dead issue.

It seems to me that poor documentation of something so important threatens the health of your company.

These are not comments which are intended to reflect on you personally in any way.

Notice that I have posted a file elsewhere which contains all the command-line parameters for starting Netscape Navigator and other Netscape Communicator programs. This information might be useful for someone trying to control Netscape programs with WinBatch. The information is available in the Netscape Help, but having it formatted and easily available saves time.

Answer:

I am used to processID's under Unix. Everything there is pretty much based on the processID.

The concept sort of exists in Windows but is quite buried, and is not generally used by anything except the operating system itself.

WinBatch generally uses window titles to keep track of various windows, and the focus is more toward talking to various windows rather than to an application.

A WinID function exists to get a window handle which can be used instead of a window title in cases where applications may change the window titles.

The whole system is more or less based on the ability to predict Window titles. There are instances where using WinGetActive after a program launch you can grab the then current window title and hope it is the correct one.

The window titles of DOS BAT file and DOS programs can usually be set in the shortcut associated with the DOS BAT file or program.

There has been added in recent versions the ability to get the DOS errorlevel code back into WinBatch without a BAT file. IntControl (64.....) However it does require the use of some version of RunWait.

I haven't tried to flip a DOS window from maximized to full screen and back again for quite some time. However I do recall that it was done by simply sending the same keystroke combination as one would type to do it.


SendKeyTo("My DOS Window","!{ENTER}")
ought to do it. I haven't tried this in any modern version of Windows. I also recall there was some difficulty in determining the state of a DOS window. If WinState reports @ICONIZED it could mean really iconized or it could mean full screen.

PS. FullScreen dos/console apps only exist on the WinTel platforms. Other platforms running NT (Dec Alpha, Mips, Power PC) prohibit full screen dos/console apps.

PPS. For detailed documentation about Windows, keystrokes, registry settings and all sorts of related stuff, we generally recommend the Microsoft 95/98/NT Resource kit.

Question (cont'd):

This discussion has revealed a huge and easily corrected flaw in WinBatch.

You say, "The whole system is more or less based on the ability to predict Window titles. There are instances where using WinGetActive after a program launch you can grab the then current window title and hope it is the correct one."

This is exactly right, of course. But there are numerous heartaches for the user in "hoping it is the correct window".

The title may change during program execution, as with batch files. The user may get the case of the title wrong, or put in a space where it shouldn't be, or forget that the title was changed, or change the title in one part of the program and not realize that it should be changed elsewhere.

Also, there is extreme ambiguity when there are two or more instances of the same program.

Basing program execution on window title is one of the most time-consuming areas of WinBatch programming. There are so many hassles for the user which aren't mentioned here. For example, if the user, or someone, upgrades a program which is under WinBatch control, and the upgrade uses a different title, the WinBatch program breaks!!!!! This example shows how unnecessarily fragile WinBatch programs are.

You say, "I am used to processID's under Unix. Everything there is pretty much based on the processID.

"The concept sort of exists in Windows but is quite buried, and is not generally used by anything except the operating system itself."

I don't understand this. The concept is not buried. WinBatch's WinIdGet() function shows that WinBatch developers are aware of the Windows process ID.

The problem is that the RUN() functions return only TRUE or FALSE. The RUN() functions should return the process ID, or the null string if the program is not found.

I understand that it might not be politically correct for you to agree with this: Basing program execution on window title is a huge flaw in WinBatch. Something should be done about correcting the flaw immediately.

Answer:

The WinID is not a ProcessID. It is a Window ID.

A given program is allowed to make as many different windows as it likes. Having a "ProcessID" does not necessarily allow you to find the window the user is interested in.

It is a one to many problem. One Process could be in charge of may windows. However each window is only owned by one process.

Even if a ProcessID were specified with each command, there would still need to be information about what window to send data to.

Interjection:

The actual problem to solve seems very unclear in this thread. Why aren't you launching the dos applications from a winbatch script, and thereby increasing your likelihood of finding the correct window? Just store the WinItemize before running, go into a loop for a reasonable amount of time, checking a new WinItemize, for a new, DOS, window. If it fails after x seconds, the startup failed. You can get the WinID then.

Also, why is the window title changing unpredictably? I don't know any applications that make up random letters for a window title each time; surely there is some constant or predictable pattern.

Question (cont'd):

You said, "thereby increasing your likelihood of finding the correct window". I don't want to play a game of chance. I need a sure way of knowing the Window ID so that the program will be reliable.

Whether it is a process ID or window ID is not the issue here; being able to write a reliable program is. Each DOS instance has only one window. So in DOS under windows the process ID refers to the correct window.

I need a way of solving this problem.

Another Interjection:

You should treat the problems of working with DOS sessions under windows as insoluble and find another solution. Full screen sessions are almost totally impossible to work with, and even windowed DOS sessions are problematic. This is not the fault of the Winbatch product, but of the limitations of DOS session support in the windows environment. I have worked with VB and VC++ programmers over the years, and this remains a constant problem that has taxed the massed intelects of many skilled people over the years, resulting in a selection of "kludges" crafted by hand to suit each particular scenario. You need to find the best solution that you can live with for your environment, however kludgy, and go with it. There is no magic solution to be found here.

Question:

Many thanks for your comment on the WinBatch WebBoard. The key issue being discussed is explained below, under the heading WebBoard Thread.

I don't understand your comment. My understanding is that WinBatch can reliably move a DOS window from Full Screen to Windowed and back, and can reliably send the letter characters to a Full Screen DOS window. Marty Williams in Tech Support told me that. Therefore, it should be possible to move the DOS window from Full Screen to Windowed if it is necessary to control a DOS window with characters which cannot be sent to a Full Screen DOS window.

WebBoard Thread -- A very, very important issue is being discussed in the WebBoard thread: The WinBatch RUN() commands do not return the Window ID.

This Window ID is always available and always usable inside WinBatch. It is possible to obtain it using the WinGetID() function. Once you have it, you can use the Window ID in ALL functions which use a partial title. The Window ID returned by WinGetID() specifies the window perfectly, without the ambiguity caused by having multiple instances of a program with the same title, and the ambiguity of the DOS title changes during DOS batch execution.

In the WebBatch thread, I am trying to convince the Tech Support person that a RUN() command should be added to WinBatch which returns the Window ID. This would make programming in WinBatch easier, and would resolve all problems with Window titles and uncertainty about which Window was being accessed.

Answer:

The solution appears to be a modification of the RunShell function so that when the @NOWAIT parameter is specified it would return a special code.

This code could then be used in a new function (yet to be named) that would return a tab delimited list of WinID's associated with that particular instance of the program run. In most cases only one WinID would be returned.


Article ID:   W12879
Filename:   Discussion on Identifying DOS Process ID Window.txt
File Created: 2013:06:19:15:12:28
Last Updated: 2013:06:19:15:12:28