# Prozesse auslesen



## Newbie8 (6. Mai 2011)

Hallo,

bin gerade am verzweifeln, ich möchte alle Prozesse, die gerade laufen auslesen, um einen bestimmten zu killen. Hoffe, dass ich über den Namen den richtigen herausfinden kann. Allerdings habe ich EnumProcesses probiert, dann sagt er mir immer obwohl ich #include <psapi.h> aufgenommen habe, dass er EnumProcesses ein nichtdeklarierter Bezeichner ist. Jetzt hatte ich auf einer anderen Seite gelesen, dass wenn man XP hat, man lieber CreateToolhelp32Snapshot verwenden sollte, aber auch hier das gleiche Spiel, habe oben #include <tlhelp32.h> eingebunden, aber der Compiler sagt wieder nichtdeklarierter Bezeichner. Habe jetzt echt schon viel Zeit investiert und auch sehr viel gegoogelt, aber ich komme einfach nicht weiter. Ich hoffe, ihr könnt mir weiterhelfen.

Das Programm wird unter XP kompiliert, ich arbeite mit Visual Studio C++ 6 und wenn möglich, sollte das Programm auch unter Vista funktionieren.

Für Enumerating Processes hatte ich zB folgendes ausprobiert:
http://msdn.microsoft.com/en-us/library/ms682623.aspx
und für CreateToolhelp32Snapshot zB folgendes Beispiel:
http://weseetips.com/tag/createtoolhelp32snapshot/

Ich hoffe, ihr könnt mir weiterhelfen. Vielen lieben Dank im Voraus
Viele Grüße


----------



## deepthroat (6. Mai 2011)

Hi.

Schau doch mal in deiner Version der psapi.h nach, ob dort die EnumProcesses Funktion deklariert wird.

Willst du denn nicht einen neueren C/C++ Compiler verwenden?

Gruß


----------



## Newbie8 (6. Mai 2011)

Hi,

muss sagen wenn ich auf meiner Festplatte nach psapi.h suche, finde ich nur unter C:\windows\system32 eine psapi.dll. Fehlt mir hier eine Bibliothek? Wenn ja, wo bekomme ich die her? Habe mal etwas bei Microsoft heruntergeladen, weil ich dachte mir fehlt evtl die psapi.h aber das war dann wieder die dll oder ist die psapi.h in der dll enthalten? Bzw wie finde ich die Version der psapi.h heraus? Sorry dass ich mich so wenig auskenne

Schau doch mal in deiner Version der psapi.h nach, ob dort die EnumProcesses Funktion deklariert wird.

Ist der Compiler so sehr überaltet? In der Firma, wo ich arbeite, verwenden wir diesen Compiler 
Viele Grüße


----------



## deepthroat (6. Mai 2011)

Newbie8 hat gesagt.:


> muss sagen wenn ich auf meiner Festplatte nach psapi.h suche, finde ich nur unter C:\windows\system32 eine psapi.dll. Fehlt mir hier eine Bibliothek?


Die DLL ist die Bibliothek. Irgendwo muss allerdings auch die Headerdatei sein. Der Compiler würde sich beschweren, wenn er die Datei nicht finden könnte.

Die Datei ist Teil des Platform SDKs. Sollte also unter %programfiles%\Microsoft SDKs\Windows\vX.Y\include zu finden sein...

Ansonsten starte mal filemon (kann man bei MS runterladen), trage als Filter "*psapi.h" ein und starte das Kompilieren. So findest du genau raus wo der Compiler die Datei findet.


Newbie8 hat gesagt.:


> Ist der Compiler so sehr überaltet?


Veraltet ist gar kein Ausdruck. Und schlecht war der schon immer.


Newbie8 hat gesagt.:


> In der Firma, wo ich arbeite, verwenden wir diesen Compiler


Lauf schnell weg... 

Gruß


----------



## Newbie8 (6. Mai 2011)

Anfangs hatte er auch gemeckert, dass er die psapi.h nicht findet, dann hatte ich gegoogelt und da hatte jmd mal geschrieben, dass man unter den Projekteinstellungen unter C/C++->Allgemein unter Präprozessor-Definitionen DPSAPI_VERSION=1 eintragen soll und unter Linker->Eingabe Zusätlicher Bibliothekspfad Psapi.lib und danach hatte er zwar nicht mehr gesagt, dass er psapi.h nicht findet, aber er kannte EnumProcesses, EnumProcessModules und GetModuleBaseName trotzdem nicht. Selbst als ich das jetzt rückgängig gemacht habe, trotzdem meckert er nicht die psapi.h an sondern EnumProcesses,...Habe soviel ausprobiert, da hab ich wohl irgendwo noch was verstellt  Vielleicht sollte ich es sonst nochmal neu installieren lassen?

http://technet.microsoft.com/en-us/sysinternals/bb896642 hier stand dass filemon durch ProcessMonitor ersetzt wurde, habe es heruntergeladen und den Filter gesetzt und es läuft schon ewig. (wobei ich eh nicht weiß, was ich beim Filter auswählen muss, Architecture?), wollte gern einen Screenshot anhängen aber das ist wohl nicht erlaubt oder?

;-)
Gruß


----------



## deepthroat (6. Mai 2011)

Newbie8 hat gesagt.:


> http://technet.microsoft.com/en-us/sysinternals/bb896642 hier stand dass filemon durch ProcessMonitor ersetzt wurde, habe es heruntergeladen und den Filter gesetzt und es läuft schon ewig. (wobei ich eh nicht weiß, was ich beim Filter auswählen muss,


Path ends with psapi.h


Newbie8 hat gesagt.:


> wollte gern einen Screenshot anhängen aber das ist wohl nicht erlaubt oder?


Doch, das ist erlaubt.

Gruß


----------



## Newbie8 (6. Mai 2011)

> Path ends with psapi.h


Danke  then include oder?

Als ich vorhin auf antworten gegangen bin, hat er immer direkt antworten angezeigt, da fehlten dann ein paar Buttons zB zum Anhängen von Grafiken. jetzt zeigt er die normale Oberfläche an 
Gruß


----------



## Newbie8 (6. Mai 2011)

Hm irgendwie kommt der gar nicht vorwärts - ist das normal? Apply Event Filter 23% - 139.07 remaining (06.05.2011 14:15:21)

Allerdings steigt 139.07 und 14:15:21 weiter an und die Prozente gehen gar nicht mehr hoch


----------



## deepthroat (6. Mai 2011)

Newbie8 hat gesagt.:


> Hm irgendwie kommt der gar nicht vorwärts - ist das normal? Apply Event Filter 23% - 139.07 remaining (06.05.2011 14:15:21)
> 
> Allerdings steigt 139.07 und 14:15:21 weiter an und die Prozente gehen gar nicht mehr hoch


Ich weiß nicht genau wovon du redest.

Normalerweise startet man Procmon mit dem entsprechenden Filter, startet das Kompilieren, beendet das Monitoring in Procman (F5) und schaut sich das Resultat an. Die Angelegenheit dauert vielleicht 2-3 min.

\edit: Hast du denn mal in %programfiles%\Microsoft SDKs\Windows\vX.Y\include geschaut?

Gruß


----------



## Newbie8 (6. Mai 2011)

Vorhin hat sich dann sogar mein PC aufgehängt, kam ein Bluescreen mit Hard Error. war ganz schön geschockt, aber gott sei dank ist er ohne Probleme hochgefahren.

Also ich starte Procman.exe, dann erscheint folgende Anzeige: Zwischenablage02.jpg

Vorhin hatte ich Path ends with psapi.h then Include ausgewählt und Add geklickt. Jetzt versuche ich lieber mal Path ends with psapi.h then exclude, also bei mir läuft das dann schon länger als 2-3min, jetzt läufts nämlich schon 10min und unten steht dann "the current filter exclues all 2.684.745 events" und die zahlt steigt sekündlich.

Ok jetzt gings doch noch schnell, wenn ich then include angebe, dann ist das Ergebnis no events (capture disabled) und wenn ich exclude angebe, werden einige Prozesse angezeigt.


----------



## deepthroat (6. Mai 2011)

Newbie8 hat gesagt.:


> Vorhin hat sich dann sogar mein PC aufgehängt, kam ein Bluescreen mit Hard Error. war ganz schön geschockt, aber gott sei dank ist er ohne Probleme hochgefahren.


Vermutlich ist dein PC / Speicher / deine Festplatte defekt.


Newbie8 hat gesagt.:


> Also ich starte Procman.exe, dann erscheint folgende Anzeige: Zwischenablage02.jpg
> 
> Vorhin hatte ich Path ends with psapi.h then Include ausgewählt und Add geklickt.


Richtig.


Newbie8 hat gesagt.:


> Jetzt versuche ich lieber mal Path ends with psapi.h then exclude


Falsch.


Newbie8 hat gesagt.:


> , also bei mir läuft das dann schon länger als 2-3min, jetzt läufts nämlich schon 10min und unten steht dann "the current filter exclues all 2.684.745 events" und die zahlt steigt sekündlich.


Du mußt das nur solange laufen lassen bis die Kompilierung abgeschlossen ist.


Newbie8 hat gesagt.:


> Ok jetzt gings doch noch schnell, wenn ich then include angebe, dann ist das Ergebnis no events (capture disabled) und wenn ich exclude angebe, werden einige Prozesse angezeigt.


Was wird angezeigt?

Hast du denn mal in %programfiles%\Microsoft SDKs\Windows\vX.Y\include geschaut?

Gruß


----------



## Newbie8 (6. Mai 2011)

Ok habe jetzt nochmal Procmon.exe mit dem Filter path ends with psapi.h then include gestartet, wenn ich beim Filter auf ok klicke, dann kommt manchmal erst so ein kleines Fenster(manchmal auch nicht), wo er recht schnell die Prozente hochzählt und anschließend wird das hier angezeigt:Zwischenablage03.jpg - lasse es mal weiterlaufen, hoffe er beendet sich dann irgendwann und zeigt was an, womit wir was anfangen können 

Also mein Rechner ist recht neu und läuft jetzt wieder einwandfrei, hoffe mal nicht dass da was am Speicher ist.

ja hab ich - da sind ganz viele .h dateien aber kein psapi.h - ich habe auch extra mal nach psapi.h gesucht, da findet er unter program files\microsoft visual studio nichts

Hast du eine Idee, wo ich die datei herbekommen könnte bzw was ich verstellt haben könnte, so dass er nicht die psapi.h anmeckert sondern die FUnktionen?

Viele Grüße


----------



## deepthroat (6. Mai 2011)

Newbie8 hat gesagt.:


> Ok habe jetzt nochmal Procmon.exe mit dem Filter path ends with psapi.h then include gestartet, wenn ich beim Filter auf ok klicke, dann kommt manchmal erst so ein kleines Fenster(manchmal auch nicht), wo er recht schnell die Prozente hochzählt und anschließend wird das hier angezeigt:Zwischenablage03.jpg - lasse es mal weiterlaufen, hoffe er beendet sich dann irgendwann und zeigt was an, womit wir was anfangen können


Nein, da beendet sich nichts von alleine.

Du mußt doch nun wirklich nur mal einen Kompilierungslauf starten und dann in Procmon auf F5 (bzw. auf die Lupe) drücken.


Newbie8 hat gesagt.:


> Also mein Rechner ist recht neu und läuft jetzt wieder einwandfrei, hoffe mal nicht dass da was am Speicher ist.


Ein Bluescreen kommt normalerweise nicht aus heiterem Himmel. Überprüfe den Speicher (memtest86). Könnte auch an anderer Hardware / Treibern (Viren?) liegen.


Newbie8 hat gesagt.:


> ja hab ich - da sind ganz viele .h dateien aber kein psapi.h - ich habe auch extra mal nach psapi.h gesucht, da findet er unter program files\microsoft visual studio nichts
> 
> Hast du eine Idee, wo ich die datei herbekommen könnte


Wie bereits gesagt, ist die Datei Teil des Platform SDKs. Das kann man bei Microsoft runterladen.


Newbie8 hat gesagt.:


> bzw was ich verstellt haben könnte, so dass er nicht die psapi.h anmeckert sondern die FUnktionen?


Nein. Zeig mal die kompletten Fehlermeldungen.

Gruß


----------



## Newbie8 (6. Mai 2011)

> Nein, da beendet sich nichts von alleine.
> 
> Du mußt doch nun wirklich nur mal einen Kompilierungslauf starten und dann in Procmon auf F5 (bzw. auf die Lupe) drücken.


So langsam komm ich mir echt bissl doof vor, also ich Start progmon.exe, gebe meinen Filter ein, klicke ok und dann läuft er los, wenn ich dann f5 drücke, passiert nichts und wenn cih auf die lupe klicke, kommt diese Meldung: Zwischenablage04.jpg und dann stoppt er den Lauf, zeigt aber nichts an: Zwischenablage05.jpg oder mache ich was falsch?



> Ein Bluescreen kommt normalerweise nicht aus heiterem Himmel. Überprüfe den Speicher (memtest86). Könnte auch an anderer Hardware / Treibern (Viren?) liegen.


wie kann ich memtest86 durchführen? Kenne mich da leider nicht aus 

