Frage

Hier ist mein Problem: Ich brauche einen Prozess zu schließen, bereits ausgeführt wird, von einem C # -Programm. Das Problem ist, dass der Prozess läuft nun als Symbol (auf der Taskleiste minimiert), und es sei denn, der Benutzer es mindestens einmal öffnet (was nie unbeaufsichtigt Maschinen passieren wird), es werde nie hat ein Hauptfenster.

Die andere Anforderung, die ich habe, ist, dass die Anwendung sein geschlossen nicht getötet . Ich brauche es, es ist auf der Festplatte Speicherpuffer zu schreiben -. Und tötet sie verursacht Datenverlust

Hier ist, was ich versuchte, so weit:

        foreach (Process proc in Process.GetProcesses())
        {
            if (proc.ProcessName.ToLower().StartsWith("myapp"))
            {
                if (proc.MainWindowHandle.ToInt32() != 0)
                {
                    proc.CloseMainWindow();
                    proc.Close();
                    //proc.Kill();  <--- not good!
                }
            }
        }

Ich habe die hinzugefügt, wenn Klausel, nach der Entdeckung, dass die Mainwindowhandle == 0 , wenn das Fenster minimiert wurde. Entfernen Sie die , wenn hilft nicht. Weder die Closemainwindow () noch die Close () Arbeit. Das kill () der Fall ist, aber wie oben erwähnt -. Es ist nicht das, was ich brauche

Jede mögliche Idee akzeptiert werden, einschließlich der Verwendung von obskuren Win32-API-Funktionen:)

War es hilfreich?

Lösung 3

Hier sind einige Antworten und Erklärungen:

rpetrich : Versucht Ihre Methode vor, und das Problem ist, ich weiß nicht den Fensternamen kennen, unterscheidet sie sich von Benutzer zu Benutzer, Version zu Version - nur die exe Name bleibt konstant. Ich habe alle ist der Prozessname. Und wie Sie im Code über dem Mainwindowhandle des Prozesses sehen können, ist 0.

Roger : Ja, ich habe die Taskleiste Infobereich bedeuten - Danke für die Klarstellung. I NEED PostQuitMessage zu nennen. Ich weiß nur nicht, wie ein processs nur gegeben, und kein Fenster.

Craig : Ich würde mich freuen, die Situation zu erklären: Die Anwendung verfügt über eine Befehlszeilenschnittstelle, so dass Sie Parameter angeben, die diktieren, was sie tun würde, und wo wird es die Ergebnisse speichern. Aber sobald es läuft ist der einzige Weg, um es zu stoppen und die Ergebnisse erhält, wird die rechte Maustaste in dem Fach Benachrichtigung und wählen Sie ‚exit‘.

Jetzt möchte meine Benutzer Skript / Batch die App. Sie hatten absolut kein Problem es aus einem Batch-Start (nur die exe-Namen angeben und und ein paar Fahnen) bekam aber dann mit einem laufenden Prozess stecken. Unter der Annahme, niemand wird den Prozess ändern, um eine API zur Verfügung zu stellen, ihn zu stoppen beim Laufen (es ist ziemlich alt), habe ich eine Art und Weise müssen sie künstlich schließen.

In ähnlicher Weise auf unbeaufsichtigten Computern, das Skript zum Starten des Prozesses kann durch eine Aufgabenplanung oder Operationen steuern Programm gestartet werden, aber es gibt keinen Weg, um den Prozess zu beenden.

Hoffnung, dass meine Situation klärt, und wieder, dank jeder, der zu helfen versucht!

Andere Tipps

Dies sollte funktionieren:

[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr FindWindow(string className, string windowName);
[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

private const int WM_CLOSE = 0x10;
private const int WM_QUIT = 0x12;

public void SearchAndDestroy(string windowName) 
{
    IntPtr hWnd = FindWindow(null, windowName);
    if (hWnd == IntPtr.Zero)
        throw new Exception("Couldn't find window!");
    SendMessage(hWnd, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);
}

Da einige Fenster reagieren nicht auf WM_CLOSE, WM_QUIT haben könnte stattdessen gesendet werden. Diese Erklärungen sollen beide arbeiten auf 32bit und 64bit.

Wenn es in der Taskleiste ist, wird es ein Fenster. Oder meinen Sie, dass es in der Taskleiste ist (auch bekannt als die SysTray)? In diesem Fall, haben sie immer noch ein Fenster.

Win32-Anwendungen nicht wirklich ein „Hauptfenster“, mit Ausnahme von Konvention (das Hauptfenster ist derjenige, der PostQuitMessage als Reaktion auf WM_DESTROY ruft die Nachrichtenschleife verursacht verlassen).

Mit dem Programm ausgeführt wird, führen Spy ++. Um alle Fenster durch ein Verfahren zu finden im Besitz, sollten Sie Spy wählen -> Prozesse aus dem Hauptmenü. Dies wird einen Baum von Prozessen angezeigt werden soll. Von dort können Sie unten auf das Gewinde bohren, und dann zu den Scheiben. Dies wird Ihnen sagen, welche Fenster der Prozess hat. Beachten Sie die Fensterklasse und Beschriftung nach unten. Mit diesen können Sie Findwindow (oder EnumWindows) den Fenstergriff in Zukunft zu finden.

Mit dem Fenstergriff, können Sie ein WM_CLOSE oder WM_SYSCOMMAND / SC_CLOSE (entspricht einem Klick auf das ‚X‘ auf der Fensterbeschriftung) Nachricht senden. Dies sollte das Programm heruntergefahren schön führen.

Beachten Sie, dass ich von einem Win32-Point-of-View bin hier im Gespräch. Unter Umständen müssen Sie P / Invoke oder andere Tricks verwenden, um diese von einem .NET-Programm zu arbeiten.

Frage zu klären, warum Sie dies versuchen: Wenn die einzige Benutzeroberfläche auf dem Prozess das System Tray-Icon ist, warum sollten Sie, dass töten wollen und doch den Prozess laufen lassen? Wie würde der Benutzer auf den Prozess? Und wenn die Maschine „unbeaufsichtigt“ ist, warum beschäftigen Sie sich mit dem Tray-Icon?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top