Ahoi fleißige C#ler 😉,
ich möchte ein Tool schreiben, bei dem ich überprüfe ob gewisse Prozesse laufen, wenn ja soll die Laufzeit von der Startzeit bis zur Endzeit des jeweiligen Prozesses in eine Datenbank gespeichert werden. Gleichzeitig wird überprüft, wie lange der Prozess schon gelaufen ist (innerhalb einer Woche, dann wird wieder auf 0 gesetzt) und wenn er zu lange läuft, z.B länger als 10 h in einer Woche soll er beendet werden.
Zur Zeit habe ich eine MySQL Datenbank in der ich user mit Zeitkontingent eingetragen habe, eine tbl mit Prozessen + ID und eine mit userID, username und Zeit
Mein Problem liegt darin, dass ich nicht weiß wie ich überprüfen kann wie lange ein bestimmter Prozess läuft bzw. wenn mehere Prozesse die auf der "Blacklist" stehen laufen.
Meine Idee bis jetzt war in einem timer dauernt zu überprüfen ob ein Prozess läuft, und wenn ja einen neuen Timer zu starten
private void m_timProz_Tick(object sender, EventArgs e)
{
foreach (ClsProzess propertie in m_lstProz)
{
if (CheckIfAProcessIsRunning(propertie.Name) == true)
{
m_timLaufend.Start();
}
}
}
private bool CheckIfAProcessIsRunning(string processname)
{
return Process.GetProcessesByName(processname).Length > 0;
}
funktioniert aber nicht... ich bin gerade etwas ratlos, und hoffe mir kann jemand helfen
danke schonmal 😃
greetz daddithegood
🙂
Hallo daddithegood,
einen Timer musst du nicht neu starten. Er löst von alleine immer wieder aus, sofern er nicht gestoppt wird. Allerdings bekommt man bei Windows.Forms.Timer keine Events, wenn das GUI blockiert ist. Siehe [FAQ] Warum blockiert mein GUI?
herbivore
@koller
Also, 1. weiß ich nicht wie man mitprotokollieren kann wenn mehrere Prozesse laufen und 2. funtkioniert das mit den 2 Timer nicht, obwohl es theoretisch doch gehen sollte(im 2. Timer prüfe ich in einer foreach ob der prozess noch rennt, und wenn beendet schreibe ich die vergangene Zeit in die DB), aber es kommen immer irgendwelche Zeiten raus
@herbivore
wieso neustarten? ich starte ja einen 2. timer, und den nur wenn ein prozess in der datenbank gefunden wurde, um zu sehen wie lange ein prozess läuft
🙂
Ich habe diese Funktionalität auch einmal gebaut und das mit Wmi gelöst. Dort gibt es events, die gefeuert werden, wenn ein Prozess startet, und wenn er beendet wird.
Leider bekommt man nicht mitgeteit, was gestartet nd gestoppt wurde, deswegen muss man das dann noch manuell Prüfen.
Dann gibt es bei dem ganzen noch einen Bug, den ich mir trotz längerer Suche nicht erklären konnte. Und zwar implementiert die klasse IDisposable, aber wenn man die Anwendung beendet, gibt es diesen Fehler(bei mir nur wenn der Debuger angeschlossen ist: Ein COM-Objekt, das vom zugrunde liegenden RCW getrennt wurde, kann nicht verwendet werden.
Deswegen einfach Dispose manuell vor dem Schließen aufrufen, dann gibts keine Fehler.
public class ProcessChangeWatcher : IDisposable
{
WqlEventQuery start_query;
WqlEventQuery stop_query;
ManagementEventWatcher start_watcher;
ManagementEventWatcher stop_watcher;
volatile bool _disposed;
event EventHandler _statusChanged;
object _statusChangedLock = new object();
public ChangeWatcher()
{
StartProcessWatching();
}
public event EventHandler StatusChanged
{
add
{
if (_disposed) throw new ObjectDisposedException(ToString());
lock (_statusChangedLock)
_statusChanged += value;
}
remove
{
if (_disposed) throw new ObjectDisposedException(ToString());
lock (_statusChangedLock)
_statusChanged -= value;
}
}
private void StartProcessWatching()
{
if (_disposed) throw new ObjectDisposedException(ToString());
start_query = new WqlEventQuery("Win32_ProcessStartTrace");
start_watcher = new ManagementEventWatcher(start_query);
start_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
start_watcher.Start();
stop_query = new WqlEventQuery("Win32_ProcessStopTrace");
stop_watcher = new ManagementEventWatcher(stop_query);
stop_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
stop_watcher.Start();
}
void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
//Changed
if (_disposed) return;
lock (_statusChangedLock)
{
if (_statusChanged != null)
_statusChanged(this, EventArgs.Empty);
}
}
public void Dispose()
{
try
{
if (_disposed) throw new ObjectDisposedException(ToString());
_disposed = true;
start_watcher.EventArrived -= watcher_EventArrived;
stop_watcher.EventArrived -= watcher_EventArrived;
start_watcher.Stopped += (s, e) => start_watcher.Dispose();
stop_watcher.Stopped += (s, e) => stop_watcher.Dispose();
start_watcher.Stop();
stop_watcher.Stop();
}
catch { }
}
}
Hallo daddithegood,
mir ist nicht klar, warum du meinst, zwei Timer zu brauchen. Einer sollte reichen.
- weiß ich nicht wie man mitprotokollieren kann wenn mehrere Prozesse laufen
Merk dir z.B. in einem Dictionary zu jedem Prozess die Startzeit (oder die Zeit zu der du mitbekommen hast, dass der Prozess jetzt läuft). Die einzige Frage ist doch, was passieren soll, wenn es zu einer exe mehrere Instanzen(Prozesse) gibt. Im Zweifel musst du also noch die ProzessID in den Key mit aufnehmen hinzuziehen.
aber es kommen immer irgendwelche Zeiten raus
Was genau meinst du damit?
herbivore