Das sind die Fehlermeldungen:
--------------------Konfiguration: Shutdown_new - Win32 Debug--------------------
Kompilierung läuft...
Shutdown_new.cpp
C:\Projekte\Programmierung\C++\Shutdown_new\Shutdown_new.cpp(73) : error C2065: 'EnumProcessModules' : nichtdeklarierter Bezeichner
C:\Projekte\Programmierung\C++\Shutdown_new\Shutdown_new.cpp(76) : error C2065: 'GetModuleBaseName' : nichtdeklarierter Bezeichner
C:\Projekte\Programmierung\C++\Shutdown_new\Shutdown_new.cpp(199) : error C2065: 'EnumProcesses' : nichtdeklarierter Bezeichner
Fehler beim Ausführen von cl.exe.

Shutdown_new.exe - 3 Fehler, 0 Warnung(en)

Gruß


----------



## deepthroat (8. Mai 2011)

Newbie8 hat gesagt.:


> So langsam komm ich mir echt bissl doof vor, also ich Start progmon.exe, gebe meinen Filter ein, klicke ok und dann läuft er los, wenn ich dann f5 drücke, passiert nichts und wenn cih auf die lupe klicke, kommt diese Meldung: Zwischenablage04.jpg und dann stoppt er den Lauf, zeigt aber nichts an: Zwischenablage05.jpg oder mache ich was falsch?


Und du führst auch einen Kompilierungslauf durch? Und in shutdown_new.cpp befindet sich auch eine #include <psapi.h> Anweisung? Ist shutdown_new.cpp der Code aus http://msdn.microsoft.com/en-us/library/ms682623.aspx?


Newbie8 hat gesagt.:


> wie kann ich memtest86 durchführen? Kenne mich da leider nicht aus


z.B. indem du das ISO Image hier (http://www.memtest86.com/download.html) runterlädst, auf eine CD(-RW) brennst und den Rechner damit startest.

Gruß


----------



## Newbie8 (9. Mai 2011)

Ich habe jetzt festgestellt, wann er die Fehlermeldung anzeigt, dass er  <psapi.h> nicht findet. Ich habe eine MFC-Anwendung und hatte die beiden BLöcke vertauscht:

#include "stdafx.h"
#include "Shutdown.h"
#include "ShutdownDlg.h"


#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <psapi.h>

Wenn ich mit dem windows.h Block anfange und den anderen darunter kopiere, dann kennt er die Funktionen EnumProcesses, EnumProcessModules,.. nicht. Wenn ich in der Reihenfolge verwende, in der es oben steht, kommt folgende Fehlermeldung:

fatal error C1083: Include-Datei kann nicht geöffnet werden: 'psapi.h': No such file or directory

Ich habe auch schon auf der msdn-Seite gesucht, aber ein SDK für Visual Studio C++ 6.0 habe ich bisher nicht gefunden. Hast du eine Idee, wo ich das herbekommen könnte bzw wie ich die psapi.h bekommen könnte? Oder müsste das bei meinem Visual C++ dabei sein und ich muss mich sozusagen an den Help Support meiner Firma wenden?

danke für den Tipp mit memtest86, werde ich auf jeden Fall ausprobieren. Hoff ich hab genügend Rechte um das auszuführen!

Viele Grüße


----------



## deepthroat (9. Mai 2011)

Newbie8 hat gesagt.:


> Ich habe jetzt festgestellt, wann er die Fehlermeldung anzeigt, dass er  <psapi.h> nicht findet. Ich habe eine MFC-Anwendung und hatte die beiden BLöcke vertauscht:
> 
> #include "stdafx.h"
> #include "Shutdown.h"
> ...


Seltsam.

Was steht denn in der stdafx.h?

Grundsätzlich: die stdafx.h *muss* die erste Datei sein, die du einbindest.


Newbie8 hat gesagt.:


> Ich habe auch schon auf der msdn-Seite gesucht, aber ein SDK für Visual Studio C++ 6.0 habe ich bisher nicht gefunden. Hast du eine Idee, wo ich das herbekommen könnte bzw wie ich die psapi.h bekommen könnte? Oder müsste das bei meinem Visual C++ dabei sein und ich muss mich sozusagen an den Help Support meiner Firma wenden?


Normalerweise ist eine Version des Platform SDKs bei VS dabei. Allerdings weiß ich nicht wie das bei VC++ 6 aussah (so alt bin ich noch nicht ). Die Version des SDKs ist dann z.B. nicht v6.0 sondern v6.0A.

Das aktuelle Windows SDK kann man hier runterladen: http://www.microsoft.com/downloads/...69-9671-4330-a63e-1fd44e0e2505&displaylang=en

\edit: Hab gerade gelesen, das VC++ 6.0 nicht von dem SDK unterstützt wird. Auf der Seite vom Windows Server 2003 R2 SDK (welches immerhin schon von 2006 ist) steht:





> The last SDK that will work with VC 6.0 is the February 2003 Edition, you can order a CD on the fulfillment site. Side by side installations are not supported.


Vermutlich mußt du mal in deiner Firma fragen ob sie dir mal das SDK installieren oder nicht endlich mal einen anständigen Compiler / IDE erwerben wollen...

Findest du denn eine tlhelp32.h auf deinem Rechner?


Newbie8 hat gesagt.:


> danke für den Tipp mit memtest86, werde ich auf jeden Fall ausprobieren. Hoff ich hab genügend Rechte um das auszuführen!


Wenn du CDs brennen darfst und der Rechner von CD bootet (bzw. du das im BIOS Setup einstellen darfst) ist alles OK.

Gruß


----------



## Newbie8 (9. Mai 2011)

Wollte grad mal die stdafx.h anhängen, dies ging aber nicht. Hier also der content:


```
// stdafx.h : Include-Datei für Standard-System-Include-Dateien,
//  oder projektspezifische Include-Dateien, die häufig benutzt, aber
//      in unregelmäßigen Abständen geändert werden.
//

#if !defined(AFX_STDAFX_H__B40B769D_81A7_4642_B53D_A9A61B1DBC72__INCLUDED_)
#define AFX_STDAFX_H__B40B769D_81A7_4642_B53D_A9A61B1DBC72__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define VC_EXTRALEAN		// Selten verwendete Teile der Windows-Header nicht einbinden

#include <afxwin.h>         // MFC-Kern- und -Standardkomponenten
#include <afxext.h>         // MFC-Erweiterungen
#include <afxdisp.h>        // MFC Automatisierungsklassen
#include <afxdtctl.h>		// MFC-Unterstützung für allgemeine Steuerelemente von Internet Explorer 4
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC-Unterstützung für gängige Windows-Steuerelemente
#endif // _AFX_NO_AFXCMN_SUPPORT


//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ fügt unmittelbar vor der vorhergehenden Zeile zusätzliche Deklarationen ein.

#endif // !defined(AFX_STDAFX_H__B40B769D_81A7_4642_B53D_A9A61B1DBC72__INCLUDED_)
```



> Grundsätzlich: die stdafx.h muss die erste Datei sein, die du einbindest.


Das wusste ich bisher nicht  Danke da hab ich wieder was gelernt 

Auf der Welt war ich schon als VC++ 6 rauskam, aber zum Programmieren war ich da auch noch bissl jung  Ist ja echt schon ganz schön alt *geschocktbin* Hatte die aktuelle Version mal heruntergeladen (war aber über einen anderen Link, da ich keine Netzversion hatte), beim Installieren meinte er dann natürlich dass die Version nicht übereinstimmen  Hatte nochmal über deinen Link die exe heruntergeladen, aber beim Installieren hatte er glaube ich ein Problem, da ich zwar lokale Adminrechte, aber über diese dann keinen Internetzugang  habe



> Findest du denn eine tlhelp32.h auf deinem Rechner?


Die gibt es  Findet er unter Microsoft Visual Studio\VC98\Include, gibt dort zB auch eine Process.h aber leider keinen psapi.h 



> Wenn du CDs brennen darfst und der Rechner von CD bootet (bzw. du das im BIOS Setup einstellen darfst) ist alles OK.


CDs brennen darf ich natürlich  das mit dem BIOS muss ich mal schauen, denk aber eigentlich schon

Gruß


----------



## deepthroat (9. Mai 2011)

Newbie8 hat gesagt.:


> Wollte grad mal die stdafx.h anhängen, dies ging aber nicht.


Du hättest die Endung (z.B. in .txt) ändern müssen.


Newbie8 hat gesagt.:


> Hier also der content:


OK, sieht ganz normal aus.

Das Problem ist wirklich die Reihenfolge. Wenn du vorkompilierte Header aktiviert hast (standardmäßig der Fall) werden alle #include Direktiven vor #include <stdafx.h> nicht wirklich ausgeführt. Deshalb gibt es keine Fehlermeldung und deswegen wird dann im ProcessExplorer nichts angezeigt.


Newbie8 hat gesagt.:


> Die gibt es  Findet er unter Microsoft Visual Studio\VC98\Include, gibt dort zB auch eine Process.h aber leider keinen psapi.h


Dann verwende doch die Toolhelp-Variante um Prozesse auszulesen. Nicht vergessen: erst stdafx.h einbinden, dann die anderen Header.

Gruß


----------



## Newbie8 (9. Mai 2011)

VIelen lieben Dank schon mal für deine tolle Hilfe. Bei der Toolhelp-Variante entstehen jetzt keine Fehler mehr, wenn ich den Code von der msdn-Seite kopiere, allerdings verstehe ich es noch nicht so ganz. Ich möchte den Prozess Apache.exe suchen und diesen dann herunterfahren. Ich würde in diesen Zweig kommen, da ich ja kein NT als Betriebssystem einsetze, ich verstehe allerdings nicht, wie ich an den Prozess herankomme.



```
} else if (osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS
         || (osver.dwPlatformId == VER_PLATFORM_WIN32_NT
         && osver.dwMajorVersion > 4)) {

      __try {

         hInstLib = LoadLibraryA("Kernel32.DLL");
         if (hInstLib == NULL)
            __leave;

         // If NT-based OS, load VDMDBG.DLL.
         if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
            hInstLib2 = LoadLibraryA("VDMDBG.DLL");
            if (hInstLib2 == NULL)
               __leave;
         }

         // Get procedure addresses. We are linking to 
         // these functions explicitly, because a module using
         // this code would fail to load under Windows NT,
         // which does not have the Toolhelp32
         // functions in KERNEL32.DLL.
         lpfCreateToolhelp32Snapshot =
               (HANDLE (WINAPI *)(DWORD,DWORD))
               GetProcAddress(hInstLib, "CreateToolhelp32Snapshot");

         lpfProcess32First =
               (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32))
               GetProcAddress(hInstLib, "Process32First");

         lpfProcess32Next =
               (BOOL (WINAPI *)(HANDLE,LPPROCESSENTRY32))
               GetProcAddress(hInstLib, "Process32Next");

         if (lpfProcess32Next == NULL
               || lpfProcess32First == NULL
               || lpfCreateToolhelp32Snapshot == NULL)
            __leave;

         if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT) {
            lpfVDMEnumTaskWOWEx = (INT (WINAPI *)(DWORD, TASKENUMPROCEX,
                  LPARAM)) GetProcAddress(hInstLib2, "VDMEnumTaskWOWEx");
            if (lpfVDMEnumTaskWOWEx == NULL)
               __leave;
         }

         // Get a handle to a Toolhelp snapshot of all processes.
         hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
         if (hSnapShot == INVALID_HANDLE_VALUE) {
            FreeLibrary(hInstLib);
            return FALSE;
         }

         // Get the first process' information.
         procentry.dwSize = sizeof(PROCESSENTRY32);
         bFlag = lpfProcess32First(hSnapShot, &procentry);

         // While there are processes, keep looping.
         while (bFlag) {
            
            // Call the enum func with the filename and ProcID.
            if (lpProc(procentry.th32ProcessID, 0,
                  procentry.szExeFile, lParam)) {

               // Did we just bump into an Apache?
               if (_stricmp(procentry.szExeFile, "Apache.EXE") == 0) {
//->er geht wirklich hier rein und hier würde ich dann den Prozess beenden wollen
                  // Fill in some info for the 16-bit enum proc.
                  sInfo.dwPID = procentry.th32ProcessID;
                  sInfo.lpProc = lpProc;
                  sInfo.lParam = (DWORD) lParam;
                  sInfo.bEnd = FALSE;

                  // Enum the 16-bit stuff.
                  lpfVDMEnumTaskWOWEx(procentry.th32ProcessID,
                     (TASKENUMPROCEX) Enum16, (LPARAM) &sInfo);

                  // Did our main enum func say quit?
                  if (sInfo.bEnd)
                     break;
               }

               procentry.dwSize = sizeof(PROCESSENTRY32);
               bFlag = lpfProcess32Next(hSnapShot, &procentry);

            } else
               bFlag = FALSE;
         }

      } __finally {

         if (hInstLib)
            FreeLibrary(hInstLib);

         if (hInstLib2)
            FreeLibrary(hInstLib2);
      }

   }
```

Bisher hatten wir den Prozess so gestartet:

```
PROCESS_INFORMATION piA;
		STARTUPINFO suiA;
		suiA.cb		=sizeof(STARTUPINFO);
		suiA.lpReserved	=0;
		suiA.lpDesktop	=NULL;
		suiA.lpTitle	=NULL;
		suiA.dwX		=0;
		suiA.dwY		=0;
		suiA.dwXSize	=0;
		suiA.dwYSize	=0;
		suiA.dwXCountChars	=0;
		suiA.dwYCountChars	=0;
		suiA.dwFillAttribute	=0;
		suiA.dwFlags	=STARTF_USESHOWWINDOW;
		suiA.wShowWindow	=SW_MINIMIZE;
		suiA.cbReserved2	=0;
		suiA.lpReserved2	=0;
//strApache = Pfad zum Apache -k start
		if(CreateProcess(NULL,strApache,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiA,&piA)==TRUE) {
			//CloseHandle(piA.hThread);
		}
		WaitForInputIdle(piA.hProcess,INFINITE);

//Beenden von APache:
// Apache herunterfahren
		strcat(strApache, " -k shutdown");
		if(CreateProcess(NULL,strApache,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiA,&piA)==TRUE) {
			CloseHandle(piA.hThread);
		}
```

Das Beenden würde ich jetzt in meinem Testprogramm aufnehmen wollen, nachdem ich den Apache.exe-Prozess gefunden habe. Kannst du mir hier auch nochmal einen Tipp geben?

LG


----------



## deepthroat (9. Mai 2011)

Newbie8 hat gesagt.:


> VIelen lieben Dank schon mal für deine tolle Hilfe. Bei der Toolhelp-Variante entstehen jetzt keine Fehler mehr, wenn ich den Code von der msdn-Seite kopiere, allerdings verstehe ich es noch nicht so ganz. Ich möchte den Prozess Apache.exe suchen und diesen dann herunterfahren. Ich würde in diesen Zweig kommen, da ich ja kein NT als Betriebssystem einsetze


Doch, du setzt ein NT Betriebssystem ein. Wo hast du denn diesen Code gefunden? Du kannst doch die Funktionen einfach implizit linken lassen und mußt nicht LoadLibrary etc. verwenden...


Newbie8 hat gesagt.:


> ich verstehe allerdings nicht, wie ich an den Prozess herankomme.


Was meinst du denn mit "herankommen". Was genau willst du denn mit dem Prozess machen?

Gruß


----------



## Newbie8 (9. Mai 2011)

Also eigentlich habe ich XP installiert. das ist doch kein NT Betriebssystem oder? Hier habe ich den Code her: http://support.microsoft.com/kb/175030/de, zumindest geht er in den Zweig "// If any OS other than Windows NT 4.0"

Also ich möchte gerne den Prozess Apache.exe finden und dann den Apache herunterfahren und somit den Prozess beenden. Den Apache würde ich mit "Verzeichnis der Apache.exe/Apache.exe" -f "Verzeichnis der httpd.conf/httpd.conf" -k shutdown herunterfahren, brauche aber dazu den wirklich laufenden Prozess, weil er sonst leider nicht wartet, bis er wirklich heruntergefahren ist. Ich hoffe, du versteht wie ich das meine 

LG


----------



## Newbie8 (9. Mai 2011)

Ich habe jetzt mal probiert, die exe auf unserem Vista-Rechner laufen zu lassen. Leider kam da die Fehlermeldung "Die Anwendung konnte nicht gestartet werden, weil MFC42D.DLL nicht gefunden wurde. Neuinstallation der Anwendunge könnte das Problem beheben". Hast du ne Idee woran das liegen könnte? Muss ich die DLL wirklich neu installieren oder läuft der Code einfach nicht unter Vista 

LG


----------



## deepthroat (9. Mai 2011)

Newbie8 hat gesagt.:


> Also eigentlich habe ich XP installiert. das ist doch kein NT Betriebssystem oder?


Doch Windows 2000, XP, Vista usw. sind alles NT Betriebssysteme. Siehe z.B. http://de.wikipedia.org/wiki/Windows_NT


Newbie8 hat gesagt.:


> Hier habe ich den Code her: http://support.microsoft.com/kb/175030/de, zumindest geht er in den Zweig "// If any OS other than Windows NT 4.0"


Wenn dein Code nicht auf älteren Betriebssystemen als Windows 2000 laufen soll, schau mal hier: http://msdn.microsoft.com/en-us/library/ms686701(v=vs.85).aspx

Der Code ist doch viel einfacher.


Newbie8 hat gesagt.:


> Also ich möchte gerne den Prozess Apache.exe finden und dann den Apache herunterfahren und somit den Prozess beenden. Den Apache würde ich mit "Verzeichnis der Apache.exe/Apache.exe" -f "Verzeichnis der httpd.conf/httpd.conf" -k shutdown herunterfahren, brauche aber dazu den wirklich laufenden Prozess, weil er sonst leider nicht wartet, bis er wirklich heruntergefahren ist. Ich hoffe, du versteht wie ich das meine


Dann mußt du doch nur das szExeFile Element der PROCESSENTRY32 Struktur untersuchen. Siehe http://msdn.microsoft.com/en-us/library/ms684839(v=vs.85).aspx


> szExeFile
> The name of the executable file for the process. To retrieve the full path to the executable file, call the Module32First function and check the szExePath member of the MODULEENTRY32 structure that is returned. However, if the calling process is a 32-bit process, you must call the QueryFullProcessImageName function to retrieve the full path of the executable file for a 64-bit process.


Gruß


----------



## Newbie8 (12. Mai 2011)

Jetzt bräuchte idh doch nochmal deinen Rat. Ich habe den Code verwendet, den du mir empfohlen hast. stimmt der ist viel einfacher 

Ich dachte, so könnte ich den Prozess dann suchen und beenden. Er findet zwar den Prozess, OpenProcess funktioniert auch, zumindest kommt er nicht in den if-Zweig. Er geht in den else-Zweig, läuft da schön durch, aber er beendet den Prozess nicht. Was mache ich falsch? 


```
if(strcmp(pe32.szExeFile, "Apache.exe")==0){
		MessageBox(NULL, pe32.szExeFile, "", MB_OKCANCEL);
		hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID );
		if( hProcess == NULL ){
			printError( TEXT("OpenProcess") );
		}else
		{
			MessageBox(NULL, "ungelcih null", "", MB_OKCANCEL);
			dwPriorityClass = GetPriorityClass( hProcess );
			if( !dwPriorityClass )
			printError( TEXT("GetPriorityClass") );
			CloseHandle( hProcess );
		    WaitForInputIdle(hProcess, INFINITE);
		    while(WaitForSingleObject(hProcess, 10000) == WAIT_TIMEOUT) {
			}
            MessageBox(NULL, "weiter", "", MB_OKCANCEL);
		}

		_tprintf( TEXT("\n  Process ID        = 0x%08X"), pe32.th32ProcessID );
		_tprintf( TEXT("\n  Thread count      = %d"),   pe32.cntThreads );
		_tprintf( TEXT("\n  Parent process ID = 0x%08X"), pe32.th32ParentProcessID );
		_tprintf( TEXT("\n  Priority base     = %d"), pe32.pcPriClassBase );

		if( dwPriorityClass ){
			_tprintf( TEXT("\n  Priority class    = %d"), dwPriorityClass );
		}
		// List the modules and threads associated with this process
		ListProcessModules( pe32.th32ProcessID );
		ListProcessThreads( pe32.th32ProcessID );
	}
```


----------



## deepthroat (12. Mai 2011)

Hi.

Was willst du denn nun machen? Warum sollte sich der Prozess jetzt beenden? Du besorgst dir ein Handle, liest die Priorität aus und schließt das Handle wieder. Danach greifst du weiter auf das Handle zu. Das macht keinen Sinn.

Ich dachte du willst Apache ordentlich herunterfahren? Willst du den Prozess einfach abschießen?

Gruß


----------



## Newbie8 (12. Mai 2011)

Hey ;-)

