CreateProcess wartet bei IE8 nicht

Newbie8

Mitglied
Hallo,

bisher haben wir folgendes unter Windows XP und IE6 verwendet und es hat funktioniert:
Code:
PROCESS_INFORMATION piIE;
STARTUPINFO suiIE;
suiIE.cb		=sizeof(STARTUPINFO);
suiIE.lpReserved	=0;
suiIE.lpDesktop	=NULL;
suiIE.lpTitle	=NULL;
suiIE.dwX		=0;
suiIE.dwY		=0;
suiIE.dwXSize	=0;
suiIE.dwYSize	=0;
suiIE.dwXCountChars	=0;
suiIE.dwYCountChars	=0;
suiIE.dwFillAttribute	=0;
suiIE.dwFlags	=STARTF_USESHOWWINDOW;
suiIE.wShowWindow	=SW_SHOWMAXIMIZED;
suiIE.cbReserved2	=0;
suiIE.lpReserved2	=0;
		if(CreateProcess(NULL,strIE,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiIE,&piIE)==TRUE) {
  CloseHandle(piIE.hThread);
}
WaitForInputIdle(piIE.hProcess, INFINITE);
WaitForSingleObject(piIE.hProcess, 100) ;
aber im IE8 wartet er jetzt nicht mehr, bis der IE sich beendet hat. Bzw es funktioniert nur, wenn noch keine IE-Fenster offen sind. Wenn schon welche offen sind, dann wartet er einfach nicht, sondern geht ihm Code direkt weiter. Ich habe jetzt im Internet gelesen, dass man lieber CoCreateInstance verwenden sollte. ist das richtig? Ich habe es jetzt so versucht:

Code:
IWebBrowser2 *pBrowser = NULL;
WNDCLASS a; HWND b; MSG c; char aa[100];

HRESULT h;

// Wurde diese Funktion fehlerfrei ausgeführt, wird der IE geöffnet.
h = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowser2, (void**)&pBrowser); 

pBrowser->put_Visible(VARIANT_TRUE); // Setzt den Browser sichtbar
Was ist daran falsch? Das Programm beendet sich leider mit einer Fehlermeldung:
Fehler in der Anwendung - Die ANweisung in "0x004027c6" verweist auf Speicher in "0x000000000". Der Vorgang "read" konnte nicht auf dem Speicher durchgeführt werden.

Ich hoffe mir kann jmd helfen. WEnn CoCreateInstance doch falsch sein sollte, vielleicht hat ja jmd einen Tipp, wie man den IE starten kann, auch wenn schon IE-FEnster offen sind und das Programm so lange wartet, bis man den IE wieder schließt.

Viele Grüße
 
Hi.
bisher haben wir folgendes unter Windows XP und IE6 verwendet und es hat funktioniert:
Code:
PROCESS_INFORMATION piIE;
STARTUPINFO suiIE;
suiIE.cb		=sizeof(STARTUPINFO);
suiIE.lpReserved	=0;
suiIE.lpDesktop	=NULL;
suiIE.lpTitle	=NULL;
suiIE.dwX		=0;
suiIE.dwY		=0;
suiIE.dwXSize	=0;
suiIE.dwYSize	=0;
suiIE.dwXCountChars	=0;
suiIE.dwYCountChars	=0;
suiIE.dwFillAttribute	=0;
suiIE.dwFlags	=STARTF_USESHOWWINDOW;
suiIE.wShowWindow	=SW_SHOWMAXIMIZED;
suiIE.cbReserved2	=0;
suiIE.lpReserved2	=0;
		if(CreateProcess(NULL,strIE,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiIE,&piIE)==TRUE) {
  CloseHandle(piIE.hThread);
}
WaitForInputIdle(piIE.hProcess, INFINITE);
WaitForSingleObject(piIE.hProcess, 100) ;
Ein Fehler der hier sofort auffällt: du greifst in jedem Fall auf pilE.hProcess zu, auch wenn CreateProcess nicht erfolgreich war.
aber im IE8 wartet er jetzt nicht mehr, bis der IE sich beendet hat. Bzw es funktioniert nur, wenn noch keine IE-Fenster offen sind.
Das ist logisch. Der Prozess den du startest verbindet sich nur mit der bereits laufenden Instanz (wenn eine solche existiert) und wird dann prompt beendet.
Wenn schon welche offen sind, dann wartet er einfach nicht, sondern geht ihm Code direkt weiter.
Er wartet schon, nur der Prozess ist dann beendet...
Ich habe jetzt im Internet gelesen, dass man lieber CoCreateInstance verwenden sollte. ist das richtig?
Ja.
Ich habe es jetzt so versucht:

