我想创建新的窗口站& Windows桌面并将我的进程附加到它。我怎么能这样做
我需要知道
创建Window工作站并连接我的桌面
创造&有效地在桌面之间切换
如何将进程附加到winlogon桌面(如果可能的话)
销毁创建的桌面并返回到Windows桌面
答案 0 :(得分:3)
每个'会话'只有一个交互式窗口站,但您可以有多个会话。
http://blogs.technet.com/markrussinovich/archive/2010/02/24/3315174.aspx
我不知道直接创建登录会话的API但是如果您使用的是Windows Server版本,则可以使用远程桌面创建本地会话,在那里自动运行程序,然后在程序结束后再次注销(您在远程桌面会话中运行的程序可以在完成时注销)。
下面的代码将使用MSTSC ActiveX控件以编程方式创建RDP会话。您需要手动生成ActiveX存根并将其添加到项目中。
从Visual Studio命令提示符键入以下内容:
aximp.exe %windir%\system32\mstscax.dll
将生成的文件(MSTSCLib.dll和AxMSTSCLib.dll)复制到项目目录。
将两个文件添加到项目引用中。
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); } }
}
答案 1 :(得分:0)
虽然Windows支持多个“窗口站”,但documentation表示:
交互式窗口站,Winsta0,是唯一可以显示用户界面或接收用户输入的窗口站。它被分配给交互式用户的登录会话,并包含键盘,鼠标和显示设备。所有其他窗口站都是非交互式的,这意味着它们无法显示用户界面或接收用户输入。
这表示无法以您提议的方式在窗口站之间切换。