hab auch grad gemerkt dass man ja mit closeHandle gar nicht den Prozess herunterfährt sondern nur schließt. Sagt der Name ja eigentlich auch aus ;-) weiß auch nicht, hatte grad wohl nen Brett vor dem Kopf. 

Stimmt will ihn ordentlich herunterfahren. Wenn ich nur wüsste, wie ich das dem Prozess sagen kann. Mit TerminateProcess wird er da ordentlich heruntergefahren oder ist das mehr ein schnelles Killen des Prozesses. Was gebe ich eigentlich als Rechte bei open_process am besten an, dass es unter XP und Vista läuft? Ich dachte ich muss eigentlich CreateProcess machen, um den APache herunterzufahren und dann müsste ich ja eigentlich warten bis hProcess wirklich beendet ist. aber irgendwie passt das noch nicht so ganz, kopiere dir nochmal meinen geänderten Code hierrein.


```
if(strcmp(pe32.szExeFile, "Apache.exe")==0){
		MessageBox(NULL, pe32.szExeFile, "", MB_OKCANCEL);
		hProcess = OpenProcess( PROCESS_CREATE_PROCESS, FALSE, pe32.th32ProcessID );
		if( hProcess == NULL ){
			printError( TEXT("OpenProcess") );
		}else
		{
			MessageBox(NULL, "ungelcih null", "", MB_OKCANCEL);
			dwPriorityClass = GetPriorityClass( hProcess );
			/*if( !dwPriorityClass )
			//printError( TEXT("GetPriorityClass") );
			MessageBox(NULL, "GetPriorityClass", "", MB_OKCANCEL);
			*/

			PROCESS_INFORMATION piA;
			STARTUPINFO suiA;
			suiA.cb		=sizeof(STARTUPINFO);
			suiA.lpReserved	=0;
			suiA.lpDesktop	=NULL;
			suiA.lpTitle	=NULL;
			suiA.dwX		=0;
			suiA.dwY		=0;
			suiA.dwXSize	=0;
			suiA.dwYSize	=0;
			suiA.dwXCountChars	=0;
			suiA.dwYCountChars	=0;
			suiA.dwFillAttribute	=0;
			suiA.dwFlags	=STARTF_USESHOWWINDOW;
			suiA.wShowWindow	=SW_MINIMIZE;
			suiA.cbReserved2	=0;
			suiA.lpReserved2	=0;
			if(CreateProcess(NULL,strApacheShutdown,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiA,&piA)==TRUE) {
				CloseHandle(piA.hThread);
			}
			else {
				//exit(-1);
			}

			WaitForInputIdle(piA.hProcess, INFINITE);
			while(WaitForSingleObject(piA.hProcess, 10000) == WAIT_TIMEOUT) {
			}
			WaitForInputIdle(hProcess, INFINITE);
			while(WaitForSingleObject(hProcess, 10000) == WAIT_TIMEOUT) {
			}
			//MessageBox(NULL, "weiter", "", MB_OKCANCEL);
			if(CloseHandle( hProcess )==0){
			//	MessageBox(NULL, "nicht beendet", "", MB_OKCANCEL);
			}else{
			//	MessageBox(NULL, "beendet", "", MB_OKCANCEL);
			}
            //MessageBox(NULL, "weiter", "", MB_OKCANCEL);
		}

		if( dwPriorityClass ){
			_tprintf( TEXT("\n  Priority class    = %d"), dwPriorityClass );
		}
		// List the modules and threads associated with this process
		ListProcessModules( pe32.th32ProcessID );
		ListProcessThreads( pe32.th32ProcessID );
	}
```

Vielleicht kannst du mir sagen, was nicht passt, bzw irgendwie scheint es schon zu passen, irgendwann beenden sich die Apache.exe aber viel später wie ich möchte, v.a. möchte ich ja sozusagen abwarten bis er heruntergefahren ist und anschließend die log-Dateien vom Apache löschen, die sich ja erst löschen lassen, wenn er wirklich heruntergefahren ist und deswegen muss ich den Zeitpunkt herausfinden. 

Gruß


----------



## deepthroat (12. Mai 2011)

Das Beenden von Apache über "apache -k stop" funktioniert nur wenn Apache als Service registriert ist. Ist das bei dir der Fall? Hast du denn das mal per Hand ausprobiert, ob es klappt bevor du versuchst das in dein Programm einzubauen?

Was ist dann der Return-Code des "strApacheShutdown" Befehls?

Ich habe irgendwie immer noch nicht ganz verstanden welches Problem du versuchst zu lösen. Was ist denn das Ziel des Programmes bzw. worin unterscheidet es sich von anderen Programmen (pskill)?

Gruß


----------



## Newbie8 (12. Mai 2011)

Also ich habe probiert den Apache mit apache -k shutdown herunterzufahren, das klappt

Im strApacheShutdown steht folgendes: PfadzumApache\Apache.exe -f Pfad zu httpd\httpd.conf -k shutdown

Also das Problem ist folgendes: wir haben eine start.exe, in der ein paar Sachen geprüft bzw gesetzt werden, die wir für die Software brauchen, dann wird der Apache gestartet und anschließend der Internet Explorer mit einer Startseite gestartet. Im start-exe-Programm hatten wir es so programmiert dass der Apache solange läuft bis der Internet Explorer geschlossen wird. Dies hat bei XP einwandfrei funktioniert, aber bei Vista geht es nicht, weil der Prozess vom IE wohl schon kurz nach dem Starten geschlossen wird. Ich hatte da recht lange gegoogelt und da haben die meisten geschrieben, dass das Sicherheitskonzept bei Vista anders ist und der Prozess daher dann schon am Anfang beendet wird und man den nicht so einfach überwachen kann. Daher dachten wir dass wir auf unserer Software einfach einen Button einfügen, über den dann die Seite geschlossen wird und der Apache heruntergefahren wird und die log-Dateien vom Apache gelöscht werden sollen, zusätzlich müsste eben noch die Kopf-/Fußzeile auf den Wert gesetzt werden, bevor das Programm lief, sonst hätten wir das auch einfach über eine .bat-Datei machen können. 

