Link to home
Start Free TrialLog in
Avatar of Clinton112299
Clinton112299

asked on

Impossible to figure out "CreateProcess"

Hello,
I have been working on a project that uses Builder C++ with Windows 95\98. The program is to set up with Tabs, and on each tab there are several buttons. Each button is use with CreateProcess() that opens the called Dos program. The CreateProcess works fine opening the Dos program and I can go though the various menus. I have found out that the Dos program doesn't work correctly with the Com ports. To test this I have closed the C++ and dos program. I than went into Windows Explorer and opened the same Dos program. The Dos program works fine this way. Why doesn't the Dos program com ports work correctly from CreateProcess(). I have read that Windows blocks this and I require a Stub that will redirect the Dos program or something like that. I guess my question is how can I open the Dos program without Windows giving me this problem. Can someone Please give me Help on this? I've been trying to figure this out for Weeks without luck. I even tried to Call a Batch File from CreateProcess which than Call the Dos program. This worked to a point. Once I closed the Dos program, the com ports stayed opened. I look forward in hearing from you.

Things I tried:
ShellExecuteEX().
Spawnlp().
CreateProcess().
Batch File.

Thanks
Clinton
 
This is one of the CreateProcess I tried:

void __fastcall TFormMain::ButtonAdj10Click(TObject *Sender)
{
 STARTUPINFO si;
 PROCESS_INFORMATION pi;

 memset (&pi, 0, sizeof(pi));
 memset (&si, 0, sizeof(si));

 si.cb = sizeof(si);
 si.dwFlags |=STARTF_USESHOWWINDOW;
 si.wShowWindow|=SW_SHOWNORMAL;

 if ( ! CreateProcess(
            NULL,
            "C:\\Hi-Tech Software\\JCM\\WBA\\Adj\\adj10.bat",
            NULL,
            NULL,
            false,
            NORMAL_PRIORITY_CLASS,
            NULL,
            NULL,
            &si,
            &pi))
            {
            MessageBox(0, "Could not execte program \n Please contact software author.", "Error", MB_ICONSTOP);
            }
    {
    CloseHandle(&pi.hProcess);
    CloseHandle(&pi.hThread);
    }
}
//---------------------------------------------------------------------------
 
 

Avatar of jkr
jkr
Flag of Germany image

Use
"command.com /k \"C:\\Hi-Tech Software\\JCM\\WBA\\Adj\\adj10.bat\""

instead...

More to follow...

 
Ooops, sorry, I meant

"command.com /c \"C:\\Hi-Tech Software\\JCM\\WBA\\Adj\\adj10.bat\""

The '/c' option makes command.com execute the command and terminate when it's finished. As batch files are no executables but shell command files and a Win32 executable is needed for 'CreateProcess()', 'command.com /c file.bat' creates a console that executes the batch file. '/k' would cause the console not to close after finishing the execution... This might also come in handy if you want to redirect the output of other apps, e.g. by using 'command.com /c myapp.exe >> myapp.txt'
Avatar of Clinton112299
Clinton112299

ASKER

Sorry Jkr, but I made a mistake with the question. I have tried to use Batch but don't know if this is the correct way of doing this? I really would like to get CreateProcess to work with .exe and not .bat. But if this is the only way to get around my problem with using Dos with BUilder and the Com ports, than thanks and I will accept your question.

Thanks
Clinton
Sorry I would like to get the CreateProcess to work correctly with .exe and not .bat. Or can someone explain to me that there is no different by using the .bat file instead of the .exe.

Thanks
Clinton
JKr,
Thanks for the Ideal, but still the Com port doesn't close. I see the Dos Box open and close and the program seems to work fine. I have set the .bat properties to "Close on Exit". Could the problem be due to my Batch File? I have read that the only way to close the program is with the "Close on Exit".

Thanks
Clinton
>>Or can someone explain to me that there is no different
>>by using the .bat file instead of the .exe

See my last comment.

