2009-08-28 90 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); } }

}