Ich hoffe du kannst jetzt verstehen was ich machen möchte 
Gruß


----------



## deepthroat (12. Mai 2011)

Und wozu willst du den Apache Prozeß finden? Ich dachte anfangs du willst den Pfad zur Apache .exe ermitteln, aber wie es aussieht kannst du davon ausgehen, dass du den Pfad kennst.

So wie ich das sehe würde doch reichen:

```
int ret = system(strApacheShutdown);
if (ret == 0) {
  // erfolgreich gestoppt.
} else if (ret == 2) {
  // Fehler. Service nicht installiert
} else {
  // anderer Fehler, Datei nicht gefunden...
}
```
Gruß


----------



## Newbie8 (12. Mai 2011)

Ich möchte abfragen ab wann alle Apache-Prozesse wirklich nicht mehr laufen, um anschließend die log-Dateien löschen zu können, die noch gesperrt sind, solange der Prozess noch läuft. Das fehlt mir bisher noch, zu wissen, jetzt läuft wirklich kein Apache-Prozess mehr, denn dann bleiben die log-Dateien liegen und werden mit der Zeit immer größer weil er bei jedem Starten dann die Infos einfach anhängt. 

Muss sagen, das mit system (strApacheShutdown) habe ich bisher nicht ausprobiert, werd ich dann gleich mal machen 

Wobei es denk am besten wäre, eine Funktion zu haben, die wirklich prüft ob alle Apache.exe's geschlossen sind. Blöd ist nämlich dass im Taskmanager auch noch 2 Apache.exe stehen, ich denke das liegt daran dass wir einmal eine Eingabeaufforderung haben, in der steht, dass der Apache läuft und dann noch die Apache.exe selber, anders kann ichs mir nicht erklären, weil wir mit CreateProcess eigentlich nur einmal den Apache starten. 

Ganz schön kompliziert 
Gruß


----------



## Newbie8 (12. Mai 2011)

Irgendwie ist das echt komisch. Normalerweise sollte doch WaitforsingleObject warten bis der Prozess beendet ist, ich habe ja 10Sekunden eingestellt, aber er wartet gar nicht, sondern gibt ca. 1Sekunde später eine Message aus, die ich beim Löschen der Logs eingebaut habe, um zu sehen ob er schon löscht bevor der Apache heruntergefahren ist. wieso wartet er nicht? Habe ja diese While-Schleife mit Wait_timeout falls der Apache sich mal nicht runterfahren lässt, nicht dass er sonst hängenbleibt.

Hast du ne Idee wieso er nicht wartet bis hProcess wirklich beendet ist?

Gruß


----------



## deepthroat (12. Mai 2011)

Newbie8 hat gesagt.:


> Wobei es denk am besten wäre, eine Funktion zu haben, die wirklich prüft ob alle Apache.exe's geschlossen sind.


Und was willst du machen wenn es nicht so ist?

Könnte doch sein, das noch andere Apachen laufen, außer dem den du verwalten willst.


Newbie8 hat gesagt.:


> Blöd ist nämlich dass im Taskmanager auch noch 2 Apache.exe stehen, ich denke das liegt daran dass wir einmal eine Eingabeaufforderung haben, in der steht, dass der Apache läuft und dann noch die Apache.exe selber, anders kann ichs mir nicht erklären, weil wir mit CreateProcess eigentlich nur einmal den Apache starten.


Je nachdem startet Apache evlt. Kindprozesse von sich selbst.


Newbie8 hat gesagt.:


> Irgendwie ist das echt komisch. Normalerweise sollte doch WaitforsingleObject warten bis der Prozess beendet ist, ich habe ja 10Sekunden eingestellt, aber er wartet gar nicht, sondern gibt ca. 1Sekunde später eine Message aus, die ich beim Löschen der Logs eingebaut habe, um zu sehen ob er schon löscht bevor der Apache heruntergefahren ist. wieso wartet er nicht? Habe ja diese While-Schleife mit Wait_timeout falls der Apache sich mal nicht runterfahren lässt, nicht dass er sonst hängenbleibt.
> 
> Hast du ne Idee wieso er nicht wartet bis hProcess wirklich beendet ist?


Was ist der Rückgabewert der Funktion? Falls WAIT_FAILED, was gibt GetLastError zurück?

Warum nimmst du nicht einfach system()?

Gruß


----------



## Newbie8 (12. Mai 2011)

Da hast du recht, könnten natürlich noch andere Apache laufen. sollten aber eigentlich nicht, aber könnte natürlich sein. Eigentlich möchte ich nur wissen, wann mein Apache heruntergefahren ist, um anschließend über c++ die log-Dateien zu löschen. Sollte doch eigentlich möglich sein.



> Je nachdem startet Apache evlt. Kindprozesse von sich selbst.


Denke auch dass das einfach ein Kindprozess ist 



> Was ist der Rückgabewert der Funktion? Falls WAIT_FAILED, was gibt GetLastError zurück?


Erhlichgesagt weiß ich nicht ob ich das richtig mache. Da ich Ausageben irgendwie über cout oder so nicht bekomme, sondern das immer über MessageBox mache *shameOnMe* ich habe es jetzt so gemacht: 
sprintf(buffer, "%d", GetLastError());
MessageBox(NULL, buffer, "", MB_OKCANCEL);

da kommt dann error 5 raus, aber damit kann man nichts anfangen oder?

mit system beendet er zwar den Apache aber ich weiß dann doch trotzdem nciht den Zeitpunkt, wann er mit dem Herunterfahren des Apache's fertig ist oder wie könnte ich das herausfinden, wenn ich system() verwende. ich möchte ja wissen, wann alle Kindprozesse sozusagen beendet sind, um die log-dateien zu löschen

Gruß


----------



## deepthroat (12. Mai 2011)

Newbie8 hat gesagt.:


> Erhlichgesagt weiß ich nicht ob ich das richtig mache. Da ich Ausageben irgendwie über cout oder so nicht bekomme, sondern das immer über MessageBox mache *shameOnMe* ich habe es jetzt so gemacht:
> sprintf(buffer, "%d", GetLastError());
> MessageBox(NULL, buffer, "", MB_OKCANCEL);
> 
> da kommt dann error 5 raus, aber damit kann man nichts anfangen oder?


5 == ERROR_ACCESS_DENIED


Newbie8 hat gesagt.:


> mit system beendet er zwar den Apache aber ich weiß dann doch trotzdem nciht den Zeitpunkt, wann er mit dem Herunterfahren des Apache's fertig ist oder wie könnte ich das herausfinden, wenn ich system() verwende. ich möchte ja wissen, wann alle Kindprozesse sozusagen beendet sind, um die log-dateien zu löschen


system() führt ein Programm synchron aus. Der Apache Service wird über "net stop" beendet und wenn das Programm beendet ist und einen Rückgabewert von 0 hatte, ist auch der Apache beendet.

Du könntest ja evtl. auch  einfach die Logdateien löschen bevor du den Apache startest.

Gruß


----------



## Newbie8 (12. Mai 2011)

Was ich interessant finde, ich habe ja im TaskManager 2 Apache.exe, also ein Kindelement und einmal den richtigen Prozess. Dadurch geht er die Schleife if(strcmp(pe32.szExeFile, "Apache.exe")==0){...} zweimal durch, aber wenn ich if(WaitForSingleObject(hProcess, 10000) == WAIT_FAILED){} verwende, dann kommt ja bei GetLastError() 5 zurück, was wohl heißt "Access denied", soweit ich das gegoogelt habe, hoffe das stimmt. Dann kommt er beim 2.mal 
    if(strcmp(pe32.szExeFile, "Apache.exe")==0){
    hProcess = OpenProcess( PROCESS_CREATE_PROCESS, FALSE, pe32.th32ProcessID );
    if(hProcess ==null){
    }else{
    }       
in die Schleife dass hprocess gleich null ist, wenn ich das if .... ==WAIT_FAILED auskommentiere, geht er den else-Zweig hProcess!=null zweimal durch. 

WEnn ich nur wüsste, wie ich das anstellen soll. Eigentlich würde mir ja Apache herunterfahren mittel system() reichen und dann bräuchte ich noch eine Funktion, die prüft wann er denn wirklich heruntergefahren ist, aber irgendwie scheint das ja nicht zu gehen, weil er das ja eigentlich bei WaitForSingeObject tun sollte, wenn ich das richtig verstanden habe?

Gruß


----------



## deepthroat (13. Mai 2011)

Hi.

Letztendlich ist doch völlig egal ob da noch ein Apache Prozess läuft oder nicht. Es könnten auch andere Programme die Log-Dateien geöffnet haben (Anti-Virus Software,  Backup Software, File Indexing Software, File Viewer etc.), so dass du die Dateien dann auch nicht löschen kannst.

Versuche einfach den Apache runter zu fahren und danach versuche die Dateien zu löschen, nach dem gleichen Schema wie es hier (http://support.microsoft.com/?scid=kb;en-us;316609&x=17&y=20) beschrieben ist.

Gruß


----------



## Newbie8 (13. Mai 2011)

> 5 == ERROR_ACCESS_DENIED


Das kann man sozusagen nicht irgendwie umgehen oder?



> system() führt ein Programm synchron aus. Der Apache Service wird über "net stop" beendet und wenn das Programm beendet ist und einen Rückgabewert von 0 hatte, ist auch der Apache beendet.


Der Befehl wurde vielleicht dann erfolgreich ausgeführt, aber bis der Apache wirklich heruntergefahren ist, dauerts oft noch ein paar Sekdunen.



> Du könntest ja evtl. auch einfach die Logdateien löschen bevor du den Apache startest.


Ja ist auch eine Möglichkeit aber schöner wäre es anders geklappt hätte, so muss ich ja prüfen, ob es die logs gibt, wenn ja dann löschen.



> Hi.
> 
> Letztendlich ist doch völlig egal ob da noch ein Apache Prozess läuft oder nicht. Es könnten auch andere Programme die Log-Dateien geöffnet haben (Anti-Virus Software, Backup Software, File Indexing Software, File Viewer etc.), so dass du die Dateien dann auch nicht löschen kannst.


ja das stimmt schon, verstehe halt nicht, wieso ich nicht das Recht habe, den Apache zu beenden bzw den Prozess zu beobachten und zu warten bis er beendet ist. denn ich habe ihn ja gestartet, aber gut anscheinend muss ich damit leben, dass ich den Apache herunterfahren kann aber es nicht klappt, ein Signal zu bekommen (also so lange zu warten) bis er wirklich heruntergefahren ist, um die logs anschleißend zu löschen.



> Versuche einfach den Apache runter zu fahren und danach versuche die Dateien zu löschen, nach dem gleichen Schema wie es hier (http://support.microsoft.com/?scid=k...6609&x=17&y=20) beschrieben ist.
> 
> Gruß


Kann ich die Dateien nicht auch einfach mit DeleteFile(strHTTPD); löschen? 

Viele Grüße und vielen Dank im Voraus


----------



## Newbie8 (13. Mai 2011)

Habe jetzt nochmal eine Frage, habe bisher das Programm ja nur mittels klick auf die exe getestet, habe es jetzt mal in das Programm integriert, in dem ich es verwenden möchte und anscheinend wird die Internet Explorer Seite zu langsam geschlossen bzw alle Prozesse die dazugehören, so dass er bei system Probleme macht und bei GetProcessList() den Apache-Prozess nicht beendet. Habe jetzt überlegt ob vielleicht ein sleep() helfen könnte. Weißt du welche .h ich da includen müsste, dass es funktioniert bzw. hast du eine Idee, was ich sonst machen könnte? So langsam bin ich echt gefrustet 

Gruß


----------



## deepthroat (13. Mai 2011)

Newbie8 hat gesagt.:


> Das kann man sozusagen nicht irgendwie umgehen oder?


Laut MSDN:


> PROCESS_ALL_ACCESS	All possible access rights for a process object.
> Windows Server 2003 and Windows XP/2000:  The size of the PROCESS_ALL_ACCESS flag increased on Windows Server 2008 and Windows Vista. If an application compiled for Windows Server 2008 and Windows Vista is run on Windows Server 2003 or Windows XP/2000, the PROCESS_ALL_ACCESS flag is too large and the function specifying this flag fails with *ERROR_ACCESS_DENIED*. To avoid this problem, specify the minimum set of access rights required for the operation. If PROCESS_ALL_ACCESS must be used, set _WIN32_WINNT to the minimum operating system targeted by your application (for example,
> #define _WIN32_WINNT _WIN32_WINNT_WINXP
> ). For more information, see Using the Windows Headers.


Evtl. ist das das Problem.


Newbie8 hat gesagt.:


> Der Befehl wurde vielleicht dann erfolgreich ausgeführt, aber bis der Apache wirklich heruntergefahren ist, dauerts oft noch ein paar Sekdunen.


Hast du das wirklich ausprobiert? Das kann ich mir eigentlich nicht vorstellen, der "net stop" Befehl wartet eigentlich extrem lange bis ein Service wirklich gestoppt wurde.


Newbie8 hat gesagt.:


> Ja ist auch eine Möglichkeit aber schöner wäre es anders geklappt hätte, so muss ich ja prüfen, ob es die logs gibt, wenn ja dann löschen.


Generell ist es besser etwas einfach zu versuchen und dann zu prüfen ob es geklappt hat. Vorher zu prüfen ob die Datei da ist kann man sich sparen, man weiß dann ja trotzdem nicht ob das Löschen erfolgreich ist. Wenn du ERROR_FILE_NOT_FOUND zurück bekommst, dann ist doch auch OK.


Newbie8 hat gesagt.:


> ja das stimmt schon, verstehe halt nicht, wieso ich nicht das Recht habe, den Apache zu beenden bzw den Prozess zu beobachten und zu warten bis er beendet ist. denn ich habe ihn ja gestartet, aber gut anscheinend muss ich damit leben, dass ich den Apache herunterfahren kann aber es nicht klappt, ein Signal zu bekommen (also so lange zu warten) bis er wirklich heruntergefahren ist, um die logs anschleißend zu löschen.


Als Service wird der Apache vermutlich unter einem System-Konto ausgeführt, eben nicht unter dem gleichen Konto.


Newbie8 hat gesagt.:


> Kann ich die Dateien nicht auch einfach mit DeleteFile(strHTTPD); löschen?


Nein. Lies dir den Artikel durch. Es kann immer irgendwelche (gleichzeitigen) Zugriffe auf Dateien geben. Damit muss man leben und entsprechend handeln.

Du solltest dir Gedanken machen was du willst und vor allem was du machst wenn etwas schief geht.

Was ist wenn der Apache nicht runterfährt? Willst du ewig auf das Beenden vom Häuptling warten?

Was ist wenn du die Datei nicht löschen kannst obwohl der Apache runtergefahren ist (weil ein anderer Prozess die Datei geöffnet hat oder weil du gar nicht die Rechte hast)?

Bei mir funktioniert folgendes einwandfrei:

```
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    int ret = system("c:/xampp/apache/bin/httpd -k shutdown");
    if (ret != 0) {
        perror("apache shutdown");
        return ret;
    } else {
        int retries = 0;
        const int maxRetries = 20;
        const int wait_msecs = 250;
        int err = ERROR_SUCCESS;

        while (++retries <= maxRetries &&
               !DeleteFile("c:/xampp/apache/logs/error.log") &&
               (err = GetLastError()) == ERROR_SHARING_VIOLATION)
        {
            puts("waiting...");
            fflush(stdout);
            Sleep(wait_msecs);
        }
        if (err == ERROR_FILE_NOT_FOUND ||
            err == ERROR_SUCCESS)
        {
            return 0;
        } else {
            return 1;
        }
    }
}
```
Ich habe jedesmal die Ausgabe bekommen:

```
The Apache2.2 service is stopping.
The Apache2.2 service has stopped.
```
In keinem Fall wurde die Schleife betreten.

Gruß


----------



## deepthroat (13. Mai 2011)

Newbie8 hat gesagt.:


> Habe jetzt nochmal eine Frage, habe bisher das Programm ja nur mittels klick auf die exe getestet, habe es jetzt mal in das Programm integriert, in dem ich es verwenden möchte und anscheinend wird die Internet Explorer Seite zu langsam geschlossen bzw alle Prozesse die dazugehören, so dass er bei system Probleme macht


Dann mach einfach mehrere Versuche.

Gruß


----------



## Newbie8 (13. Mai 2011)

Weil du meintest ich soll sonst einfach mehrere Versuche machen, wenn ich das mit system eingebunden habe, kommt folgende Fehlermeldung, daher hab ich dann doch wieder zu der GetProcessFile()-Version tendiert. Aber vielleicht weißt du ja auch was ich falsch gemacht habe. 

Gruß


----------



## deepthroat (13. Mai 2011)

Newbie8 hat gesagt.:


> Weil du meintest ich soll sonst einfach mehrere Versuche machen, wenn ich das mit system eingebunden habe, kommt folgende Fehlermeldung, daher hab ich dann doch wieder zu der GetProcessFile()-Version tendiert. Aber vielleicht weißt du ja auch was ich falsch gemacht habe.


Du hast offenbar einfach einen leeren String an die system() Funktion übergeben. Das macht keinen Sinn.

Gruß


----------



## Newbie8 (13. Mai 2011)

deepthroat hat gesagt.:


> Laut MSDN:
> 
> Evtl. ist das das Problem.
> 
> Hast du das wirklich ausprobiert? Das kann ich mir eigentlich nicht vorstellen, der "net stop" Befehl wartet eigentlich extrem lange bis ein Service wirklich gestoppt wurde.


Es lag daran dass ich PROCESS_CREATE_PROCESS verwendet hatte, anstatt SYNCHRONIZE. Dadurch kommt jetzt kein ACCESS DENIED mehr und er wartet wirklich bis er heruntergefahren ist, zumindest wenn ich es per Klick auf exe und nicht auf den Button ausführe. 


> Generell ist es besser etwas einfach zu versuchen und dann zu prüfen ob es geklappt hat. Vorher zu prüfen ob die Datei da ist kann man sich sparen, man weiß dann ja trotzdem nicht ob das Löschen erfolgreich ist. Wenn du ERROR_FILE_NOT_FOUND zurück bekommst, dann ist doch auch OK.
> <


stimmt schon 



> Als Service wird der Apache vermutlich unter einem System-Konto ausgeführt, eben nicht unter dem gleichen Konto.


Nein da der Apache mit dem Anklicken einer exe gestartet wird, wird er sozusagen mit dem gleichen Konto ausgeführt. 



> Was ist wenn der Apache nicht runterfährt? Willst du ewig auf das Beenden vom Häuptling warten?


Nein will ich natürlich nicht, wenn ich ihn nicht herunterfahren kann, dann läuft er halt weiter. Daher hatte ich ja auch nur 2 Sekunden als Timeout eingestellt und nicht INFINITE, zumindest in der eigentlichen Version. Kann sein dass ichs zwischendurch mal geändert hatte, aber jetzt hab ichs so geändert:


```
if(strcmp(pe32.szExeFile, "Apache.exe")==0){
		hProcess = OpenProcess( SYNCHRONIZE , FALSE, pe32.th32ProcessID );
		if( hProcess == NULL ){
			printError( TEXT("OpenProcess") );
		}else
		{
			dwPriorityClass = GetPriorityClass( hProcess );

			PROCESS_INFORMATION piA;
			STARTUPINFO suiA;
			suiA.cb		=sizeof(STARTUPINFO);
			suiA.lpReserved	=0;
			suiA.lpDesktop	=NULL;
			suiA.lpTitle	=NULL;
			suiA.dwX		=0;
			suiA.dwY		=0;
			suiA.dwXSize	=0;
			suiA.dwYSize	=0;
			suiA.dwXCountChars	=0;
			suiA.dwYCountChars	=0;
			suiA.dwFillAttribute	=0;
			suiA.dwFlags	=STARTF_USESHOWWINDOW;
			suiA.wShowWindow	=SW_MINIMIZE;
			suiA.cbReserved2	=0;
			suiA.lpReserved2	=0;
			if(CreateProcess(NULL,strApacheShutdown,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiA,&piA)==TRUE) {
				CloseHandle(piA.hThread);
			}
			

			WaitForInputIdle(piA.hProcess, INFINITE);
			while(WaitForSingleObject(piA.hProcess, 10000) == WAIT_TIMEOUT) {
			}

			WaitForInputIdle(hProcess, INFINITE);
			while(WaitForSingleObject(hProcess, 2000) == WAIT_TIMEOUT) {
			}

			CloseHandle( hProcess );
		}		
	}
```

Ich hatte Sleep() immer klein geschrieben, deswegen ging es nicht ;-) Danke für dein Code-Beispiel. Muss ich mal versuchen bei mir beim Löschen einzubinden. Das mit dem system werde ich auch so mal ausprobieren, aber anscheinend mag er das ja nicht aus javascript heraus. (siehe Screenshot von vorherigem Beitrag von mir)

Hast du eine Idee woran es liegen könnte, dass es funktioniert, wenn ich die exe per Maus-Klick ausführe, wenn ich aber einen Button klicke und dann sage 

document.location.href="http://localhost/cgi-bin/test.exe"; 

dann beendet er den Apache auf einmal nicht mehr

Viele Grüße


----------



## Newbie8 (13. Mai 2011)

> Du hast offenbar einfach einen leeren String an die system() Funktion übergeben. Das macht keinen Sinn.
> 
> Gruß


Du hast natürlich recht! Ich habe jetzt mal vorher ein paar MessageBox-Ausgaben gemacht, wenn ich die exe per Klick ausführe, dann sagt er mir dass mein Temp-File unter C:\Documents and Settings\UserName\Local Settings\Temp ist, wenn ich die exe über den Button ausführe, dann sagt er mir bei GetTempPath, dass das C:\Windows wäre und da findet er dann meine log-Datei nicht, in der der Pfad zum Apache steht (in der unter anderem steht wie die Kopf-/Fußzeile vor dem Ausführen der start.exe war, damit er sie zurücksetzen kann)  Siehst du da eine Möglichkeit, dass er auch vom Button aus das Temp-Verzeichnis unter Documents and Settings findet?

Gruß und vielen lieben Dank für deine Hilfe


----------



## deepthroat (13. Mai 2011)

Newbie8 hat gesagt.:


> Nein da der Apache mit dem Anklicken einer exe gestartet wird, wird er sozusagen mit dem gleichen Konto ausgeführt.


Dann wird er nicht als Service gestartet und kann demnach auch nicht über die -k shutdown Methode beendet werden.

Vermutlich startest du aber über -k start, womit der Apache als Service unter dem in den Serviceeigenschaften eingestellten lokalen Systemkonto gestartet wird?!


Newbie8 hat gesagt.:


> Nein will ich natürlich nicht, wenn ich ihn nicht herunterfahren kann, dann läuft er halt weiter. Daher hatte ich ja auch nur 2 Sekunden als Timeout eingestellt und nicht INFINITE, zumindest in der eigentlichen Version. Kann sein dass ichs zwischendurch mal geändert hatte, aber jetzt hab ichs so geändert:
> 
> 
> ```
> ...


Damit wartest du aber trotzdem ewig, da die Schleife ja nur abgebrochen wird, wenn ein Fehler auftritt oder der Apache beendet wurde.


Newbie8 hat gesagt.:


> Ich hatte Sleep() immer klein geschrieben, deswegen ging es nicht ;-) Danke für dein Code-Beispiel. Muss ich mal versuchen bei mir beim Löschen einzubinden. Das mit dem system werde ich auch so mal ausprobieren, aber anscheinend mag er das ja nicht aus javascript heraus. (siehe Screenshot von vorherigem Beitrag von mir)


Der Screenshot sagt nur aus, das du irgendwelchen Mist gemacht hast. (siehe Beitrag #43)


Newbie8 hat gesagt.:


> Hast du eine Idee woran es liegen könnte, dass es funktioniert, wenn ich die exe per Maus-Klick ausführe, wenn ich aber einen Button klicke und dann sage
> 
> document.location.href="http://localhost/cgi-bin/test.exe";
> 
> dann beendet er den Apache auf einmal nicht mehr


Wenn du die .exe als CGI Programm (und damit als Kindprozess vom Apache) ausführen läßt, dann wartet der Apache auf die Beendigung dieses Prozesses während dein Programm auf die Beendigung vom Apache wartet. Blöd... 

Du müßtest dein Programm von deinem Programm aus nochmal starten.

Gruß


----------



## Newbie8 (13. Mai 2011)

deepthroat hat gesagt.:


> Dann wird er nicht als Service gestartet und kann demnach auch nicht über die -k shutdown Methode beendet werden.
> 
> Vermutlich startest du aber über -k start, womit der Apache als Service unter dem in den Serviceeigenschaften eingestellten lokalen Systemkonto gestartet wird?!


Genau so ist es 



> Damit wartest du aber trotzdem ewig, da die Schleife ja nur abgebrochen wird, wenn ein Fehler auftritt oder der Apache beendet wurde.


wie wäre es dann besser? Wobei ich ja deine Lösung über system momentan bevorzuge, jedoch habe ich ja das Problem mit dem Temp-Verzeichnis, wobei das natürlich beide Lösungen trifft, da ich über die log.txt im Temp-Verzeichnis des Users den APacheShutDown-Befehl beim Starten speichern lasse, damit man weiß wie der Apache gestartet wurde.



> Der Screenshot sagt nur aus, das du irgendwelchen Mist gemacht hast. (siehe Beitrag #43)


Stimmt, das kommt davon dass er bei GetTempPath C:\Windows zurückgibt, anstatt das Temp-Verzeichnis des Users, nur wieso könnte das so sein?



> Wenn du die .exe als CGI Programm (und damit als Kindprozess vom Apache) ausführen läßt, dann wartet der Apache auf die Beendigung dieses Prozesses während dein Programm auf die Beendigung vom Apache wartet. Blöd...


Ich dachte in das cgi-bin-Verzeichnis kann man ausführbare Dateien kopieren, die man mit Hilfe von localhost dann ausführen lassen kann. 



> Du müßtest dein Programm von deinem Programm aus nochmal starten.


Verstehe ich nicht ganz, wie müsste ich das denn machen? Ich wollte eigetnlich über einen Button das FEnster mit top.window.close(); schließen und anschließend die exe ausführen, um den Apache zu beenden, die logs zu löschen und die Kopf-/Fußzeile auf den vorherigen Wert setzen, da der Kunde für dieses Projekt ganz spezielle Vorstellungen für KOpf-/Fußzeile hat, die er nach dem Beenden des Programmes aber nicht mehr haben sollte. Hast du eine Idee, wie man das besser lösen könnte wie bisher? also wie es besser wäre, anstatt bei ButtonClick erst das Fenster zu schließen und dann document.location.href="http://localhost/cgi-bin/test.exe"; auszuführen?

Viele Grüße


----------



## deepthroat (14. Mai 2011)

Newbie8 hat gesagt.:


> wie wäre es dann besser?


Überleg doch mal. Wozu die Schleife?


Newbie8 hat gesagt.:


> Wobei ich ja deine Lösung über system momentan bevorzuge, jedoch habe ich ja das Problem mit dem Temp-Verzeichnis, wobei das natürlich beide Lösungen trifft, da ich über die log.txt im Temp-Verzeichnis des Users den APacheShutDown-Befehl beim Starten speichern lasse, damit man weiß wie der Apache gestartet wurde.
> 
> 
> Stimmt, das kommt davon dass er bei GetTempPath C:\Windows zurückgibt, anstatt das Temp-Verzeichnis des Users, nur wieso könnte das so sein?


Weil der Apache nicht unter dem User ausgeführt wird, sondern unter dem lokalen Systemkonto.


Newbie8 hat gesagt.:


> Ich dachte in das cgi-bin-Verzeichnis kann man ausführbare Dateien kopieren, die man mit Hilfe von localhost dann ausführen lassen kann.


Habe ich etwas anderes behauptet? Evlt. solltest du dich mal informieren was CGI ist.


Newbie8 hat gesagt.:


> Verstehe ich nicht ganz, wie müsste ich das denn machen?


Ungefähr so:

```
int main(int argc, char argv[]) {
  // wenn als CGI Programm ausgeführt
  if (getenv("REMOTE_HOST") != NULL) {
    char env[256];
    sprintf(env, "COMSPEC=%s%c%c",
                getenv("COMSPEC"), '\0', '\0');
    puts("Content-type: text/plain\n\n"
           "shutting down...");
    fclose(stdout);
    // dieses Programm als Kindprozess starten, mit
    ...
    CreateProcess(argv[0], NULL, ...,
        FALSE, // inherit HANDLES
        ...
        env,  // Environment
        ...);
  } else {
     // wie bisher.
  }
}
```
Gruß


----------



## Newbie8 (16. Mai 2011)

deepthroat hat gesagt.:


> Überleg doch mal. Wozu die Schleife?


ich dachte er wartet bei: while(WaitForSingleObject(hProcess, 2000) == WAIT_TIMEOUT) {} 2 Sekunden lang ob der Apache heruntergefahren wurde, wenn nicht geht er eh in den Wait_timeout?



deepthroat hat gesagt.:


> Weil der Apache nicht unter dem User ausgeführt wird, sondern unter dem lokalen Systemkonto.


Aber ich starte den Apache doch über eine start.exe mit CreateProcess und apache -k start Wieso wird der Apache dann unter dem lokalen Systemkonto ausgeführt, wenn ich start.exe ausführe, startet er es doch auch im Documents&Settings/Username/Local Settings/Temp-Verzeichnis und im TaskManager steht der Prozess doch auch unter meinem usernamen. Scheint für mich ja daran zu liegen von wo aus ich die shutdown.exe starte. Wenn ich sie per Hand anklicke, funktioniert es und er sagt mir dass das TempVerzeichnis unter dem Usernamen ist, wenn ich es über den Button ausführe, dann sagt er mit ja C:\Windows (ohne Temp hintendran). Wenn ich nur wüsste, wie man das ändern könnte



deepthroat hat gesagt.:


> Habe ich etwas anderes behauptet? Evlt. solltest du dich mal informieren was CGI ist.


Dann habe ich dich falsch verstanden. Sorry!



deepthroat hat gesagt.:


> Ungefähr so:
> 
> ```
> int main(int argc, char argv[]) {
> ...


Wenn ich das Programm per Hand anklicke, geht er genauso wie wenn ichs über den Button ausführe in den else-Zweig. Es liegt wohl auf jeden Fall erstmal daran dass ich nicht den richtigen Temp-Pfad bei GetTempPath zurückbekomme, so dass strApacheShutdown leer ist, wenn ich das Programm über den CGI-Aufruf/Button beenden möchte und es nicht funktioniert.  

Gruß


----------



## deepthroat (16. Mai 2011)

Newbie8 hat gesagt.:


> ich dachte er wartet bei: while(WaitForSingleObject(hProcess, 2000) == WAIT_TIMEOUT) {} 2 Sekunden lang ob der Apache heruntergefahren wurde, wenn nicht geht er eh in den Wait_timeout?


Du hast dort eine Schleife. Und du rufst WaitForSingleObject immer wieder auf und wartest immer wieder 2 Sek. solange WAIT_TIMEOUT zurückkommt.


Newbie8 hat gesagt.:


> Aber ich starte den Apache doch über eine start.exe mit CreateProcess und apache -k start Wieso wird der Apache dann unter dem lokalen Systemkonto ausgeführt, wenn ich start.exe ausführe, startet er es doch auch im Documents&Settings/Username/Local Settings/Temp-Verzeichnis und im TaskManager steht der Prozess doch auch unter meinem usernamen.


Nochmal: Du startest den Apache als Service. Demnach wird er unter dem Konto ausgeführt welches in den Serviceeigenschaften hinterlegt ist. Normalerweise ist das NT-Autorität\SYSTEM (und das ist auch gut so).

Es ist völlig unerheblich wie du den Apache startest und unter welchem Konto deine start.exe läuft.


Newbie8 hat gesagt.:


> Scheint für mich ja daran zu liegen von wo aus ich die shutdown.exe starte. Wenn ich sie per Hand anklicke, funktioniert es und er sagt mir dass das TempVerzeichnis unter dem Usernamen ist, wenn ich es über den Button ausführe, dann sagt er mit ja C:\Windows (ohne Temp hintendran). Wenn ich nur wüsste, wie man das ändern könnte


Wieso willst du das ändern?


Newbie8 hat gesagt.:


> Wenn ich das Programm per Hand anklicke, geht er genauso wie wenn ichs über den Button ausführe in den else-Zweig. Es liegt wohl auf jeden Fall erstmal daran dass ich nicht den richtigen Temp-Pfad bei GetTempPath zurückbekomme, so dass strApacheShutdown leer ist, wenn ich das Programm über den CGI-Aufruf/Button beenden möchte und es nicht funktioniert.


Was hat denn der strApacheShutdown mit dem TempPath zu tun?

Gruß


----------



## Newbie8 (16. Mai 2011)

deepthroat hat gesagt.:


> Du hast dort eine Schleife. Und du rufst WaitForSingleObject immer wieder auf und wartest immer wieder 2 Sek. solange WAIT_TIMEOUT zurückkommt.




```
do  {
    dwPriorityClass = 0;
    if(strcmp(pe32.szExeFile, "Apache.exe")==0){
      hProcess = OpenProcess( SYNCHRONIZE , FALSE, pe32.th32ProcessID );
      if( hProcess != NULL ){
	dwPriorityClass = GetPriorityClass( hProcess );
	PROCESS_INFORMATION piA;
	STARTUPINFO suiA;
	suiA.cb		=sizeof(STARTUPINFO);
	suiA.lpReserved	=0;
	suiA.lpDesktop	=NULL;
	suiA.lpTitle	=NULL;
	suiA.dwX		=0;
	suiA.dwY		=0;
	suiA.dwXSize	=0;
	suiA.dwYSize	=0;
	suiA.dwXCountChars	=0;
	suiA.dwYCountChars	=0;
	suiA.dwFillAttribute	=0;
	suiA.dwFlags	=STARTF_USESHOWWINDOW;
	suiA.wShowWindow	=SW_MINIMIZE;
	suiA.cbReserved2	=0;
	suiA.lpReserved2	=0;
	if(CreateProcess(NULL,strApacheShutdown,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiA,&piA)==TRUE) {
	CloseHandle(piA.hThread);
      }
        WaitForInputIdle(piA.hProcess, INFINITE);
        while(WaitForSingleObject(piA.hProcess, 2000) == WAIT_TIMEOUT) {}
        WaitForInputIdle(hProcess, INFINITE);
        while(WaitForSingleObject(hProcess, 2000) == WAIT_TIMEOUT) {}
        CloseHandle( hProcess );
      }		
    }
  } while( Process32Next( hProcessSnap, &pe32 ) );
```
Er geht doch bei do alle Prozesse durch aber er geht nur in die Schleife rein, wenn der Prozessename Apache.exe ist. Dadurch wartet er für jeden Apache-Prozess die 2 Sekunden oder sehe ich das falsch? 



> Nochmal: Du startest den Apache als Service. Demnach wird er unter dem Konto ausgeführt welches in den Serviceeigenschaften hinterlegt ist. Normalerweise ist das NT-Autorität\SYSTEM (und das ist auch gut so).
> 
> Es ist völlig unerheblich wie du den Apache startest und unter welchem Konto deine start.exe läuft.


Also die start.exe startet den apache, der Apache läuft aber unter meinem Userkonto und nicht unter SYSTEM oder so. Also wenn ich in den Taskmanager reinschaue, dann läuft der Apache unter (sagen wir mal XYZ, wenn mein Username XYZ ist). Das hattest du falsch verstanden, meinte nicht die start.exe läuft unter dem usernamen sondern der Apache.



> Was hat denn der strApacheShutdown mit dem TempPath zu tun?
> 
> Gruß


 Also bisher hatte ich es ja so gemacht, dass ich mit GetTempPath() den Temp-Path des Users bekommen hatte/wollte, dort liegt eine log.txt in der der strApacheShutdown-Path und die Kopf-/Fußzeile (Wert vor dem starten der start.exe, damit man es wieder auf diesen Wert setzen kann) eingetragen ist. Verstehe halt nicht so ganz wieso das so ein Unterschied ist, klicke ich die shutdown.exe per Hand an, bekomme ich den richtigen Temp-Pfad und ich kann strApacheShutdown aus der log.txt auslesen. Starte ich shutdown.exe beim Beenden des Internet-Explorer-Fensters bekomme ich C:\Windows als TempVerzeichnis zurück, dadurch findet er die log.txt nicht! Und somit kann ich den Apache nicht herunterfahren, weil ich nicht weiß, wo die Apache.exe und wo die httpd.conf liegt und die Kopf-/Fußzeile kann auch nicht zurückgesetzt werden. Ich hoffe, du kannst jetzt verstehen wieso ich unbedingt den User-Temppath bräuchte. Hast du eine Idee, wie ich ansonsten zum User-Temppath kommen könnte oder starte ich vielleicht den Internet Explorer falsch?

Gruß


----------



## deepthroat (16. Mai 2011)

Newbie8 hat gesagt.:


> Er geht doch bei do alle Prozesse durch aber er geht nur in die Schleife rein, wenn der Prozessename Apache.exe ist.


Ja.


Newbie8 hat gesagt.:


> Dadurch wartet er für jeden Apache-Prozess die 2 Sekunden oder sehe ich das falsch?


Du hast dort eine SCHLEIFE. Du brichst diese Schleife niemals ab wenn der Apache Prozess nicht beendet wird.


Newbie8 hat gesagt.:


> Also die start.exe startet den apache, der Apache läuft aber unter meinem Userkonto und nicht unter SYSTEM oder so. Also wenn ich in den Taskmanager reinschaue, dann läuft der Apache unter (sagen wir mal XYZ, wenn mein Username XYZ ist). Das hattest du falsch verstanden, meinte nicht die start.exe läuft unter dem usernamen sondern der Apache.


Aha. Dann startet vermutlich der Apache das CGI Programm unter einem anderen Nutzerkonto oder einfach mit einer veränderten Umgebung in der weder TMP, noch TEMP, noch USERPROFILE gesetzt sind.

Unter welchem Konto wird die shutdown.exe ausgeführt, wenn du es als CGI Programm ausführst? Sind die angesprochenen Umgebungsvariablen gesetzt?


Newbie8 hat gesagt.:


> Also bisher hatte ich es ja so gemacht, dass ich mit GetTempPath() den Temp-Path des Users bekommen hatte/wollte, dort liegt eine log.txt in der der strApacheShutdown-Path und die Kopf-/Fußzeile (Wert vor dem starten der start.exe, damit man es wieder auf diesen Wert setzen kann) eingetragen ist. Verstehe halt nicht so ganz wieso das so ein Unterschied ist, klicke ich die shutdown.exe per Hand an, bekomme ich den richtigen Temp-Pfad und ich kann strApacheShutdown aus der log.txt auslesen. Starte ich shutdown.exe beim Beenden des Internet-Explorer-Fensters bekomme ich C:\Windows als TempVerzeichnis zurück, dadurch findet er die log.txt nicht! Und somit kann ich den Apache nicht herunterfahren, weil ich nicht weiß, wo die Apache.exe und wo die httpd.conf liegt


Also den Pfad zur Apache.exe kannst du aus den Prozessinformationen extrahieren.


Newbie8 hat gesagt.:


> und die Kopf-/Fußzeile kann auch nicht zurückgesetzt werden.


Welche Kopf/Fusszeilen? Verwendest du SSI?


Newbie8 hat gesagt.:


> Ich hoffe, du kannst jetzt verstehen wieso ich unbedingt den User-Temppath bräuchte. Hast du eine Idee, wie ich ansonsten zum User-Temppath kommen könnte oder starte ich vielleicht den Internet Explorer falsch?


Du hast nicht genug Informationen geliefert wie genau du den Apache nun startest, wie die Konfiguration zustande kommt usw. Evlt. kannst du den Pfad aus den standardmäßig gesetzten Umgebungsvariablen extrahieren. Siehe z.B. http://www.cgi101.com/book/ch3/text.html

Gruß


----------



## Newbie8 (16. Mai 2011)

deepthroat hat gesagt.:


> Ja.
> 
> Du hast dort eine SCHLEIFE. Du brichst diese Schleife niemals ab wenn der Apache Prozess nicht beendet wird.


Ich dachte, dass er nur 2 Sekunden lang probiert herunterzufahren, ansonsten Wait-Timeout zurückgibt und abbricht. Ist anscheinend nicht so? Wie meinst du wäre es dann besser?



deepthroat hat gesagt.:


> Aha. Dann startet vermutlich der Apache das CGI Programm unter einem anderen Nutzerkonto oder einfach mit einer veränderten Umgebung in der weder TMP, noch TEMP, noch USERPROFILE gesetzt sind.
> 
> Unter welchem Konto wird die shutdown.exe ausgeführt, wenn du es als CGI Programm ausführst? Sind die angesprochenen Umgebungsvariablen gesetzt?


die shutdown.exe wird auch als XYZ (ausgedachter username) im Taskmanager aufgeführt, wenn ich es als CGI-Programm ausführe, also unter meinem usernamen läuft die shutdown.exe sozusagen.
Unter System-> Erweitert->Umgebungsvariablen, steht unter den Umgebungsvariablen von user XYZ
TMP und TEMP als C:\Documents and Settings\... drinnen, aber unter Systemvariablen steht bei TMP und TEMP C:\Windows\TEmp, wobei er ja bei mir C:\Windows zurückgibt. Könnte es sein, dass ich beim Server etwas angeben könnte, also in den Einstellungen vom Apache?



deepthroat hat gesagt.:


> Also den Pfad zur Apache.exe kannst du aus den Prozessinformationen extrahieren.


Ja, wie geht das? Wobei ich ja wissen müsste, wo die httpd.conf liegt, denn die liegt im User-Tempverzeichnis. Kann man das auch über die Prozessinformationen herausfinden?



deepthroat hat gesagt.:


> Welche Kopf/Fusszeilen? Verwendest du SSI?


Wir lesen die Fuß-/Kopfzeilen aus der Registry aus, schreiben sie in die log.txt und wollen sie am Ende wieder zurücksetzen, da sie nur in dieser Projektumgebung beim Drucken angezeigt werden sollen. Ist Wunsch vom Kunden. 



deepthroat hat gesagt.:


> Du hast nicht genug Informationen geliefert wie genau du den Apache nun startest, wie die Konfiguration zustande kommt usw. Evlt. kannst du den Pfad aus den standardmäßig gesetzten Umgebungsvariablen extrahieren. Siehe z.B. http://www.cgi101.com/book/ch3/text.html
> 
> Gruß


Wir starten den Apache folgendermaßen:

```
PROCESS_INFORMATION piA;
		STARTUPINFO suiA;
		suiA.cb		=sizeof(STARTUPINFO);
		suiA.lpReserved	=0;
		suiA.lpDesktop	=NULL;
		suiA.lpTitle	=NULL;
		suiA.dwX		=0;
		suiA.dwY		=0;
		suiA.dwXSize	=0;
		suiA.dwYSize	=0;
		suiA.dwXCountChars	=0;
		suiA.dwYCountChars	=0;
		suiA.dwFillAttribute	=0;
		suiA.dwFlags	=STARTF_USESHOWWINDOW;
		suiA.wShowWindow	=SW_MINIMIZE;
		suiA.cbReserved2	=0;
		suiA.lpReserved2	=0;
		if(CreateProcess(NULL,strApache,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,NULL,NULL,&suiA,&piA)==TRUE) {}
```
, wobei "PFad_zum_apche\Apache.exe -f Pfad_zur_httpd.conf\httpd.conf -k start" in strApache steht.

Gruß


----------



## deepthroat (16. Mai 2011)

Newbie8 hat gesagt.:


> Ich dachte, dass er nur 2 Sekunden lang probiert herunterzufahren, ansonsten Wait-Timeout zurückgibt und abbricht. Ist anscheinend nicht so? Wie meinst du wäre es dann besser?


Da solltest du wirklich alleine drauf kommen.


Newbie8 hat gesagt.:


> die shutdown.exe wird auch als XYZ (ausgedachter username) im Taskmanager aufgeführt, wenn ich es als CGI-Programm ausführe, also unter meinem usernamen läuft die shutdown.exe sozusagen.
> Unter System-> Erweitert->Umgebungsvariablen, steht unter den Umgebungsvariablen von user XYZ
> TMP und TEMP als C:\Documents and Settings\... drinnen, aber unter Systemvariablen steht bei TMP und TEMP C:\Windows\TEmp, wobei er ja bei mir C:\Windows zurückgibt.


Es ist ziemlich irrelevant was in diesen Variablen drin steht. Du solltest überprüfen welche Variablen in dem CGI Prozess gesetzt sind.


Newbie8 hat gesagt.:


> Könnte es sein, dass ich beim Server etwas angeben könnte, also in den Einstellungen vom Apache?


Ja. Stichwort mod_env.


Newbie8 hat gesagt.:


> Ja, wie geht das?


Ich hatte dich bereits auf die entsprechende Information verwiesen.


Newbie8 hat gesagt.:


> Wobei ich ja wissen müsste, wo die httpd.conf liegt, denn die liegt im User-Tempverzeichnis. Kann man das auch über die Prozessinformationen herausfinden?


Ja,  indem man die Umgebungsvariablen des Prozesses ausliest.


Newbie8 hat gesagt.:


> Wir lesen die Fuß-/Kopfzeilen aus der Registry aus, schreiben sie in die log.txt und wollen sie am Ende wieder zurücksetzen, da sie nur in dieser Projektumgebung beim Drucken angezeigt werden sollen. Ist Wunsch vom Kunden.


Ich verstehe immer noch nicht von welchen Kopf-/Fußzeilen du redest.


Newbie8 hat gesagt.:


> Wir starten den Apache folgendermaßen:


Ja, geschenkt. Du solltest erläutern wie ihr den Apache genau verwenden wollt. Wie die Konfiguration zustande kommt. Wie kommt es z.B. das der Apache eine log.txt in das temp. Verzeichnis schreibt? Wieso liegt die httpd.conf im temp. Verzeichnis? Wird die Datei generiert?

Gruß


----------



## Newbie8 (16. Mai 2011)

deepthroat hat gesagt.:


> Da solltest du wirklich alleine drauf kommen.


Ich würde wahrscheinlich nicht fragen, wenn ich wüsste, wie



deepthroat hat gesagt.:


> Es ist ziemlich irrelevant was in diesen Variablen drin steht. Du solltest überprüfen welche Variablen in dem CGI Prozess gesetzt sind.
> Ja. Stichwort mod_env.


Ich bin an dieser Stelle etwas überfordert, da ich mich noch nicht so tiefgehend mit der Apache-Installation bzw Einstellungsmöglichkeiten beschäftigt habe, da das bisher mein Chef gemacht hat. Ich habe jetzt ein bisschen danach gegoogelt, anscheinend kann man die Definition von Umgebungsvariablen in die httpd.conf aufnehmen. Habe dort jetzt ein Setenv TMP "pfad zum user-Temp" aufgenommen und jetzt findet er meine log-datei zum Auslesen *freu*



> Ich verstehe immer noch nicht von welchen Kopf-/Fußzeilen du redest.


Ich rede von den Kopf-/Fußzeilen im Internet Explorer, da der Kunde möchte, dass beim Ausdrucken etwas bestimmtes als Kopf-/Fußzeile angezeigt wird. Dies muss aber nach dem Schließen des Projektes geändert werden, da das projektspezifische Infos sind. 



> Ja, geschenkt. Du solltest erläutern wie ihr den Apache genau verwenden wollt. Wie die Konfiguration zustande kommt. Wie kommt es z.B. das der Apache eine log.txt in das temp. Verzeichnis schreibt? Wieso liegt die httpd.conf im temp. Verzeichnis? Wird die Datei generiert?


Das mit der log.txt hat mein Chef damals so programmiert, um vielleicht über spezielle Aufrufe zu haben. Ich dachte die könnte man für diesen Fall auch verwenden, da die ja beim Starten des Programmes geschrieben wird und da ja die Kopf-/fußzeilen ausgelesen werden und man auch weiß wie der Apache gestartet wird und kann dann also darin festhalten wie der Apapche heruntergefahren werden müsste. die httpd.conf liegt im temp Verzeichnis weil wir das so in der start.exe programmiert haben, dort liegen auch httpd.pid, jserv.conf, jserv.properties,... da unser Programm von CD gestartet wird und man im User-Temp-Verzeichnis immer Schreibrecht haben sollte und diese Dateien dann bei Programmstart geschrieben werden. Genau die Datei wird beim Starten generiert. 

Das Herunterfahren würde jetzt funktionieren, dauert aber noch viel zu lange, mit dem system-Aufruf ca. 40Sekunden, mit dem GetProcessList() und CreateProcess() dauert es 1 Minute. Wäre blöd, wenn jmd kurz drauf merkt er will neustarten und er ist noch nicht heruntergefahren, hoffe ich bekomme das noch schneller hin. Vielleicht liegt es auch wirklich daran dass sie sich gegenseitig blockieren, habe aber noch nicht verstanden wie ich das umgehen kann. Hoffe bekomme das noch hin

Viele Grüße und vielen Dank


----------



## deepthroat (16. Mai 2011)

Newbie8 hat gesagt.:


> Ich würde wahrscheinlich nicht fragen, wenn ich wüsste, wie


Ich habe im Grunde schon x-mal mit dem Zaunpfahl gewunken, die nächste Stufe wäre zu schlagen... Das willst du doch nicht, oder?! ;-]

Aber ich stelle nochmal die Frage: WOZU DIE SCHLEIFE?


Newbie8 hat gesagt.:


> Ich rede von den Kopf-/Fußzeilen im Internet Explorer, da der Kunde möchte, dass beim Ausdrucken etwas bestimmtes als Kopf-/Fußzeile angezeigt wird.


Ach, Du meinst beim Ausdrucken?


Newbie8 hat gesagt.:


> Dies muss aber nach dem Schließen des Projektes geändert werden, da das projektspezifische Infos sind.
> 
> Das mit der log.txt hat mein Chef damals so programmiert, um vielleicht über spezielle Aufrufe zu haben. Ich dachte die könnte man für diesen Fall auch verwenden, da die ja beim Starten des Programmes geschrieben wird und da ja die Kopf-/fußzeilen ausgelesen werden und man auch weiß wie der Apache gestartet wird und kann dann also darin festhalten wie der Apapche heruntergefahren werden müsste. die httpd.conf liegt im temp Verzeichnis weil wir das so in der start.exe programmiert haben, dort liegen auch httpd.pid, jserv.conf, jserv.properties,... da unser Programm von CD gestartet wird und man im User-Temp-Verzeichnis immer Schreibrecht haben sollte und diese Dateien dann bei Programmstart geschrieben werden. Genau die Datei wird beim Starten generiert.


Du willst also diese log.txt auslesen um festzustellen, wie die Konfiguration der Kopf-/Fußzeile war um diese dann zurücksetzen zu können?


Newbie8 hat gesagt.:


> Das Herunterfahren würde jetzt funktionieren, dauert aber noch viel zu lange, mit dem system-Aufruf ca. 40Sekunden, mit dem GetProcessList() und CreateProcess() dauert es 1 Minute. Wäre blöd, wenn jmd kurz drauf merkt er will neustarten und er ist noch nicht heruntergefahren, hoffe ich bekomme das noch schneller hin. Vielleicht liegt es auch wirklich daran dass sie sich gegenseitig blockieren, habe aber noch nicht verstanden wie ich das umgehen kann.


Wie bereits gesagt mußt du lediglich einen Kindprozess starten und das CGI Programm beenden um das CGI Programm und den Apache zu entkoppeln.

Du hast übrigens vergessen das piA Prozess-Handle zu schließen.

Gruß


----------



## Newbie8 (18. Mai 2011)

deepthroat hat gesagt.:


> Ich habe im Grunde schon x-mal mit dem Zaunpfahl gewunken, die nächste Stufe wäre zu schlagen... Das willst du doch nicht, oder?! ;-]
> Aber ich stelle nochmal die Frage: WOZU DIE SCHLEIFE?


Nein natürlich nicht ;-) Also ich denke mal das while ist hier einfach falsch und es reicht, WaitForSingleObject(hProcess, 2000); oder? 



deepthroat hat gesagt.:


> Ach, Du meinst beim Ausdrucken?
> Du willst also diese log.txt auslesen um festzustellen, wie die Konfiguration der Kopf-/Fußzeile war um diese dann zurücksetzen zu können?


Genau  das klappt jetzt immerhin, nachdem du mir den Tipp mit mod_env gegeben hattest. Danke 



deepthroat hat gesagt.:


> Wie bereits gesagt mußt du lediglich einen Kindprozess starten und das CGI Programm beenden um das CGI Programm und den Apache zu entkoppeln.


wie das mit dem Entkoppeln klappen könnte, verstehe ich noch nicht so ganz. Du hast mir ja schon mal als Tipp diesen Code geschrieben:

```
int main(int argc, char argv[]) {
  // wenn als CGI Programm ausgeführt
  if (getenv("REMOTE_HOST") != NULL) {
    char env[] = "\0\0";
    puts("Content-type: text/plain\n\n"
           "shutting down...");
    fclose(stdout);
    // dieses Programm als Kindprozess starten, mit
    ...
    CreateProcess(argv[0], NULL, ...,
        FALSE, // inherit HANDLES
        ...
        env,  // Environment
        ...);
  } else {
     // wie bisher.
  }
}
```

was wäre argv[0] in diesem Fall? Was wären die letzten 2 Parameter bei createprocess? Und würde ich dann nach CreateProcess den Apache herunterfahren lassen? Ich habe bisher mein c++ programm als Project mit der Eigenschaft MFC-Anwendungs-Assistent (exe) erstellt, weil ich ja unbedingt eine exe haben möchte und dadurch habe ich gar keine int main bzw. habe bisher den Code in die Funktion InitInstance() geschrieben. Ist das falsch gewesen?



deepthroat hat gesagt.:


> Du hast übrigens vergessen das piA Prozess-Handle zu schließen.


Stimmt - danke 

Gruß und nochmal danke für alle Tipps bisher


----------



## deepthroat (18. Mai 2011)

Newbie8 hat gesagt.:


> Nein natürlich nicht ;-) Also ich denke mal das while ist hier einfach falsch und es reicht, WaitForSingleObject(hProcess, 2000); oder?


Ja 


Newbie8 hat gesagt.:


> Genau  das klappt jetzt immerhin, nachdem du mir den Tipp mit mod_env gegeben hattest. Danke


Wenn du allerdings in der httpd.conf generieren kannst was du willst, dann könntest du natürlich auch gleich eine Variable genieren, in der die alten Einstellungen drin stehen. Weiterhin wäre zu überlegen, ob du nicht einfach eine temp. Datei (siehe http://msdn.microsoft.com/en-us/library/aa363875(v=vs.85).aspx) erzeugst. Dann brauchst du dich eigentlich gar nicht um das Löschen kümmern.


Newbie8 hat gesagt.:


> wie das mit dem Entkoppeln klappen könnte, verstehe ich noch nicht so ganz. Du hast mir ja schon mal als Tipp diesen Code geschrieben:
> ...
> was wäre argv[0] in diesem Fall?


argv[0] ist wie üblich in main belegt:

```
int main(int argc, char argv[])
```
Also der Pfad zur gerade ausgeführten .exe Datei.


Newbie8 hat gesagt.:


> Und würde ich dann nach CreateProcess den Apache herunterfahren lassen?


Nein.

Apache -> deineCGI.exe -> deineCGI.exe

Den Apache fährst du in der zweiten Instanz herunter, nicht in der ersten.


Newbie8 hat gesagt.:


> Ich habe bisher mein c++ programm als Project mit der Eigenschaft MFC-Anwendungs-Assistent (exe) erstellt, weil ich ja unbedingt eine exe haben möchte und dadurch habe ich gar keine int main bzw. habe bisher den Code in die Funktion InitInstance() geschrieben. Ist das falsch gewesen?


Hm. Vielleicht nicht gerade sinnvoll wenn du gar kein MFC benutzt. Du kannst aber über die GetModuleFileName Funktion (http://msdn.microsoft.com/en-us/library/ms683197(v=vs.85).aspx) auch den aktuellen Pfad zur exe herausfinden.

Gruß


----------



## Newbie8 (18. Mai 2011)

deepthroat hat gesagt.:


> Wenn du allerdings in der httpd.conf generieren kannst was du willst, dann könntest du natürlich auch gleich eine Variable genieren, in der die alten Einstellungen drin stehen. Weiterhin wäre zu überlegen, ob du nicht einfach eine temp. Datei (siehe http://msdn.microsoft.com/en-us/library/aa363875(v=vs.85).aspx) erzeugst. Dann brauchst du dich eigentlich gar nicht um das Löschen kümmern.


Das muss ich mir mal anschauen. hört sich gut an



deepthroat hat gesagt.:


> argv[0] ist wie üblich in main belegt:
> 
> ```
> int main(int argc, char argv[])
> ...


Ich versuche das jetzt umzustellen, habe mal einen neuen ARbeitsbereich erstellt und versuche das jetzt noch aufzunehmen, was du mir gerade hast, aber ich verstehe es noch nicht so ganz. 

Ich habe das jetzt folgendermaßen aufgenommen:

```
int main(int argc, char* argv[])
{
	if (getenv("SERVER_NAME") != NULL) {
		char env[] = "\0\0";
		PROCESS_INFORMATION piA;
		STARTUPINFO suiA;
		CreateProcess(argv[0],NULL,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,env,NULL,&suiA,&piA);
  } else {
//hereinkopiert so wie es vorher war
}
```
Weil du meintest den Apache fährst du in der zweiten Instanz herunter. Meinst du den else-Zweig? Wie kommt er da rein, er geht doch sicher in die main nur einmal rein und dann würde er in den if-Zweig gehen oder? Bisher geht er jetzt zwar in den if-Zweig und beendet die test.exe. Aber der Apache wird dann natürlich nicht heruntergefahren

Tut mir echt leid, dass ich soviel frage, aber verstehe es einfach noch nicht und wäre so super wenn ich das verstehen würde und das Programm dann richtig funktioniere würde *träum*

Gruß


----------



## deepthroat (19. Mai 2011)

Newbie8 hat gesagt.:


> Ich versuche das jetzt umzustellen, habe mal einen neuen ARbeitsbereich erstellt und versuche das jetzt noch aufzunehmen, was du mir gerade hast, aber ich verstehe es noch nicht so ganz.
> 
> Ich habe das jetzt folgendermaßen aufgenommen:
> 
> ...


Das ist nicht der aktuelle Code. Die COMSPEC Variable muss gesetzt sein. Siehe Beitrag #48.


Newbie8 hat gesagt.:


> Weil du meintest den Apache fährst du in der zweiten Instanz herunter. Meinst du den else-Zweig?


Ja.


Newbie8 hat gesagt.:


> Wie kommt er da rein, er geht doch sicher in die main nur einmal rein und dann würde er in den if-Zweig gehen oder? Bisher geht er jetzt zwar in den if-Zweig und beendet die test.exe. Aber der Apache wird dann natürlich nicht heruntergefahren


Wenn ein Programm als CGI Programm ausgeführt wird, sind bestimmte Umgebungsvariablen gesetzt (z.B. REMOTE_ADDR). So kann man feststellen, ob das aktuelle Programm als CGI Programm ausgeführt wird.

Wenn man dann einen Kindprozeß erzeugen will der nicht als CGI Programm ausgeführt werden soll, muss man dann natürlich sicherstellen, dass in diesem Prozess die CGI Variablen nicht gesetzt sind. Dazu werden neue Umgebungsvariablen an den Kindprozess übergeben.

Gruß


----------



## Newbie8 (19. Mai 2011)

deepthroat hat gesagt.:


> Das ist nicht der aktuelle Code. Die COMSPEC Variable muss gesetzt sein. Siehe Beitrag #48.




```
if (getenv("SERVER_NAME") != NULL) {
                char env[256];
		sprintf(env, "COMSPEC=%s%c%c",
                getenv("COMSPEC"), '\0', '\0');

		PROCESS_INFORMATION piA;
		STARTUPINFO suiA;
		// dieses Programm als Kindprozess starten, mit		CreateProcess(argv[0],NULL,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,env,NULL,&suiA,&piA);
  } else {}
```
Habe es jetzt so übernommen



> Wenn ein Programm als CGI Programm ausgeführt wird, sind bestimmte Umgebungsvariablen gesetzt (z.B. REMOTE_ADDR). So kann man feststellen, ob das aktuelle Programm als CGI Programm ausgeführt wird.
> Wenn man dann einen Kindprozeß erzeugen will der nicht als CGI Programm ausgeführt werden soll, muss man dann natürlich sicherstellen, dass in diesem Prozess die CGI Variablen nicht gesetzt sind. Dazu werden neue Umgebungsvariablen an den Kindprozess übergeben.
> Gruß


Er beendet meine test.exe, aber die APache.exe läuft weiter. Ich hatte dann überlegt, nach dem CreateProcess(); nochmal meine test.exe aufzurufen mit system(argv[0]); aber dann startet er immer wieder die test.exe und kommt sozusagen in eine Endlosschleife, weil er jedesmal in den if-Zweig reingeht. 

Was mache ich falsch bzw. was müsste ich nach CreateProcess() noch ausführen?

Gruß


----------



## deepthroat (19. Mai 2011)

Newbie8 hat gesagt.:


> Er beendet meine test.exe, aber die APache.exe läuft weiter. Ich hatte dann überlegt, nach dem CreateProcess(); nochmal meine test.exe aufzurufen mit system(argv[0]);


Wie ich eben erklärt habe ist das Unsinn. Lies es dir nochmal durch.


Newbie8 hat gesagt.:


> aber dann startet er immer wieder die test.exe und kommt sozusagen in eine Endlosschleife, weil er jedesmal in den if-Zweig reingeht.


Allerdings.


Newbie8 hat gesagt.:


> Was mache ich falsch bzw. was müsste ich nach CreateProcess() noch ausführen?


Du mußt nur die Handles schließen. Aber das ist ja klar.

Stelle fest was nicht funktioniert. Schreibe ein Log-Datei im else Zweig, wo du die Ausgabe bzw. den Rückgabewert der system() Funktion reinschreibst, so kannst du nachschauen warum es nicht geht.

Oder du "spielst" den Apache und setzt die Umgebungsvariable in einer Shell:

```
set SERVER_NAME=blub
dein_programm.exe
```
Füge ein paar Sleep() Aufrufe hinzu, so dass du im Task-Manager beobachten kannst das deine Programme aktiv sind.

Gruß


----------



## Newbie8 (19. Mai 2011)

deepthroat hat gesagt.:


> Du mußt nur die Handles schließen. Aber das ist ja klar.


Welche Handles? in dem Bsp:

```
if (getenv("SERVER_NAME") != NULL) {
		char env[256];
		sprintf(env, "COMSPEC=%s%c%c",
                getenv("COMSPEC"), '\0', '\0');

		PROCESS_INFORMATION piA;
		STARTUPINFO suiA;		CreateProcess(argv[0],NULL,NULL,NULL,FALSE,CREATE_DEFAULT_ERROR_MODE|NORMAL_PRIORITY_CLASS,env,NULL,&suiA,&piA);
		system(argv[0]);
  }
```
sind doch gar keine Handles offen oder sehe ich das falsch?


> Stelle fest was nicht funktioniert. Schreibe ein Log-Datei im else Zweig, wo du die Ausgabe bzw. den Rückgabewert der system() Funktion reinschreibst, so kannst du nachschauen warum es nicht geht.


Wie kommt er denn irgendwann in den else-Zweig. Die main wird doch nur einmal aufgerufen und zwar aus der javascript durch den Aufruf der exe, dann geht er aber in den if-Zweig, weils ja von einem Server aus aufgerufen wurde und dann beendet er bei CreateProcess die test.exe und dann? wie soll er dann in den else-Zweig kommen? Bei mir geht er nicht in den else-Zweig rein.

Gruß


----------



## deepthroat (19. Mai 2011)

Newbie8 hat gesagt.:


> Welche Handles? in dem Bsp:
> ...
> sind doch gar keine Handles offen oder sehe ich das falsch?


Letzteres. Versuch doch mal den Code zu verstehen. Welche Handles mußt du denn nach dem CreateProcess Aufruf schließen? ;-]

Das ist kein vollständiges Beispiel. Die auf der Hand liegenden Dinge (Initialsierung von den Strukturen, Parameter für den CreateProcess Aufruf, Überprüfung des Rückgabewertes der CreateProcess Funktion) habe ich weggelassen. Irgendwas sollst du ja auch selber machen.


Newbie8 hat gesagt.:


> Wie kommt er denn irgendwann in den else-Zweig. Die main wird doch nur einmal aufgerufen und zwar aus der javascript durch den Aufruf der exe, dann geht er aber in den if-Zweig, weils ja von einem Server aus aufgerufen wurde und dann beendet er bei CreateProcess die test.exe und dann? wie soll er dann in den else-Zweig kommen? Bei mir geht er nicht in den else-Zweig rein.


Beweise es. Zeig dein vollständiges Programm.

Gruß


----------

