我如何使用 C# 创建窗口站和 Windows 桌面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1344916/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how can i creating window station and windows desktop using c#
提问by Suriyan Suresh
i would like create new window station & windows desktop and attach my process to it. how can i do that
我想创建新的窗口站和 Windows 桌面并将我的进程附加到它。我怎样才能做到这一点
i need to know
我需要知道
Creating Window station and attach my desktop
Creating & switching between Desktop effectively
how do i attaching process to winlogon desktop(if it is possible )
Destroy created desktop and return back to windows desktop
创建窗口站并附加我的桌面
有效地在桌面之间创建和切换
我如何将进程附加到 winlogon 桌面(如果可能)
销毁创建的桌面并返回到 Windows 桌面
回答by watsonmw
There is only one interactive window station per 'session' but you can have multiple sessions.
每个“会话”只有一个交互式窗口站,但您可以有多个会话。
http://blogs.technet.com/markrussinovich/archive/2010/02/24/3315174.aspx
http://blogs.technet.com/markrussinovich/archive/2010/02/24/3315174.aspx
I'm not aware of an API to directly create a login session but if you are using a Windows Server version you could use Remote Desktop to create a local session, autorun your program there, then logout again once the program has ended (the program you are running in the Remote Desktop Session could logout when finished).
我不知道直接创建登录会话的 API,但如果您使用的是 Windows Server 版本,您可以使用远程桌面创建本地会话,在那里自动运行您的程序,然后在程序结束后再次注销(程序您正在远程桌面会话中运行,完成后可能会注销)。
The code below will use the MSTSC ActiveX control to programmatically create an RDP session. You will need to manually generate the ActiveX stubs and add them to your project.
下面的代码将使用 MSTSC ActiveX 控件以编程方式创建 RDP 会话。您需要手动生成 ActiveX 存根并将它们添加到您的项目中。
From the Visual Studio Command Prompt type the following:
aximp.exe %windir%\system32\mstscax.dll
Copy the generated files (MSTSCLib.dll and AxMSTSCLib.dll) to the project directory.
Add both files to the project references.
从 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); } }
}
}
回答by Greg Hewgill
Although Windows supports multiple "window stations", the documentationstates that:
尽管 Windows 支持多个“窗口站”,但文档指出:
The interactive window station, Winsta0, is the only window station that can display a user interface or receive user input. It is assigned to the logon session of the interactive user, and contains the keyboard, mouse, and display device. All other window stations are noninteractive, which means they cannot display a user interface or receive user input.
的交互式窗口站,Winsta0,是唯一的窗口站,可以显示的用户接口或接收用户输入。它被分配给交互式用户的登录会话,并包含键盘、鼠标和显示设备。所有其他窗口站都是非交互式的,这意味着它们无法显示用户界面或接收用户输入。
This indicates that the ability to switch between window stations in the way you are proposing is not possible.
这表明无法按照您提议的方式在窗口站之间切换。