BTW: Of course it could be a problem with your batch file...
jkr,
I have found out that the problem with the com port is something with Windows. MSN Q130402, Q138159. It says that once a Dos program opens the com port Windows can't get it back. GREAT just what I want to hear! I CAN'T believe that Windows and Dos can't operate together. So I'm back to the question, by opening the .bat with CreateProcess is this fine to do? This is what I have for the Batch file:

@echo off
cls
C:
CD  "\Hi-Tech Software\JCM\CBA\CBATOOL"
CBATOOL.EXE

This there anything else that I should add to make this 100% fail prof.

Thanks
Clinton
You can tary PIF file.You must make
PIF file handly or programmatcally and use ShellExecute("my.pif",..).
For create PIF file you can use, too, IShellLink Interface.
I use PIF in my project ant it works perfect(nut NOT with Com ports).
If you find, that this way helps you,
i can post my programm for creating
PIF files.
Alex
Please can you Post your program for creting PIF files, and I'll try that.

Thanks
Clinton
Next is code for creating abd executing PIF File (structure of PIF see
Tom Swan: "Inside Windows File Formats", ch. 14)

typedef struct tagPIFHEADER {
  BYTE reserved1;
  BYTE reserved2;
  char windowsTitile[30];
  short maxMem;
  short minMem;
  char programFilename[63];
  short msFlags;
  char startupDirectory[64];
  unsigned short reserved[138];
}PIFHEADER;
typedef struct tagPIFDATA {
  short memKBDesired;
  short memKBRequired;
  short backgroundPriority;
  short foregroundPriority;
  short emsKBLimit;
  short emsKBRequired;
  short xmsKBLimit;
  short xmsKBRequired;
  BYTE  fFlags1;
  BYTE  fFlags2;
  BYTE  fFlags3;
  BYTE  fFlags4;
  BYTE  fFlags5;
  BYTE  fFlags6;
  short reserved1;
  short keyScanCode;
  short appKeyFlags;
  BYTE reserved2[12];
  char optionalParameters[64];
}PIFDATA;

   PIFHEADER pfH;
   PIFDATA pfD;
   FILE *fIn;
    //form Header
   memset(&pfH, 0,sizeof(pfH));
   pfH.reserved2 = 0xF0;
   pfH.maxMem = 128;
   pfH.minMem = 128;
   memset(pfH.windowsTitile,' ',30);
   char *szT = "Test";
   strncpy(pfH.windowsTitile, szT, strlen(szT));

   memset(pfH.programFilename,' ',63);
   char *sz = "pkzip.exe";
   strcpy(pfH.programFilename, sz);
   pfH.msFlags = 0x0010;
   memset(pfH.startupDirectory,' ',64);
   *pfH.startupDirectory = 0;
    //form Data
   memset(&pfD,0, sizeof(pfD));
   pfD.memKBDesired = -1;
   pfD.memKBRequired = -1;

   pfD.backgroundPriority = 1;
   pfD.foregroundPriority = 1;

   memset(pfD.optionalParameters, ' ',63);
   sz = "c:\\zip\\shopwork.zip d:\\shop\\work\\*.*";
   strcpy(pfD.optionalParameters, sz);

   fIn = fopen("my.pif", "wb");
   write(fIn->fd,&pfH, sizeof(pfH));
   write(fIn->fd,&pfD, sizeof(pfD));
   fclose(fIn);
   ShellExecute(this->HWindow,"open", "my.pif",NULL, NULL,SW_NORMAL);

Test it!
Hmm, starting the batch with the parameters that I suggested works, doesn't it?
jkr,
I haven't have time to do it yet, and I'm not sure on some of the code. Can I clear up some issurs I have, The "my.pif" will be replaced with C:\\Hi-Tech Software\\Cba\\CBAtool.bat. Also I'm not sure on this: memset(pfD.optionalParameters, ' ',63);
   sz = "c:\\zip\\shopwork.zip d:\\shop\\work\\*.*";
   strcpy(pfD.optionalParameters, sz);


 Thanks
Clinton

   
I think ,you must make

 char *sz = "\Hi-Tech Software\JCM\CBA\CBATOOL\cbatool.exe";
 strcpy(pfH.programFilename, sz);
