Pergunta

Eu tenho que incluir um aplicativo .NET em outro aplicativo .NET como um plugin. A interface do plugin requer me para herdar a partir de um modelo de formulário. A forma é depois ligado num MDI quando o plug-in é carregado.

Tudo está funcionando até agora, mas sempre que eu registrar para eventos de arrastar e soltar, defina o modo de autocomplete para um combobox ou em várias outras situações que recebo a seguinte exceção:

... o segmento atual deve ser definido como monomodo apartamento thread (STA) antes de OLE chamadas podem ser feitas. Garantir que a sua função principal tem STAThreadAttribute marcado sobre ele ...

A principal aplicação está em execução no MTA e desenvolvido por outra empresa, então não há nada que eu possa fazer sobre isso.

Eu tentei fazer as coisas que causam essas exceções em segmentos STA, mas isso não resolveu o problema.

Alguém já foi na mesma situação? Existe alguma coisa que posso fazer para resolver o problema?

Foi útil?

Solução 3

Update: A empresa lançou uma nova versão STA. A questão não é mais relevante.

Outras dicas

Você poderia tentar gerar nova thread e chamar CoInitialize com 0 sobre ele (aparment rosca) e executar o aplicativo neste segmento. No entanto, você não será a controles de atualização diretamente dentro desta discussão que você deve usar Control.Invoke para cada modificação UI.

Eu não sei se isso vai funcionar com certeza, mas você pode experimentá-lo.

Recentemente, corri para este problema sozinho ao tentar ler imagens de uma câmera web. O que eu acabei fazendo estava criando um método que gerou uma nova thread STA, no qual o método de thread único foi executado.

O problema

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

A solução:. Mova a lógica de thread único para o seu próprio método e chamar esse método de um novo segmento 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();
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top