Code:
IWebBrowser2 *pBrowser = NULL;
WNDCLASS a; HWND b; MSG c; char aa[100];

HRESULT h;

// Wurde diese Funktion fehlerfrei ausgeführt, wird der IE geöffnet.
h = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowser2, (void**)&pBrowser); 

pBrowser->put_Visible(VARIANT_TRUE); // Setzt den Browser sichtbar
Hier prüfst du nicht ob CoCreateInstance überhaupt erfolgreich war.

Gruß
 
Ich habe jetzt mal folgendes versucht:
Code:
if(h == S_OK){
		   MessageBox(NULL, "1", "", MB_OK);
	   }else if(h == REGDB_E_CLASSNOTREG){
		   MessageBox(NULL, "2", "", MB_OK);
	   }else if(h == CLASS_E_NOAGGREGATION){
		   MessageBox(NULL, "3", "", MB_OK);
	   }else if(h == E_NOINTERFACE){
		   MessageBox(NULL, "4", "", MB_OK);
	   }else if(h == E_POINTER){
		   MessageBox(NULL, "e7", "", MB_OK);
	   }else{
		   MessageBox(NULL, "else", "", MB_OK);
	   }
um zu sehen, was als Result bei CoCreateInstance zurückgegeben wird, hier http://msdn.microsoft.com/en-us/library/ms686615(v=VS.85).aspx stand dass es diese Rückgabewerte gibt oder hab ich das falsch verstanden?

Das ist logisch. Der Prozess den du startest verbindet sich nur mit der bereits laufenden Instanz (wenn eine solche existiert) und wird dann prompt beendet.
Er wartet schon, nur der Prozess ist dann beendet...
Zitat Zitat von Newbie8 Beitrag anzeigen
Ich habe jetzt im Internet gelesen, dass man lieber CoCreateInstance verwenden sollte. ist das richtig?
Ja.

Ich dachte ich verwende CoCreateInstance ohne CreateProcess vorher, ich habe jetzt mal CreateProcess vorher stehen lassen und vor WaitForInputIdle(piIE.hProcess, INFINITE); CoCreateInstance aufgerufen. Jetzt startet er zwar, geht in den else-Zweig bei der Überprüfung des Rückgabewertes von CoCreateProcess, danach erscheint aber wieder die Fehlermeldung und er beendet das Programm unsanft.

So sieht mein Programm jetzt aus:
Code:
PROCESS_INFORMATION piIE;
STARTUPINFO suiIE;
suiIE.cb		=sizeof(STARTUPINFO);
suiIE.lpReserved	=0;
suiIE.lpDesktop	=NULL;
suiIE.lpTitle	=NULL;
suiIE.dwX		=0;
suiIE.dwY		=0;
suiIE.dwXSize	=0;
suiIE.dwYSize	=0;
suiIE.dwXCountChars	=0;
suiIE.dwYCountChars	=0;
suiIE.dwFillAttribute	=0;
suiIE.dwFlags	=STARTF_USESHOWWINDOW;
suiIE.wShowWindow	=SW_SHOWMAXIMIZED;
suiIE.cbReserved2	=0;
suiIE.lpReserved2	=0;
result = CreateProcess(NULL,strIE,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiIE,&piIE);
	
if(result == 0){
	MessageBox(NULL, "Fehler beim Starten des IE aufgetreten", "", MB_OK);
}else{
	IWebBrowser2 *pBrowser = NULL;
	HRESULT h;
	// Wurde diese Funktion fehlerfrei ausgeführt, wird der IE geöffnet.
	h = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowser2, (void**)&pBrowser); 
	if(h == S_OK){
		MessageBox(NULL, "1", "", MB_OK);
	}else if(h == REGDB_E_CLASSNOTREG){
		MessageBox(NULL, "2", "", MB_OK);
	}else if(h == CLASS_E_NOAGGREGATION){
		MessageBox(NULL, "3", "", MB_OK);
	}else if(h == E_NOINTERFACE){
		MessageBox(NULL, "4", "", MB_OK);
	}else if(h == E_POINTER){
		MessageBox(NULL, "e7", "", MB_OK);
	}else{
		MessageBox(NULL, "else", "", MB_OK);
	}
	pBrowser->put_Visible(VARIANT_TRUE); // Setzt den Browser sichtbar
	WaitForInputIdle(piIE.hProcess, INFINITE);
	WaitForSingleObject(piIE.hProcess, INFINITE);
	MessageBox(NULL, "IE beendet", "", MB_OK);
	//Fortfahren im Programm
}

Viele Grüße
 
um zu sehen, was als Result bei CoCreateInstance zurückgegeben wird
Gib doch einfach den Wert als int aus um zu sehen was zurückgeben wird.
Ich dachte ich verwende CoCreateInstance ohne CreateProcess vorher, ich habe jetzt mal CreateProcess vorher stehen lassen und vor WaitForInputIdle(piIE.hProcess, INFINITE); CoCreateInstance aufgerufen. Jetzt startet er zwar, geht in den else-Zweig bei der Überprüfung des Rückgabewertes von CoCreateProcess,
Meinst du hier CoCreateInstance?
o sieht mein Programm jetzt aus:
Code:
result = CreateProcess(NULL,strIE,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiIE,&piIE);
	
if(result == 0){
	MessageBox(NULL, "Fehler beim Starten des IE aufgetreten", "", MB_OK);
}else{
	IWebBrowser2 *pBrowser = NULL;
	HRESULT h;
	// Wurde diese Funktion fehlerfrei ausgeführt, wird der IE geöffnet.
	h = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowser2, (void**)&pBrowser); 
	if(h == S_OK){
		MessageBox(NULL, "1", "", MB_OK);
	}else if(h == REGDB_E_CLASSNOTREG){
		MessageBox(NULL, "2", "", MB_OK);
	}else if(h == CLASS_E_NOAGGREGATION){
		MessageBox(NULL, "3", "", MB_OK);
	}else if(h == E_NOINTERFACE){
		MessageBox(NULL, "4", "", MB_OK);
	}else if(h == E_POINTER){
		MessageBox(NULL, "e7", "", MB_OK);
	}else{
		MessageBox(NULL, "else", "", MB_OK);
	}
	pBrowser->put_Visible(VARIANT_TRUE); // Setzt den Browser sichtbar
	WaitForInputIdle(piIE.hProcess, INFINITE);
	WaitForSingleObject(piIE.hProcess, INFINITE);
	MessageBox(NULL, "IE beendet", "", MB_OK);
	//Fortfahren im Programm
}
Auch hier greifst du wieder auf nicht initialisierte Attribute zu. Wenn CoCreateInstance nicht erfolgreich war, darfst du nicht auf pBrowser zugreifen.

Verwende den Debugger, schau nach in welcher Zeile der Fehler auftritt, welche Werte die Variablen (h) haben.

Gruß
 
Meinst du hier CoCreateInstance?
Ja natürlich - sorry.

Ich habe es jetzt so geändert:
Code:
................so wie vorher.............
h = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_ALL, IID_IWebBrowser2, (void**)&pBrowser); 
if ( FAILED( h ) )
{
	MessageBox(NULL, "!FEHLER", "", MB_OK);
	char i[255];
	sprintf(i, "%x", h);
	MessageBox(NULL, i, "Rückgabewert", MB_OK);
}else{
	pBrowser->put_Visible(VARIANT_TRUE); // Setzt den Browser sichtbar
}
WaitForInputIdle(piIE.hProcess, INFINITE);
................so wie vorher.....

Jetzt bekomme ich aus Ausgabe 800401f0. Was sagt mir das? Wo könnte der Fehler liegen?

Viele Grüße
 
Ich hatte es gegoogelt aber leider nichts gefunden womit ich was anfangen konnte :( Habe jetzt nochmal meine Suchwörter geändert und habe gefunden, dass man wohl vorher:

HRESULT hRes = CoInitialize(NULL);

aufnehmen sollte ;)

CreateProcess und CoCreateInstance zusammen/nacheinander auszuführen ist bissl n Schmarrn oder? Jetzt gehen ja zwei IE-Seiten auf. Ich möchte gerne eine Seite mit einer Startseite öffnen (geht das mit CoCreateInstance, dass man eine Startseite übergibt?) und wenn die Seite geschlossen wird, möchte ich eine Funktion aufrufen, die er ja momentan gleich nach dem Starten ausführt. Wie kann ich mit CoCreateInstance prüfen, ob die Seite noch offen ist? Und erst wenn sie schließt etwas ausführen? Hatte gehofft, wenn ich einfach

WaitForInputIdle(pBrowser, INFINITE);
WaitForSingleObject(pBrowser, INFINITE);

verwende, dass es helfen könnte, aber war leider nicht so :(

Viele Grüße
 
Juhu das Navigieren hab ich jetzt geschafft dass er mir meine Seite öffnet, die ich geöffnet haben möchte *freu*

Habe es folgendermaßen gelöscht:
Code:
h = CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&pBrowser); 
if(pBrowser){
	VARIANT vEmpty;
	VariantInit(&vEmpty);
	BSTR bstrURL = SysAllocString(L"http://localhost/index.htm");
	HRESULT hr = pBrowser->Navigate(bstrURL, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
        if (SUCCEEDED(hr)){
		pBrowser->put_Visible(VARIANT_TRUE); // Setzt den Browser sichtbar
	}else{
		char i[255];
		sprintf(i, "%x", hr);
		MessageBox(NULL, i, "Fehler Navigate", MB_OK);
		pBrowser->Quit();
	}
	SysFreeString(bstrURL);
	pBrowser->Release();
}
OleUninitialize();

Leider habe ich keine Ahnung, wie ich das überwachen könnte, ob das Internet Explorer Fenster noch offen ist. Denn nach dem Schließen des Fensters müsste ich noch ein paar Sachen durchführen, aber erst wenn das Fenster geschlossen wird und nicht eher. Hast du vielleicht einen Tipp für mich?
Viele Grüße
 
Zuletzt bearbeitet:
Leider habe ich keine Ahnung, wie ich das überwachen könnte, ob das Internet Explorer Fenster noch offen ist. Denn nach dem Schließen des Fensters müsste ich noch ein paar Sachen durchführen, aber erst wenn das Fenster geschlossen wird und nicht eher. Hast du vielleicht einen Tipp für mich?
Es gibt ein Ereignis welches ausgelöst wird wenn sich der Browser schließt. Siehe http://msdn.microsoft.com/en-us/library/cc136549(v=VS.85).aspx

Alternativ könntest du natürlich auch dein eigenes Fenster erstellen und ein Browser Control hinzufügen. Siehe z.B. http://www.codeproject.com/KB/COM/cwebpage.aspx

Gruß
 
Zuletzt bearbeitet:
Es gibt ein Ereignis welches ausgelöst wird wenn sich der Browser schließt. Siehe http://msdn.microsoft.com/en-us/library/cc136549(v=VS.85).aspx
Das hört sich ja super an :) Habe bisher leider fast nichts über diese FUnktion gefunden und das was bei msdn steht, hilft mir leider nicht viel weiter. Ich habe ja pBrowser, was ja aber ein IWebBrowser2 ist und die Funktion gibt es wohl nur für DWebBrowserEvents2. Wie müsste ich die Funktion denn aufnehmen? kannst du mir da nicht einen Tipp geben? Komme nämlich gar nicht weiter :(

Viele Grüße
 
Zurück