and    
strcpy(pfD.optionalParameters, szParameters);
or
 char *sz = "C:\\Hi-Tech Software\\JCM\\WBA\\Adj\\adj10.bat";
 strcpy(pfH.programFilename, sz);
and without parameters


An easy way would be to have TWO batch files.
The first would be the one you call from windows.
The second would call your DOS program.

REM filename bat1
REM This will start bat2 in a sepparate new DOS window
start bat2

rem filename bat2
dosCOMprog

Mflam,
I'm not sure on what you mean. I currently use CreateProcess from my C++ code to open the batch file. Than in the batch file is the parameters that open the DOs program. SO how can I use two batch files?

Sorry AlexVirochovsky the PIF question was directed to you and not to jrk. ANyways I have reveiwed your question and would like to know what exactly does this code do? Does it do the exact samething as making a shortCut?

THanks
Clinton


Not exectly. My code creates PIF file
and use ShellExecute for Run it.
You can get same effect, if you create
PIF file manually(with some PIF editor) and press on it from Explorer.
Alex
THis is what I have done and these are the errors I get:

void __fastcall TFormMain::Button14Click(TObject *Sender)
{
typedef struct tagPIFHEADER {
  BYTE reserved1;
  BYTE reserved2;
  char windowsTitile[30];
  short maxMem;
  short minMem;
  char programFilename[63];
  short msFlags;
  char startupDirectory[64];
  unsigned short reserved[138];
}PIFHEADER;
typedef struct tagPIFDATA {
  short memKBDesired;
  short memKBRequired;
  short backgroundPriority;
  short foregroundPriority;
  short emsKBLimit;
  short emsKBRequired;
  short xmsKBLimit;
  short xmsKBRequired;
  BYTE  fFlags1;
  BYTE  fFlags2;
  BYTE  fFlags3;
  BYTE  fFlags4;
  BYTE  fFlags5;
  BYTE  fFlags6;
  short reserved1;
  short keyScanCode;
  short appKeyFlags;
  BYTE reserved2[12];
  char optionalParameters[64];
}PIFDATA;

   PIFHEADER pfH;
   PIFDATA pfD;
   FILE *fIn;
    //form Header
   memset(&pfH, 0,sizeof(pfH));
   pfH.reserved2 = 0xF0;
   pfH.maxMem = 128;
   pfH.minMem = 128;
   memset(pfH.windowsTitile,' ',30);
   char *szT = "Test";
   strncpy(pfH.windowsTitile, szT, strlen(szT));

   memset(pfH.programFilename,' ',63);
   char *sz = "\Hi-Tech Software\JCM\CBA\CBATOOL\cbatool.exe";
   strcpy(pfH.programFilename, sz);

   pfH.msFlags = 0x0010;
   memset(pfH.startupDirectory,' ',64);
   *pfH.startupDirectory = 0;
    //form Data
   memset(&pfD,0, sizeof(pfD));
   pfD.memKBDesired = -1;
   pfD.memKBRequired = -1;

   pfD.backgroundPriority = 1;
   pfD.foregroundPriority = 1;

   memset(pfD.optionalParameters, ' ',63);
   sz = "C:\\Hi-Tech Software\\JCM\\CBA\\CBATOOL\\cbatool.exe";
   strcpy(pfD.optionalParameters, sz);

   fIn = fopen("my.pif", "wb");

//FIRST ERROR
   write(fIn->fd,&pfH, sizeof(pfH));
   write(fIn->fd,&pfD, sizeof(pfD));
   fclose(fIn);

//SECOND ERROR
   ShellExecute(this->HWindow,"open", "my.pif",NULL, NULL,SW_NORMAL);

}

[C++Error] MainMenuSource.cpp(1266): Call to undefined function 'write'.
[C++Error] MainMenuSource.cpp(1269): 'HWindow' is not a member of 'TFormMain'.
It is code for BC. For BCB change:

