我怎么能创build窗口站和Windows桌面使用C#

我想创build新的窗口站和Windows桌面,并附加我的过程。 我怎样才能做到这一点

我需要知道

  1. 创build窗口站并附上我的桌面

  2. 有效地创build和切换桌面

  3. 如何将进程附加到winlogon桌面(如果可能的话)

  4. 销毁创build的桌面并返回到Windows桌面

Solutions Collecting From Web of "我怎么能创build窗口站和Windows桌面使用C#"

每个“会话”只有一个交互式窗口站,但是可以有多个会话。

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. 将这两个文件添加到项目引用。

使用系统;
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Windows.Forms;
使用AxMSTSCLib;
使用MSTSCLib;
使用System.Runtime.InteropServices; 

名称空间AutoLogin
{
公共部分类Form1:Form
{
私人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, WTSlistn, 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); } }

}

尽管Windows支持多个“窗口工作站”,但是文档指出:

交互式窗口站 Winsta0是唯一可以显示用户界面或接收用户输入的窗口站。 它被分配给交互式用户的登录会话,并包含键盘,鼠标和显示设备。 所有其他窗口站是非交互的,这意味着它们不能显示用户界面或接收用户输入。

这表明以您提议的方式在窗口站之间切换的功能是不可能的。