Problem starting multiple programs at boot time

G

Guest

I am currently using the Explorer shell and want to start two different applications at boot time

I have used RegEdit to add the following ke
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
"Startup1"="c:\\startup\\prog1.exe". That works correctly and prog1 is started at boot time

To have a second program start at boot time I added a second value to the key like "Startup2"="c:\\startup\\prog2.exe" but the second program is not started, only the first program is started. If I delete the value for prog1 then prog2 will start.

To try and resolve the problem I wrote a third program "prog3.exe". This program called CreateProcess() for each of the two applications, prog1 & prog2. When prog3 is run from Explorer the program performs as desired, starting both prog1 and prog2 applications then Prog3 terminates. I then added Prog3.EXE to the CurrentVersion\Run key to launch Prog3 on boot. But I still have a problem. On boot Prog3 is launched but it will only start one of the programs (the one called in last call to CreateProcess). I've checked and no errors are being reported by CreateProcess. I've have even left a time delay of 10 sec between the first call to CreateProcess and the second call to CreateProcess with no sucess. The first call to CreateProcess does not return an error but the application does not start (even after waiting 10 second), once Prog3 terminates the program name listed in the last CallTo CreateProcess is started

It seems that with my build of XPE I can have only application run at startup time. Is there a setting that controls this number? If I call Prog3 from Explorer after startup then Prog3 sucessfully starts Prog1 and Prog2. Also all of the above works as expected on XP Pro but not on my build of XPe

Any Help on what could be wrong?
 
R

Roberto Cortiana

Arrording to your ost, is it possible to start prog2.exe 1 minute after
prog1.exe?
thank you

Tom said:
I am currently using the Explorer shell and want to start two different applications at boot time.

I have used RegEdit to add the following key
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run]
"Startup1"="c:\\startup\\prog1.exe". That works correctly and prog1 is started at boot time.

To have a second program start at boot time I added a second value to the
key like "Startup2"="c:\\startup\\prog2.exe" but the second program is not
started, only the first program is started. If I delete the value for prog1
then prog2 will start.
To try and resolve the problem I wrote a third program "prog3.exe". This
program called CreateProcess() for each of the two applications, prog1 &
prog2. When prog3 is run from Explorer the program performs as desired,
starting both prog1 and prog2 applications then Prog3 terminates. I then
added Prog3.EXE to the CurrentVersion\Run key to launch Prog3 on boot. But I
still have a problem. On boot Prog3 is launched but it will only start one
of the programs (the one called in last call to CreateProcess). I've checked
and no errors are being reported by CreateProcess. I've have even left a
time delay of 10 sec between the first call to CreateProcess and the second
call to CreateProcess with no sucess. The first call to CreateProcess does
not return an error but the application does not start (even after waiting
10 second), once Prog3 terminates the program name listed in the last CallTo
CreateProcess is started.
It seems that with my build of XPE I can have only application run at
startup time. Is there a setting that controls this number? If I call Prog3
from Explorer after startup then Prog3 sucessfully starts Prog1 and Prog2.
Also all of the above works as expected on XP Pro but not on my build of
XPe.
 
S

Slobodan Brcin \(eMVP\)

Hi Tom,

AFAIK This is not normal behavior that you have.

How do you know that second CreateProcess did not return error?
Is there any dependency between processes?

Use something like WaitForInputIdle

Post your exact code that does not work along with error checks.

Regards,
Slobodan

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Have an opinion on the effectiveness of Microsoft Embedded newsgroups? Tell
Microsoft!
https://www.windowsembeddedeval.com/community/newsgroups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tom said:
I modified Prog3 to start Prog1 wait 60 seconds then start Prog2. Result
when Prog3 runs it calls CreateProcess() for Prog1 and waits 60 second.
During this time Prog1 does not start and CreateProcess() does not return an
error. After 60 seconds Prog3 calls CreateProcess() to start Prog2 and then
Prog3 terminates. Prog2 starts OK. Problem still exist. (Note Prog3 is a
Console app, Prog1 & Prog2 are GUI)
To try a slightly different approach I modified Prog1 to wait 60 seconds
then call Prog2. On boot I start Prog1. Then after 60 seconds Prog1 calls
CreateProcess for Prog2. That seems to work. Both programs are running. But
previously I had tried this approach where Prog1 waited 1 second before
calling CreateProcess for Prog2 that did not work, Prog2 does not start if I
only wait 1 second or less.
In my application a 60 second wait time to start Prog2 after Prog1 starts
is not acceptable. Is there a way I can shorten this delay? What is the
minimum delay required?
 
G

Guest

Here is a copy of the code from Prog3. Prog3 starts after boot but fails to start Prog1 and Prog2. Only Prog2 starts

void main(void

STARTUPINFO siStartInfo
PROCESS_INFORMATION piProcessInfo
char cFileName[256]

cout << "Starting Prog1......"
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO))
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION))
GetStartupInfo(&siStartInfo)
siStartInfo.cb = sizeof(STARTUPINFO)
siStartInfo.dwFlags = STARTF_USESHOWWINDOW
siStartInfo.wShowWindow = SW_MINIMIZE
strcpy(cFileName,"\\Starup\\Prog1.exe")
lstrcat(cFileName,cFile)
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&piProcessInfo)

cout << endl
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for "
cout << cFileName; cout << endl

els

cout << "Done."; cout << endl

Sleep(65000)
cout << "Starting Prog2......"
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO))
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION))
GetStartupInfo(&siStartInfo)
siStartInfo.cb = sizeof(STARTUPINFO)
siStartInfo.dwFlags = STARTF_USESHOWWINDOW
siStartInfo.wShowWindow = SW_SHOW
strcpy(cFileName,"\\Starup\\Prog2.exe")
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo
&piProcessInfo)

cout << endl
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for "
cout << cFileName; cout << endl

els

cout << "Done."; cout << endl
 
S

Slobodan Brcin \(eMVP\)

Hi Tom,

You are saying that without sleep you will see twice done without error,
right?
If it is working with sleep 65000 I have no idea why it won't work without
it.

Maybe process is started but invisible, try using task manager to check
this.

Also there is possibility that your two apps are using same resource and
that second application just terminate after it is started.
If you wrote them. Add some indication to file or remote debugger so you can
make sure that it was or was not started.

Regards,
Slobodan

Tom said:
Here is a copy of the code from Prog3. Prog3 starts after boot but fails
to start Prog1 and Prog2. Only Prog2 starts.
void main(void)
{
STARTUPINFO siStartInfo;
PROCESS_INFORMATION piProcessInfo;
char cFileName[256];

cout << "Starting Prog1......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_MINIMIZE;
strcpy(cFileName,"\\Starup\\Prog1.exe");
lstrcat(cFileName,cFile);
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&p
iProcessInfo))
{
cout << endl;
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for ";
cout << cFileName; cout << endl;
}
else
{
cout << "Done."; cout << endl;
}
Sleep(65000);
cout << "Starting Prog2......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_SHOW;
strcpy(cFileName,"\\Starup\\Prog2.exe");
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,
&piProcessInfo))
{
cout << endl;
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for ";
cout << cFileName; cout << endl;
}
else
{
cout << "Done."; cout << endl;
}
}
 
S

Slobodan Brcin \(eMVP\)

Tom,

I don't know. For test you can try to create two console applications that
will make infinite loop and print some text. Put sleep(10) in loop also.

Try to launch these application to see if they will make same problem.

Regards,
Slobodan

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Have an opinion on the effectiveness of Microsoft Embedded newsgroups? Tell
Microsoft!
https://www.windowsembeddedeval.com/community/newsgroups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tom said:
In answer to your question. Yes with and without the sleep command I see done printed twice.
I've checked taks manager. Both programs are not running.
THe only thing in common between Prog1 and Prog2 is some DLL's used for the display.

I've done some more testing on the problem here is what I've found out.

Currently I have Prog1 listed in [HCU\...CurrentVersion\Run] so it is
started at boot. Prog1 waits a delay time before calling CreateProcess() for
Prog2. If delay time is less than approx 4 seconds then Prog2 does not run.
If I wait 4.5 seconds it appears that Prog2 always starts. At no time does
CreateProcess() return an error. Also I noticed that if Prog2 fails to start
the input focus stays with Prog1, if Prog2 starts the input focus switches
to Prog2.
 
K

KM

Tom

Some not really important suggestions/comments inline...

--
KM,
BSquare Corporation
Here is a copy of the code from Prog3. Prog3 starts after boot but fails to start Prog1 and Prog2. Only Prog2 starts.

void main(void)
{
STARTUPINFO siStartInfo;
PROCESS_INFORMATION piProcessInfo;
char cFileName[256];

cout << "Starting Prog1......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_MINIMIZE;

Why not SW_SHOWDEFAULT or SW_SHOWNORMAL? With the flag you set, you may just see your app minimized.
strcpy(cFileName,"\\Starup\\Prog1.exe");

Is it a typo? (\\Starup or \\Startup)
lstrcat(cFileName,cFile);
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&piProcessInfo))


How about moving the cFileName to the first argument?
{
cout << endl;
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for ";
cout << cFileName; cout << endl;
}
else
{
cout << "Done."; cout << endl;
}
Sleep(65000);
cout << "Starting Prog2......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_SHOW;

And here you set SW_SHOW and you therefore see the Prog2 window.
strcpy(cFileName,"\\Starup\\Prog2.exe");


Is it a typo? (\\Starup or \\Startup)
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo, &piProcessInfo))

How about moving the cFileName to the first argument?
 
P

Phil Wilson

What I find really weird about that code is two CreateProcess calls
simultaneously using the same startupinfo and processinfo. It actually zeros
out the structures passed to the second createprocess while they still
contain data from the first (the process and thread handles etc). And there
seems to be no need at all to call GetStartupInfo. Just use two separate
structures for each program, and it wouldn't hurt to clean up your process
and thread handles either, depending on what the rest of the program does
(if it just finishes, Windows will free the handles). That would all be good
programming practice and might solve your problem.
--
Phil Wilson [MVP Windows Installer]
----
Tom said:
Here is a copy of the code from Prog3. Prog3 starts after boot but fails
to start Prog1 and Prog2. Only Prog2 starts.
void main(void)
{
STARTUPINFO siStartInfo;
PROCESS_INFORMATION piProcessInfo;
char cFileName[256];

cout << "Starting Prog1......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_MINIMIZE;
strcpy(cFileName,"\\Starup\\Prog1.exe");
lstrcat(cFileName,cFile);
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&p
iProcessInfo))
{
cout << endl;
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for ";
cout << cFileName; cout << endl;
}
else
{
cout << "Done."; cout << endl;
}
Sleep(65000);
cout << "Starting Prog2......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_SHOW;
strcpy(cFileName,"\\Starup\\Prog2.exe");
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,
&piProcessInfo))
{
cout << endl;
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for ";
cout << cFileName; cout << endl;
}
else
{
cout << "Done."; cout << endl;
}
}
 
S

Slobodan Brcin \(eMVP\)

Hi Phil,

Actually using same structures is not a problem since he reinitialized
values and they are not permanently used by OS.
Releasing handles is also not required since this is a launcher application
that closes after it starts two processes, although I absolutely agree that
this is a good practice.

Regards,
Slobodan

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Have an opinion on the effectiveness of Microsoft Embedded newsgroups? Tell
Microsoft!
https://www.windowsembeddedeval.com/community/newsgroups
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Phil Wilson said:
What I find really weird about that code is two CreateProcess calls
simultaneously using the same startupinfo and processinfo. It actually zeros
out the structures passed to the second createprocess while they still
contain data from the first (the process and thread handles etc). And there
seems to be no need at all to call GetStartupInfo. Just use two separate
structures for each program, and it wouldn't hurt to clean up your process
and thread handles either, depending on what the rest of the program does
(if it just finishes, Windows will free the handles). That would all be good
programming practice and might solve your problem.
--
Phil Wilson [MVP Windows Installer]
----
Tom said:
Here is a copy of the code from Prog3. Prog3 starts after boot but fails
to start Prog1 and Prog2. Only Prog2 starts.
void main(void)
{
STARTUPINFO siStartInfo;
PROCESS_INFORMATION piProcessInfo;
char cFileName[256];

cout << "Starting Prog1......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_MINIMIZE;
strcpy(cFileName,"\\Starup\\Prog1.exe");
lstrcat(cFileName,cFile);
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,&p
iProcessInfo))
{
cout << endl;
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for ";
cout << cFileName; cout << endl;
}
else
{
cout << "Done."; cout << endl;
}
Sleep(65000);
cout << "Starting Prog2......";
ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
ZeroMemory(&piProcessInfo, sizeof(PROCESS_INFORMATION));
GetStartupInfo(&siStartInfo);
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.dwFlags = STARTF_USESHOWWINDOW;
siStartInfo.wShowWindow = SW_SHOW;
strcpy(cFileName,"\\Starup\\Prog2.exe");
if(!CreateProcess(NULL,cFileName,NULL,NULL,FALSE,0,NULL,NULL,&siStartInfo,
&piProcessInfo))
{
cout << endl;
cout << "Error "; cout << GetLastError(); cout << " In CreateProcess for ";
cout << cFileName; cout << endl;
}
else
{
cout << "Done."; cout << endl;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top