>>   write(fIn->fd,&pfH, sizeof(pfH));
>>   write(fIn->fd,&pfD, sizeof(pfD));
to
 fwrite(&pfH, sizeof(pfH),1,fIn);
 fwrite(&pfD, sizeof(pfD),1,fIn);
and >>   ShellExecute(this->HWindow,"open", "my.pif",NULL, NULL,SW_NORMAL);
to
 #include <shellapi.h>//in begin

   ::ShellExecute(this->Handle,"open", "my.pif",NULL, NULL,SW_NORMAL);
Alex
Alex the program complies but it can't find my program? It says that that it can't find the path C:\Hi-Tech Menu\my.pif". Am I that blind that I figure out what's happing!

Thanks for you time on this
Clinton

fIn = fopen("my.pif", "wb");
   fwrite(&pfH, sizeof(pfH),1,fIn);
   fwrite(&pfD, sizeof(pfD),1,fIn);

   fclose(fIn);
   ::ShellExecute(this->Handle,"open", "my.pif",NULL, NULL,SW_NORMAL);


1.If ShellExecute can 't find file
  "my.pif" : test you code, where is file, may be must set full path to file and so on...
2. If PIF file can't find you programm  
test field
pfH.programFilename. For example
>>   char *sz = "\Hi-Tech Software\JCM\CBA\CBATOOL\cbatool.exe";  <- error
must be
char *sz = "\\Hi-Tech Software\\JCM\\CBA\\CBATOOL\\cbatool.exe";

Alex this is what I've done, it opens that Dos program but I can't get the com ports to work with it?

Clinton

//---------------------------------------------------------------------------
void __fastcall TFormMain::Button14Click(TObject *Sender)
{
typedef struct tagPIFHEADER {
  BYTE reserved1;
  BYTE reserved2;
  char windowsTitile[30];
  short maxMem;
  short minMem;
  char programFilename[63];
  short msFlags;
  char startupDirectory[64];
  unsigned short reserved[138];
}PIFHEADER;
typedef struct tagPIFDATA {
  short memKBDesired;
  short memKBRequired;
  short backgroundPriority;
  short foregroundPriority;
  short emsKBLimit;
  short emsKBRequired;
  short xmsKBLimit;
  short xmsKBRequired;
  BYTE  fFlags1;
  BYTE  fFlags2;
  BYTE  fFlags3;
  BYTE  fFlags4;
  BYTE  fFlags5;
  BYTE  fFlags6;
  short reserved1;
  short keyScanCode;
  short appKeyFlags;
  BYTE reserved2[12];
  char optionalParameters[64];
}PIFDATA;

   PIFHEADER pfH;
   PIFDATA pfD;
   FILE *fIn;
    //form Header
   memset(&pfH, 0,sizeof(pfH));
   pfH.reserved2 = 0xF0;
   pfH.maxMem = 128;
   pfH.minMem = 128;
   memset(pfH.windowsTitile,' ',30);
   char *szT = "Test";
   strncpy(pfH.windowsTitile, szT, strlen(szT));

   memset(pfH.programFilename,' ',63);
   char *sz = "C:\\Hi-Tech Software\\JCM\\CBA\\CBATOOL\\cbatool.exe";

;
   strcpy(pfH.programFilename, sz);

   pfH.msFlags = 0x0010;
   memset(pfH.startupDirectory,' ',64);
   *pfH.startupDirectory = 0;
    //form Data
   memset(&pfD,0, sizeof(pfD));
   pfD.memKBDesired = -1;
   pfD.memKBRequired = -1;

   pfD.backgroundPriority = 1;
   pfD.foregroundPriority = 1;

   memset(pfD.optionalParameters, ' ',63);
   sz = "C:\\Hi-Tech Software\\JCM\\CBA\\CBATOOL\\cbatool.exe";
   strcpy(pfD.optionalParameters, sz);

   fIn = fopen("my.pif", "wb");
   fwrite(&pfH, sizeof(pfH),1,fIn);
   fwrite(&pfD, sizeof(pfD),1,fIn);

   fclose(fIn);
   ::ShellExecute(this->Handle,"open", "C:\\Hi-Tech Software\\JCM\\CBA\\CBATOOL\\cbatool.exe",NULL, NULL,SW_NORMAL);


}
//---------------------------------------------------------------------------
1. In you last text you don't use PIF file, but make ShellExecute to Exe.
In such case you must add parameters
(if exist), thus:
   ::ShellExecute(this->Handle,"open", "C:\\Hi-Tech Software\\JCM\\CBA\\CBATOOL\\cbatool.exe parameters",NULL, NULL,SW_NORMAL);
