Prozessstart anzeigen lass für Logdatei
-
Kingmarino schrieb:
...gibt es noch eine andere möglichkeit?
Ja, aber die ist nicht gerade einfacher und geht über COM und WMI. Hier ist ein fertiges Beispiel, wie man über COM und WMI die Prozess-Starts verfolgt:
http://msdn.microsoft.com/en-us/library/aa390425.aspxViel Glück

Grüssli
-
Kingmarino schrieb:
sorry bin darus doch nicht sonderlich schlauergeworden...
Wo ist das Problem? du schreibst eine dll die beim prozess-start geladen wird und trägst ihren pfad der registry ein (s.o.).
deine dll könnte zB so aussehen:
dll.cpp:
#include<windows.h> #include<fstream> ofstream os; void log(DWORD reason) { if(!os.is_open()) { os.open("C://test//log.txt"); } switch(reason) { case DLL_PROCESS_ATTACH: os<<"DLL_PROCESS_ATTACH"<<endl; break; case DLL_PROCESS_DETACH: os<<"DLL_PROCESS_DETACH"<<endl; break; case DLL_THREAD_ATTACH: os<<"DLL_THREAD_ATTACH"<<endl; break; case DLL_THREAD_DETACH: os<<"DLL_THREAD_DETACH"<<endl; break; } } BOOL APIENTRY DllMain(HINSTANCE hInst, DWORD reason, LPVOID reserver) { switch(reason) { case DLL_PROCESS_ATTACH: log(reason); break; case DLL_PROCESS_DETACH: log(reason); break; case DLL_THREAD_ATTACH: log(reason); break; case DLL_THREAD_DETACH: log(reason); break; } }evtl. musst du eben noch ergänzen, dass die Systemzeit mitgeloggt wird.
lg,
andi01.
-
ok danke jetzt hab ichs gecheckt:)
-
Hübscher Nebeneffekt der Methode: Mit einem GetCommandLine() Aufruf in der DLL bekommst du den Prozessnamen inklusive aller Kommandozeileparameter, die man mit den Toolhelp32 Funktionen nicht bekommt.
-
Ich habe noch eine Frage dazu.
Ich hab das jetzt genauso gemacht, wie andi01 beschrieben hat. Die DLL wird auch geladen und meine Logfile angelegt, aber es wird nicht geschrieben.
So sieht mein Code aus:#include <windows.h> #include <iostream> #include <fstream> #include <string> #include <sstream> std::ofstream logstream; void log(DWORD reason) { switch (reason) { case DLL_PROCESS_ATTACH: { PSYSTEMTIME timer = NULL; GetLocalTime(timer); std::stringstream ss; ss << "Prgoramm gestartet:\n" << GetCommandLine() << ":\n" << timer->wDay << "." << timer->wMonth << "." << timer->wYear << "; " << timer->wHour << ":" << timer->wMinute << ":" << timer->wSecond << std::endl; logstream << "\n" << ss.str() << std::endl; } case DLL_PROCESS_DETACH: { PSYSTEMTIME timer = NULL; GetLocalTime(timer); std::stringstream ss; ss << "Prgoramm beendet:\n" << GetCommandLine() << ":\n" << timer->wDay << "." << timer->wMonth << "." << timer->wYear << "; " << timer->wHour << ":" << timer->wMinute << ":" << timer->wSecond << std::endl; //logstream << "\n" << ss.str() << std::endl; logstream << "test" << std::endl; } } }; BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { logstream.open("C:\\test.log", std::ios::out | std::ios::app); switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: log(ul_reason_for_call); break; case DLL_PROCESS_DETACH: log(ul_reason_for_call); break; } logstream.close(); return true; }Auch wenn ich anstatt dem Stringstream nur ein einfaches "test" schreiben will, klappts nicht

-
Hat niemand eine Idee?
-
unwissenderneuling schrieb:
Ich hab das jetzt genauso gemacht, wie andi01 beschrieben hat. Die DLL wird auch geladen und meine Logfile angelegt, aber es wird nicht geschrieben.
ich nehme an das soll heißen, dass das logfile zwar existiert aber leer ist?
wenn es nicht existiert, solltest du mal nachsehen ob das Programm direkt unter C:\ überhaupt schreibrechte hat und es gegebenenfalls als admin ausführen.für den fall dass das logfile einfach leer ist:
1.Du hast im switch der logfunktion die breaks vergessen.
einfaches Beispiel:
int a=1; switch(a) { case 1: { cout<<"1"; } case 2: { cout<<"2"; } }
hier wird "12" ausgegeben statt "1"2. würde ich den switch mal um ein default ergänzen um zu sehen ob in deiner logfunktion überhaupt was ankommt.
3.könntest du dir eigentlich den switch in der DllMain sparen da du sowieso nur den Funktionsparameter ul_reason_for_call übergiebst.
Die DllMain ließe sich schonmal vereinfachen:
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { logstream.open("C:\\test.log", std::ios::out | std::ios::app); log(ul_reason_for_call); logstream.close(); }in der log-funktion werden ja nach wie vor nur DLL_PROCESS_ATTACH und DLL_PROCESS_DETACH geloggt.
4. gibt dein Code sowieso eine Zugriffsverletzung beim Schreiben:
PSYSTEMTIME time=NULL; GetLocalTime(time);nimm besser:
SYSTEMTIME time; GetLocalTime(&time);dann eben noch statt
log<<time->wHour;lieber
log<<time.wHour;5.Um festzustellen woran es genau liegt könntest du vorläufig zB mitloggen ob die logfunktion überhaupt aufgerufen wird und wenn ja mit welchem parameter:
void log(DWORD reason) { strimngstream sstr; sstr<<"Logfunktion wurde mit parameter "<<reason<<"aufgerufen!\n"; log<<sstr.str(); }6.Wozu das Semikolon am Ende der Funktion log()? ändert zwar nichts am ergebnis, geht aber auch ohne^^
lg,
andi01.
-
1. Geht auch ohne, aber egal^^
2. Hab ich auch gemacht, kam aber nichts (siehe Punkt 4)
3. Gute Idee, mach ich
4. Ist mir heut morgen auch aufgefallen, habs dann geändert und dann klappte alles. Deswegen kam das Programm gar nicht bis zum default.
5. Kann ich mir jetzt sparen
6. Reine Gewöhnungssache. Da ich fast ausschließlich OOP programmiere, und in Klassen das Semikolon nötig ist, habe ich mir einfach angwöhnt hinter jeder Klammer eine Funktion ein Semikolon zu setzen
-
erstmal: schön, dass es funktioniert

aber nochmal zu Punkt 1 (mit den breaks):
hier mal das ziemlich stark vereinfachte Beispiel deiner logfunktion:
void log_event(DWORD reason) { switch(reason) { case DLL_PROCESS_ATTACH: { cout<<"DLL_PROCESS_ATTACH\n"; } //break; case DLL_PROCESS_DETACH: { cout<<"DLL_PROCESS_DETACH\n"; } //break; } } int main() { log_event(DLL_PROCESS_ATTACH); }bei mir wird DLL_PROCESS_ATTACH und DLL_PROCESS_DETACH ausgegeben, wenn ich die breakes einfüge nur DLL_PROCESS_ATTACH.
ohne breaks ist das ergebnis nur identisch wenn man DLL_PROCESS_DETACH übergiebt weil danach keine weiteren cases folgen.
wenn bei dir also ein DLL_PROCESS_ATTACH geloggt werden sollte müsste sowohl ein attach als auch ein detach geloggt werden...
unwissenderneuling schrieb:
1. Geht auch ohne, aber egal^^
ja, der Compiler gibt keine Fehlermeldungen aus. aber das ergebnis ist nicht gleich.
Einfach mal obiges beispiel einmal mit und einmal ohne breaks kompilieren^^lg,
andi01.
-
Das liegt sehr wahrscheinlich daran, dass ich die breaks schon in der DllMain hatte. Wenn die so vereinfacht, wie du es gemacht hast sind die in der Funktion log() dann natürlich nötig

-
selbst wenn du sie in der main hattest sind die breaks in deiner log-funktion trotzdem nötig. hier wieder mal ein kleines beispiel
:void logfunc(int param) { switch(param) { case 1: { cout<<"1"; } //break; case 2: { cout<<"2"; } //break; } } int main() { int a=1; switch(a) { case 1: logfunc(1); break; case 2: logfunc(1); break; } getch(); }auch hier wird "12" statt "1" ausgegeben

aber da du den switch aus main gestrichen hast brauchst du die breaks jetzt sowieso 
lg,
andi01.