2016-08-08 2 views
-1

기본 윈도우 핸들은 가비지 수집되지 않습니다. 그래서 인터넷에서 검색 한 후 MSDN 문서에서 SafeProcessHandle에 대해 알게되었습니다. 그것을 구현하는 시도하지만 난 현재 열려있는 창을 얻기 위해 'System.Runtime.InteropServices.SEHException을'Intptr 핸들이 가비지 수집되지 않음

https://msdn.microsoft.com/en-us/library/system.runtime.interopservices.safehandle.aspx

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Threading; 

namespace TestHandle 
{ 
class Program 
{ 
    [DllImport("user32.dll")] 
    static extern IntPtr GetForegroundWindow(); 

    [DllImport("user32.dll")] 
    static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId); 

    static void Main(string[] args) 
    { 
     while (true) 
     { 
      IntPtr hWnd = GetForegroundWindow(); 

      int processID = 0; 
      int threadID = GetWindowThreadProcessId(hWnd, out processID); 


      using (Process p = Process.GetProcessById(processID)) 
      { 
       StringBuilder text = new StringBuilder(256); 
       GetWindowText(hWnd, text, 256); 
       Console.WriteLine(text.ToString());      
      } 

      Console.WriteLine(hWnd); 
      Thread.Sleep(100); 
     } 

     char tmp = 'q'; 
     while (Console.Read() != tmp) ; 
    } 
} 
} 

수신하고, 나는 타이머를 통해 구현하는 노력도 동안을 시도하고있다 루프하지만 메모리 풋 프린트가 증가하고 PC가 실행될 때까지 작동하는 오랫동안 실행되는 콘솔 응용 프로그램을 설계한다면 상황이 점점 악화되고 있습니다. 누군가 나를 도와 줄 수 있습니까?

+0

이 창을 소유하지 않으므로 정리할 필요가 없습니다. 여기서 코드는 정리하려고하지 않습니다. 샐비어 핸들을 사용할 수 없습니다. 서비스는 대화 형 데스크톱에 액세스 할 수 없습니다. 달성하고자하는 것과 문제가 무엇인지 명확하게 밝혀주십시오. –

+0

실행중인 창을 얻으려면 장기간 실행되는 콘솔 응용 프로그램입니다. 예, 당신은 사실이지만 타이머에서이 코드를 실행하면 메모리 풋 프린트가 계속 증가하는 것을 볼 수 있습니다. – Jef

답변

0

GetForegroundWindow은 정돈 할 필요가없는 창 핸들을 반환합니다. 질문에 표시된 코드는 누출되지 않으며 안전한 핸들이 필요 없습니다. 관리되지 않는 리소스를 정리할 필요가있을 때 안전한 핸들을 사용합니다. 여기서는 그렇지 않습니다.

실제로 누출에 문제가있는 경우 수정할 필요가없는 코드와 관련이 없습니다.

업데이트

당신의 갱신에 관해서는 프로세스 ID와 닷넷 프로세스 개체를 얻을 무의미하다. 너는 그들을 사용하지 않는다. 실제로 창 핸들을 사용하여 창 텍스트를 요청할 수 있습니다.

여기에는 관리되지 않는 리소스가 누수되는 것이 나와 있으며 여기에는 안전한 핸들이 필요하지 않습니다. 프로세스 메모리 사용량이 증가하면 GC 기반 프로세스의 정상적인 동작이됩니다. 루프를 돌 때마다 새로운 StringBuilder 객체가 생성됩니다.

코드는 훨씬 간단 할 수있다 : 나는 적어도 관리 메모리 사용의 꾸준한 증가를 방지하는 하나의 StringBuilder 객체를-사용하고 있어요

StringBuilder text = new StringBuilder(256); 
    while (true) 
    { 
     IntPtr hWnd = GetForegroundWindow(); 
     GetWindowText(hWnd, text, 256); 
     Console.WriteLine(text.ToString()); 
     Console.WriteLine(hWnd); 
     Thread.Sleep(100); 
    } 

참고.

또한 API 호출의 반환 값을 검사해야하지만 오류에 대한 자세한 내용은 여기에 나와 있지 않습니다.

+0

선생님, 코드를 업데이트했습니다. 그리고 매 초마다 메모리 바이트가 증가하고 있습니다. – Jef

+0

내가 물은 질문에 대답했다. 이제 다른 질문을하십시오. 그것이 나를 격려하는 방법을 상상해보십시오. –

+0

나는이 문제에 갇혀있다. 더 잘 설명하기 위해 전체 소스 코드를 넣었다. 나는 당신의 우려를 진심으로 감사드립니다. – Jef

관련 문제