2.
>>I can't get the com ports to work with it?
As i understand, with com port works
Dos programm, isn't she?
In Windows you only run this programm.
Alex so I have done this wrong? I want to use the .pif file to see if it will work. What do i have to change to get this working as a .pif file?

Thanks
Clinton
Code must be:
   ::ShellExecute(this->Handle,"open", "my.pif",NULL, NULL,SW_NORMAL);
You must test 2 things:
1. Exists pif file: simple test you
directory.
2. Is PIF file correct?
 In Explorer set mouse to icon of File
and  DblClk   of mouse.
Alex Sorry I don't understand what's happing. Fisrt I change the ::ShellExecute back to the above code, and have fIn = fopen("my.pif", "wb"); It still comes up with an Error:
Cannot find the file 'C:\Hi-Tech Menu\My.pif'. Make sure that the file exists on your system and that the path and filename are correct.

Also I don't get your point #2? Is this in Windows Explorer? How do I set the mouse to the icon of the file?

Thanks
Clinton
Punkt 1. By message i see that file
"my.pif" don't creates.
snipet, that create file is:

   fIn = fopen("my.pif", "wb");
   fwrite(&pfH, sizeof(pfH),1,fIn);
   fwrite(&pfD, sizeof(pfD),1,fIn);

   fclose(fIn);
test it with debugger
2. Yes, if PIF file exists, you can
test it with Windows Explorer.  
Alex,
Thanks for the help, the only way I can get this to work is by opeing a Batch file from CreateProcess that in-turns opens the DOs program. Do you have any experences on batch files?

Thanks
Clinton
By you comment i understand, that
PIF file don't works in you Apps.
It is very strange, becouse i send you working example from my
project.
About bat files: yes, i have expirence
(and no so good) with bat files, becouse it is hard to control apps
in bat files(and very easy in PIF).
Now i use only PIF!
But if usual bat file don't suit you,
my be you can you WinBatch files
(tomorrow i send you URL).
 
Thanks Alex,
For some reason I can't get your pif program to work? It keeps on and on giving me that "My.pif" wrong message.

Thanks again for your time
Clinton
Alex before I go to something else I would like to get this going. I have now seen that it does make a My.pif Dos shortCut in the Dirctory of Hi-Tech Meun. I looked at the Path in the shortcut and it does tell me the correct path of 'C:\Hi-Tech Software\JCM\\CBA\\CBATOOL\CBATOOL.EXE'
But If i try to lanuch this, it gives me that error again. So my question is why does the code put the shortcut "MY.pif" in the dirctory of C:\Hi-Tech Menu? And why can't I launch the program from the shortcut? The .pif should of been put in the C:\Hi-Tech Software\JCM\CBA\CBATOOL\. This is where the .exe file is. It's close working so I would like to try and get this going.

Thanks
Clinton
As i understand, you cretes pif file,
but he is not work, right?
Only reason for it:
invalid contents of field
programFilename or/and
optionalParameters. For test it:
In Windows Explorer set mouse to
shortcut to file,press Right
button  and chouse Options:
Yoiu must see all data of Pif:
exe file name, parameters and many
other flags. Check, that all in his
place. Compare with other
pif (or i can send you my pif).

Thanks will do, but it would be nice to see your's also.

Clinton
Write you EMail and i 'll send you
clangan@hitechgaming.nb.ca

Thanks Alex for all your time and experience and my problem.

Clinton
ASKER CERTIFIED SOLUTION
Avatar of AlexVirochovsky
AlexVirochovsky

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial