using System; using System.Threading; using System.Windows; using System.Windows.Controls; using System.Runtime.InteropServices; using System.Windows.Threading; class Program { // DESKTOP_ACCESS const UInt32 DESKTOP_NONE = 0x0000u; const UInt32 DESKTOP_READOBJECTS = 0x0001u; const UInt32 DESKTOP_CREATEWINDOW = 0x0002u; const UInt32 DESKTOP_CREATEMENU = 0x0004u; const UInt32 DESKTOP_HOOKCONTROL = 0x0008u; const UInt32 DESKTOP_JOURNALRECORD = 0x0010u; const UInt32 DESKTOP_JOURNALPLAYBACK = 0x0020u; const UInt32 DESKTOP_ENUMERATE = 0x0040u; const UInt32 DESKTOP_WRITEOBJECTS = 0x0080u; const UInt32 DESKTOP_SWITCHDESKTOP = 0x0100u; const UInt32 dwDesiredAccess = DESKTOP_READOBJECTS | DESKTOP_CREATEWINDOW | DESKTOP_CREATEMENU | DESKTOP_WRITEOBJECTS | DESKTOP_SWITCHDESKTOP; [DllImport("kernel32.dll")] static extern uint GetCurrentThreadId(); [DllImport("user32.dll")] static extern IntPtr GetThreadDesktop(uint dwThreadId); [DllImport("user32.dll")] static extern IntPtr CreateDesktop(string desktopName, IntPtr device, IntPtr deviceMode, uint flags, uint accessMask, IntPtr attributes); [DllImport("user32.dll")] static extern bool SetThreadDesktop(IntPtr hDesktop); [DllImport("user32.dll")] static extern bool CloseDesktop(IntPtr hDesktop); [DllImport("user32.dll")] static extern bool SwitchDesktop(IntPtr hDesktop); [STAThread] public static void Main() { var btn = new Button() { Content = "Open secure desktop" }; btn.Click += (s, e) => SecureDialog(); var win = new Window() { Content = btn }; new Application().Run(win); } static void SecureDialog() { var hOldDesktop = GetThreadDesktop(GetCurrentThreadId()); var hNewDesktop = CreateDesktop("My desktop", IntPtr.Zero, IntPtr.Zero, 0, dwDesiredAccess, IntPtr.Zero); SwitchDesktop(hNewDesktop); var thread = new Thread( () => SecureDesktopThread(hNewDesktop) ); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); // Wait for thread to complete. SwitchDesktop(hOldDesktop); CloseDesktop(hNewDesktop); } static void SecureDesktopThread(IntPtr hNewDesktop) { SetThreadDesktop(hNewDesktop); SynchronizationContext.SetSynchronizationContext( new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher)); var win = new Window() { Content = "Hello World!", FontSize=30 }; win.ShowDialog(); Dispatcher.CurrentDispatcher.InvokeShutdown(); } }