应用程序在单独的桌面上运行 [英] Application running itself on a separate desktop

查看:139
本文介绍了应用程序在单独的桌面上运行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试创建WPF caliburn micro应用程序,该应用程序创建一个单独的桌面并在其中显示其主窗口。

Trying to create a WPF caliburn micro application that creates a separate desktop and shows its main window there.

问题:创建桌面并切换到该位置后,

Problem: after the desktop is created and i switch there, no window is shown.

namespace WpfThreads
{
   class AppBootstrapper : Bootstrapper<WpfThreads.ViewModels.WpfThreadsViewModel>
   {
      protected override void OnStartup(object sender, StartupEventArgs e)
      {
          var desktop = Native.CreateDesktop("NewDesktop", 0, 0, 0, DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_HOOKCONTROL | DESKTOP_JOURNALRECORD | DESKTOP_JOURNALPLAYBACK | DESKTOP_ENUMERATE | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP, 0);
          Native.SetThreadDesktop(desktop);
          Native.SwitchDesktop(desktop);
          base.OnStartup(sender, e);
      }
   }
}

SetThreadDesktop()失败,其他通话成功。 OnStartup()方法确实在主线程(也是UI线程)上运行。

SetThreadDesktop() fails, other calls are successful. The OnStartup() method does run on main thread (which is also the UI thread).

推荐答案


如果调用线程在当前桌面上有任何窗口或挂钩,则 SetThreadDesktop 函数将失败。

C#UI线程没有任何窗口是非常不寻常的,因为项目向导将 Main()标记为 [STAThreadAttribute] ] ,这将导致在运行任何代码之前创建一个窗口。然后,该窗口将使您的线程与当前桌面保持永久关联,从而避免切换。

It's very unusual for a C# UI thread to not have any windows, because the project wizards mark Main() with [STAThreadAttribute], which causes a window to be created before any of your code runs. This window then gives your thread permanent affinity to the current desktop, preventing you from switching.

要同时拥有STA线程模型和使用安全性桌面,您需要做的是

What you need to do to have both STA threading model and use a security desktop is to activate STA by hand.

首先,创建桌面并使用 SetThreadDesktop 激活它。这不使用COM或创建任何窗口。

First, create the desktop and activate it with SetThreadDesktop. This does not use COM or create any windows.

然后,将COM线程模型设置为STA:

Then, set the COM threading model to STA:

Threading.Thread.CurrentThread.TrySetApartmentState(Threading.ApartmentState.STA);

这将创建一个窗口,将UI线程永久绑定到刚切换到的桌面。

This creates a window, permanently binding your UI thread to the desktop you just switched to.

完成这两个步骤后,您可以安全地开始使用其他UI类,例如WinForms和WPF窗口和小部件。

After performing both these steps, you can safely start using other UI classes such as WinForms and WPF windows and widgets.

不幸的是,这仅在.NET 1.x中可行,在未设置线程模型之前,它在新线程中未初始化COM。从2.0开始,在 Main()上缺少 STAThreadAttribute 的情况被解释为对MTA的请求,尽管这不会创建一个会干扰 SetThreadDesktop 的窗口,它确实会阻止以后更改为STA。而且,新线程从进程创建选项继承其桌面,而不是从产生它们的线程继承它们,因此您不能使用MTA线程来创建和设置桌面,然后再产生STA线程来执行UI工作- STA线程不会在新的桌面中结束。

Unfortunately, this was only possible in .NET 1.x, which left COM uninitialized in a new thread until you set the threading model. Since 2.0, lack of STAThreadAttribute on Main() is interpreted as a request for MTA, and although that won't create a window that interferes with SetThreadDesktop, it does prevent changing to STA later. And new threads inherit their desktop from the process-creation options, not from the thread that spawns them, so you can't use an MTA thread to create and set the desktop and then spawn a STA thread to perform the UI work -- the STA thread won't end up in the new desktop.

这篇关于应用程序在单独的桌面上运行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