문제

내 문제는 다음과 같습니다.C# 프로그램에서 이미 실행 중인 프로세스를 닫아야 합니다.문제는 프로세스가 이제 아이콘으로 실행되며 (작업 표시 줄로 최소화) 사용자가 한 번 이상 열리지 않으면 (무인 기계에서는 결코 발생하지 않을 경우) 기본 창이 없습니다.

제가 갖고 있는 또 다른 요구 사항은 신청서가 다음과 같아야 한다는 것입니다. 닫은 ~ 아니다 사망.메모리 버퍼를 디스크에 쓰는 데 필요합니다. 이를 종료하면 데이터가 손실됩니다.

지금까지 시도한 내용은 다음과 같습니다.

        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!
                }
            }
        }

나는 만약에 조항, 그것을 발견한 후 메인윈도우핸들 == 0 창이 최소화되었을 때.제거 만약에 도움이 되지 않습니다.둘 다 닫기메인창() 도 아니고 닫다() 일하다.그만큼 죽이다() 하지만 위에서 언급했듯이 그것은 나에게 필요한 것이 아닙니다.

난해한 Win32 API 기능을 사용하는 것을 포함하여 어떤 아이디어라도 받아들여질 것입니다. :)

도움이 되었습니까?

해결책 3

다음은 몇 가지 답변과 설명입니다.

르페트리치:이전에 방법을 시도했지만 문제는 창 이름을 모르고 사용자마다, 버전마다 다르다는 것입니다. exe 이름만 일정하게 유지됩니다.내가 가진 것은 프로세스 이름뿐입니다.위 코드에서 볼 수 있듯이 프로세스의 MainWindowHandle은 0입니다.

알았다:예, 작업 표시줄 알림 영역을 의미했습니다. 설명해주셔서 감사합니다.나 필요 PostQuitMessage를 호출합니다.Window가 아닌 ​​프로세스만 주어지면 방법을 모르겠습니다.

크레이그:상황을 설명해 드리겠습니다.응용 프로그램에는 명령줄 인터페이스가 있어 수행할 작업과 결과를 저장할 위치를 지정하는 매개 변수를 지정할 수 있습니다.그러나 일단 실행되면 중지하고 결과를 얻는 유일한 방법은 트레이 알림에서 마우스 오른쪽 버튼을 클릭하고 '종료'를 선택하는 것입니다.

이제 사용자는 앱을 스크립트/일괄 처리하기를 원합니다.배치에서 시작하는 데 전혀 문제가 없었지만(exe 이름과 여러 플래그만 지정) 실행 중인 프로세스에 문제가 발생했습니다.실행 중에 중지하는 API를 제공하기 위해 프로세스를 변경하는 사람이 아무도 없다고 가정하면(상당히 오래됨) 인위적으로 닫을 수 있는 방법이 필요합니다.

마찬가지로 무인 컴퓨터에서는 작업 예약 또는 작업 제어 프로그램을 통해 프로세스를 시작하는 스크립트를 시작할 수 있지만 프로세스를 종료할 수 있는 방법은 없습니다.

제 상황이 명확해졌기를 바라며 다시 한번 도움을 주시는 모든 분들께 감사드립니다!

다른 팁

이것은 작동합니다:

[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);
}

일부 창이 응답하지 않기 때문에 WM_CLOSE, WM_QUIT 대신 보내야 할 수도 있습니다.이러한 선언은 32비트와 64비트 모두에서 작동해야 합니다.

작업 표시줄에 있으면 창이 나타납니다.아니면 작업 표시줄 알림 영역(SysTray라고도 함)에 있다는 뜻인가요?어떤 경우에도 여전히 창이 있을 것입니다.

Win32 응용 프로그램에는 관례를 제외하고 실제로 "기본 창"이 없습니다. 기본 창은 WM_DESTROY에 대한 응답으로 PostQuitMessage를 호출하여 메시지 루프를 종료시키는 창입니다.

프로그램이 실행 중인 상태에서 Spy++를 실행합니다.프로세스가 소유한 모든 창을 찾으려면 기본 메뉴에서 Spy -> 프로세스를 선택해야 합니다.그러면 프로세스 트리가 표시됩니다.여기에서 스레드로 드릴다운한 다음 창으로 드릴다운할 수 있습니다.그러면 프로세스에 어떤 창이 있는지 알려줍니다.창 클래스와 캡션을 기록해 둡니다.이를 통해 FindWindow(또는 EnumWindows)를 사용하여 나중에 창 핸들을 찾을 수 있습니다.

창 핸들을 사용하면 WM_CLOSE 또는 WM_SYSCOMMAND/SC_CLOSE(창 캡션에서 'X'를 클릭하는 것과 동일) 메시지를 보낼 수 있습니다.이로 인해 프로그램이 정상적으로 종료되어야 합니다.

여기서는 Win32 관점에서 이야기하고 있다는 점에 유의하세요..NET 프로그램에서 이 작업을 수행하려면 P/Invoke 또는 기타 트릭을 사용해야 할 수도 있습니다.

왜 이것을 시도하는지 명확히 하기 위한 질문:프로세스의 유일한 사용자 인터페이스가 시스템 트레이 아이콘이라면 왜 해당 아이콘을 종료하고 프로세스는 계속 실행되도록 하시겠습니까?사용자는 프로세스에 어떻게 액세스합니까?기계가 "무인"인 경우 왜 트레이 아이콘에 관심을 갖습니까?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top