2009-06-30 5 views
1

.NET 응용 프로그램을 다른 .NET 응용 프로그램에 플러그인으로 포함해야합니다. 플러그인 인터페이스를 사용하려면 템플릿 양식을 상속해야합니다. 플러그인은 플러그인이로드 될 때 MDI에 첨부됩니다.STA, MTA 및 OLE 악몽

모든 것은 지금까지 작업,하지만 난 드래그 등록하고 이벤트를 제거 할 때마다, 콤보 또는 나는 다음과 같은 예외가 얻을 여러 다른 상황에서 자동 완성 모드를 설정됩니다 ...

를 현재 스레드를 OLE 호출을 수행하기 전에 단일 스레드 아파트 (STA) 모드 으로 설정해야합니다. 자신의 메인 함수가 STAThreadAttribute가에 표시 을 가지고 ...

주요 응용 프로그램을 MTA에서 실행하고 다른 회사에 의해 개발되어 있는지 확인, 그래서 그것에 대해 할 수있는 일은 없습니다.

STA 스레드에서 이러한 예외를 발생시키는 작업을 시도했지만 문제가 해결되지 않았습니다.

같은 상황에 있었던 사람이 있습니까? 문제를 해결하기 위해 제가 할 수있는 일이 있습니까?

답변

0

업데이트 : 회사에서 새로운 STA 버전을 발표했습니다. 문제는 더 이상 적합하지 않습니다.

2

새 스레드를 생성하고 CoInitialize를 0으로 호출하여 (스레드가 스레드 됨)이 스레드에서 응용 프로그램을 실행할 수 있습니다. 그러나이 스레드 내에서 컨트롤을 직접 업데이트하지 않아도됩니다. UI 수정마다 Control.Invoke를 사용해야합니다.

이것이 확실하게 작동하는지 모르겠지만 시도해 볼 수 있습니다.

+0

의견을 보내 주셔서 감사합니다. 하지만 MTA 스레드에 의해 만들어진 UI 요소를 호출 할 때 동일한 오류가 발생했습니다. – xsl

+1

응용 프로그램 시작 방법을 제어 할 수 있습니까? 컨테이너 앱으로 포장 할 수있는 것보다 큽니다. 스레드를 만들고 COM을 초기화하고 프로그램의 Main 메서드를 호출하십시오. 응용 프로그램에 따라이 프로그램이 작동하거나 작동하지 않을 수 있으며 주 프로그램이 중단 될 수 있지만 최후의 수단이 될 수 있습니다. (주 응용 프로그램을 디 컴파일하고 변경하기 전에 불법 일 수 있습니다.) 또한 개발 한 회사에 문의 할 수도 있습니다. – devdimi

+0

새 스레드 t를 시작하고 t.SetApartmentState (System.Threading.ApartmentState.STA), t.Start()를 사용하면 아무 것도 잘못 될 수 있습니다. 그냥 작동, 내 거대한 애플 리케이션에서 직장에서 테스트. – Harry

1

웹 카메라에서 이미지를 읽으려고 할 때 최근에이 문제가 발생했습니다. 내가 한 일은 싱글 스레드 메서드가 실행 된 새로운 STA 스레드를 생성하는 메서드를 만드는 것이 었습니다.

문제

private void TimerTick(object sender, EventArgs e) 
{ 
    // pause timer 
    this.timer.Stop(); 

     try 
     { 
      // get next frame 
      UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0); 

      // copy frame to clipboard 
      UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0); 

      // notify event subscribers 
      if (this.ImageChanged != null) 
      { 
       IDataObject imageData = Clipboard.GetDataObject(); 

       Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap); 

       this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero))); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error capturing the video\r\n\n" + ex.Message); 
      this.Stop(); 
     } 
    } 
    // restart timer 
    Application.DoEvents(); 

    if (!this.isStopped) 
    { 
     this.timer.Start(); 
    } 
} 

솔루션 : 자신의 방법으로 단일 스레드 논리를 이동하고 새로운 STA 스레드에서이 메서드를 호출합니다.

private void TimerTick(object sender, EventArgs e) 
{ 
    // pause timer 
    this.timer.Stop(); 

    // start a new thread because GetVideoCapture needs to be run in single thread mode 
    Thread newThread = new Thread(new ThreadStart(this.GetVideoCapture)); 
    newThread.SetApartmentState(ApartmentState.STA); 
    newThread.Start(); 

    // restart timer 
    Application.DoEvents(); 

    if (!this.isStopped) 
    { 
     this.timer.Start(); 
    } 
} 

/// <summary> 
/// Captures the next frame from the video feed. 
/// This method needs to be run in single thread mode, because the use of the Clipboard (OLE) requires the STAThread attribute. 
/// </summary> 
private void GetVideoCapture() 
{ 
    try 
    { 
     // get next frame 
     UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraGetFrame, 0, 0); 

     // copy frame to clipboard 
     UnsafeNativeMethods.SendMessage(this.captureHandle, WindowsMessageCameraCopy, 0, 0); 

     // notify subscribers 
     if (this.ImageChanged!= null) 
     { 
      IDataObject imageData = Clipboard.GetDataObject(); 

      Image image = (Bitmap)imageData.GetData(System.Windows.Forms.DataFormats.Bitmap); 

      // raise the event 
      this.ImageChanged(this, new WebCamEventArgs(image.GetThumbnailImage(this.width, this.height, null, System.IntPtr.Zero))); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show("Error capturing video.\r\n\n" + ex.Message); 
     this.Stop(); 
    } 
}