2009-08-28 47 views
2

我想創建新的窗口站& Windows桌面和附加我的​​過程。我怎麼能做到這一點我如何創建窗口站和Windows桌面使用C#

我需要知道

  1. 創建窗口站和連接我的桌​​面

  2. 桌面之間創建&切換有效

  3. 我如何安裝過程中Winlogon中桌面(如果可能的話)

  4. Destroy created桌面並返回到Windows桌面

+1

本文將與對組合幫助/調用:http://www.brianbondy.com/blog/id/100/understanding-windows-at-a-更深層次的會話窗口站和桌面 – 2010-10-22 14:17:56

+0

感謝您的評論brian – 2010-10-23 04:08:17

回答

0

雖然Windows支持多個「窗口站」,該documentation指出:

交互窗口站,Winsta0,是唯一的窗口站可顯示用戶界面或接收用戶輸入。它被分配給交互式用戶的登錄會話,幷包含鍵盤,鼠標和顯示設備。所有其他窗口工作站都是非交互式的,這意味着他們無法顯示用戶界面或接收用戶輸入。

這表明以您提議的方式在窗口站之間切換的能力是不可能的。

3

每個「會話」只有一個交互式窗口站,但可以有多個會話。

http://blogs.technet.com/markrussinovich/archive/2010/02/24/3315174.aspx

我不知道一個API直接創建一個登錄會話的,但如果你用的是Windows Server版本,你可以使用遠程桌面創建一個本地會話,自動運行您的程序存在,然後註銷再次程序結束後(您在遠程桌面會話中運行的程序在完成時可以註銷)。

以下代碼將使用MSTSC ActiveX控件以編程方式創建RDP會話。您將需要手動生成ActiveX存根並將它們添加到您的項目中。

  1. 從Visual Studio命令提示符處鍵入以下內容:

    aximp.exe %windir%\system32\mstscax.dll

  2. 複製生成的文件(MSTSCLib.dll和AxMSTSCLib.dll)到項目目錄。

  3. 將這兩個文件添加到項目引用。

 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Windows.Forms; 
using AxMSTSCLib; 
using MSTSCLib; 
using System.Runtime.InteropServices;

namespace AutoLogin { public partial class Form1 : Form { private AxMSTSCLib.AxMsRdpClient5 rdpClient; public Form1() { InitializeComponent(); rdpClient = new AxMSTSCLib.AxMsRdpClient5(); ((ISupportInitialize)rdpClient).BeginInit(); rdpClient.Enabled = true; rdpClient.Location = new System.Drawing.Point(0, 0); rdpClient.Name = "MsRdpClient"; rdpClient.Size = ClientSize; rdpClient.TabIndex = 1; rdpClient.Anchor = (AnchorStyles) (AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right); Controls.Add(rdpClient); ((ISupportInitialize)rdpClient).EndInit(); }

void axRemoteDesktop_OnDisconnected (object sender, IMsTscAxEvents_OnDisconnectedEvent e) { Application.Idle += ExitTimerEvent; } public void ExitTimerEvent(object source, EventArgs e) { Application.Idle -= ExitTimerEvent; // Attempt to close down the session we just connected to (there // appears to be no way to get the session id, so we just close all // disconnected sessions. if (rdpClient.Connected == 1) { rdpClient.Disconnect(); } LogoffDisconnectedSessions(); Close(); } private Timer logoffTimer; private void Form1_Load(object sender, EventArgs e) { // Close down any existing disconnected sessions, the number of // available sessions is limited. LogoffDisconnectedSessions(); String username = "username"; String password = "password"; rdpClient.Server = "localhost"; rdpClient.UserName = username; rdpClient.AdvancedSettings2.ClearTextPassword = password; rdpClient.Domain = ""; rdpClient.FullScreen = false; rdpClient.AdvancedSettings2.RedirectDrives = false; rdpClient.AdvancedSettings2.RedirectPrinters = false; rdpClient.AdvancedSettings2.RedirectPorts = false; rdpClient.AdvancedSettings2.RedirectSmartCards = false; rdpClient.AdvancedSettings6.RedirectClipboard = false; rdpClient.AdvancedSettings6.MinutesToIdleTimeout = 1; rdpClient.OnDisconnected += new AxMSTSCLib.IMsTscAxEvents_OnDisconnectedEventHandler (axRemoteDesktop_OnDisconnected); rdpClient.Connect(); logoffTimer = new Timer(); logoffTimer.Tick += new EventHandler(LogoutTimerEvent); logoffTimer.Interval = 150000; logoffTimer.Start(); } private void Form1_Close(object sender, FormClosedEventArgs e) { Application.Idle -= ExitTimerEvent; if (rdpClient.Connected == 1) { rdpClient.Disconnect(); } } public void LogoutTimerEvent(object source, EventArgs e) { logoffTimer.Stop(); rdpClient.Disconnect(); } enum WTS_CONNECTSTATE_CLASS { WTSActive, WTSConnected, WTSConnectQuery, WTSShadow, WTSDisconnected, WTSIdle, WTSListen, WTSReset, WTSDown, WTSInit }; [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Auto)] struct WTS_SESSION_INFO { public int SessionId; public string pWinStationName; public WTS_CONNECTSTATE_CLASS State; } [DllImport("wtsapi32.dll")] private static extern bool WTSLogoffSession(IntPtr hServer, int SessionId, bool bWait); private static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero; [DllImport("wtsapi32.dll", CharSet = CharSet.Auto)] private static extern bool WTSEnumerateSessions( IntPtr hServer, [MarshalAs(UnmanagedType.U4)] int Reserved, [MarshalAs(UnmanagedType.U4)] int Version, ref IntPtr ppSessionInfo, [MarshalAs(UnmanagedType.U4)] ref int pCount); [DllImport("wtsapi32.dll")] private static extern void WTSFreeMemory(IntPtr pMemory); private void LogoffDisconnectedSessions() { IntPtr buffer = IntPtr.Zero; int count = 0; if (WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref buffer, ref count)) { WTS_SESSION_INFO sessionInfo = new WTS_SESSION_INFO(); for (int index = 0; index < count; index++) { sessionInfo = (WTS_SESSION_INFO)Marshal.PtrToStructure( new IntPtr(buffer.ToInt32() + (Marshal.SizeOf(sessionInfo) * index)), typeof(WTS_SESSION_INFO)); WTS_CONNECTSTATE_CLASS state = sessionInfo.State; if (state == WTS_CONNECTSTATE_CLASS.WTSDisconnected) { WTSLogoffSession(WTS_CURRENT_SERVER_HANDLE, sessionInfo.SessionId, true); } } } WTSFreeMemory(buffer); } }

}