2016-07-17 2 views
0

저는 마우스와 키보드 시뮬레이션을 사용하는 프로그램에서 작업 중이며 종종 클립 보드 데이터를 가져 오거나 설정해야합니다.

많은 사람들이 실행되는 문제가 발생했습니다. 클립 보드가 다른 프로세스에서 사용 중이므로 "Clipboard.SetDataObject"에서 예외가 발생합니다. "요청한 클립 보드 작업이 성공하지 못했습니다."Idle.exe에서 이미 사용중인 클립 보드

 private void CheckSetClipboard(string s) 
    { 
     IntPtr ClipWindow = GetOpenClipboardWindow(); 
     if (ClipWindow != null && ClipWindow != (IntPtr)0) 
     { 
      uint wid; 
      GetWindowThreadProcessId(ClipWindow, out wid); 
      Process p = Process.GetProcessById((int)wid); 
      Console.WriteLine("Process using Clipboard: " + p.ProcessName); 
     } else { 
      Console.WriteLine("ClipWindow:" + ClipWindow.ToString()); 
     } 
      OpenClipboard(IntPtr.Zero); 
      EmptyClipboard(); 
      CloseClipboard(); 
     try { Clipboard.SetDataObject(s, true, 10, 50); } 
     catch{// Clipboard.SetDataObject(s, true, 10, 50); 
     } 
    } 

위의 코드 에서처럼 몇 가지 해결책을 시도했지만 결국 오류가 다시 나타납니다.

프로세스 사용하여 클립 보드 :

가 어떻게 유휴 이번에는이 콘솔이 보였다 무엇
.. 클립 보드를 사용에서 전체 햄을 가기로 결정 프로세스의 프로세스 이름을 얻었다 Idle.exe는 클립 보드를 사용하고 있습니까?
해당 프로세스를 종료하여 클립 보드를 해제 할 수 있습니까?
내가 잘못하고 있니?

결국 나는 실패없이 클립 보드 작업을 수행 할 수 있기를 원합니다. Ctrl + c 및 Ctrl + v가 실패하지 않습니다. 왜 C# 코드가 작동합니까?

더 많은 정보 :
나는 클립 보드에 전달할 데이터가 "-0.09261441"또는 이와 유사한 숫자입니다.
오류는 항상 catch {...} 부분에서 발생합니다.

[SOLVED] 한스 덕분에 알아낼 수있었습니다. 팁과 샘플 코드를 pinvoke에 잘못 해석했습니다. try {} catch {}에서 두 가지 클립 보드 작업이 어떤 식 으로든 상충되는 것처럼 보입니다. 적절한 방법은 사용하지 않았고 테스트하지 않은 try {} catch {try {} catch {}}를 사용했을 것입니다.

두 번째 클립 보드 작업을 주석 처리 할 때 내 문제가 해결 된 것 같습니다.

+0

유휴 EXE를보십시오. IDisposable 패턴을 사용하여 IntPtr을 처리하려고 시도하십시오. 예 : http://stackoverflow.com/questions/6093449/proper-intptr-use-in-c-sharp –

+0

흠, 그 논리 또는 구현의 논리를 잘 모르겠습니다. . 나는 "Marshal.FreeHGlobal (ClipWindow);"을 추가하려고 시도했다. "if (ClipWindow! = null) {...}"섹션 바로 다음에 같은 오류가 표시됩니다. 오류가 100 % 발생하기 때문에 내가 뭔가 잘못하고 있다고 생각하기 시작했습니다. – JMC17

+1

"유휴 프로세스에서 사용"이 아니라 "실패했습니다"로 0을 해석해야합니다. 2 개의 값을 저장하기 위해 1 개의 변수를 사용하면 실패 할 수있는 한 가지 방법 일 수 있습니다. 실제로 프로세스 ID가 아닌 스레드 ID를 사용합니다. –

답변

1

코드를 사용하여 Dispossable 클래스를 만들고 (일부 변경) 누락 된 메서드를 채우고 아무 문제없이 실행합니다. winform 응용 프로그램에서 테스트합니다.

단추에서 메서드를 호출하고 한 텍스트 상자에서 복사 한 다음 다른 텍스트 상자에 값을 붙여 넣으면 붙여 넣기 결과가 매달리지 않고 유효합니다. IDisposable에서 클래스를 상속 받도록하여 핸들을 자동으로 처리하는 방법에 유의하십시오.

는 포인터 INTPTR를 처리하지 않은 코드를

class ClipboardUtility : IDisposable 
{ 
    private bool disposed = false; 

    //If the function succeeds, the return value is the handle to the window that has the clipboard open. 
    //If no window has the clipboard open, the return value is NULL. 
    //To get extended error information, call GetLastError. 

    [DllImport("user32.dll")] 
    static extern IntPtr GetOpenClipboardWindow(); 

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

    [DllImport("user32.dll", SetLastError = true)] 
    static extern bool OpenClipboard(IntPtr hWndNewOwner); 

    [DllImport("user32.dll", SetLastError = true)] 
    static extern bool CloseClipboard(); 
    [DllImport("user32.dll")] 
    static extern bool EmptyClipboard(); 

    private IntPtr ClipWindow; 
    public void CheckSetClipboard(string s) 
    { 

     //IntPtr ClipWindow = GetOpenClipboardWindow(); 
      ClipWindow = GetOpenClipboardWindow(); 
     Console.WriteLine("handle IntPtr= {0}", ClipWindow); 
     // if (ClipWindow != null && ClipWindow != (IntPtr)0) 
     if (ClipWindow != null) 
     { 
      Console.WriteLine("ClipWindow_" + ClipWindow.ToString()); 
      uint wid = GetWindowThreadProcessId(ClipWindow, out wid); 
      Process p = Process.GetProcessById((int)wid); 
      Console.WriteLine("Process using Clipboard: " + p.ProcessName); 
     } 
     else 
     { 
      Console.WriteLine("error: {0}", Marshal.GetLastWin32Error()); 
      // Console.WriteLine("0 is not idle"); 
     } 

     //Marshal.FreeHGlobal(ClipWindow); 
     //OpenClipboard(IntPtr.Zero); 
     //EmptyClipboard(); 
     //CloseClipboard(); 
     //Console.WriteLine("s: " + s); 

     try 
     { 
      Clipboard.SetDataObject(s, true, 10, 50); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
      // Clipboard.SetDataObject(s, true, 10, 50); 
     } 
    } 

    public void Dispose() 
    { 
     Dispose(true); 
     GC.SuppressFinalize(this); 
    } 

    protected virtual void Dispose(bool disposing) 
    { 
     if (!this.disposed) 
     { 
      CloseHandle(ClipWindow); 

      ClipWindow = IntPtr.Zero; 

      disposed = true; 

     } 
    } 

    [DllImport("Kernal32")] 
    private extern static Boolean CloseHandle(IntPtr handle); 
} 
+0

이미 내 문제를 해결하는 데 불구하고이 코드를 살펴보고 시도하고 모든 것을 이해하는 데 최선을 다할 것입니다. 귀하의 의견을 보내 주셔서 감사합니다! – JMC17