Создайте Windows Session программно из консоли или службы Windows - PullRequest
0 голосов
/ 14 октября 2018

Как я могу программно войти в Windows, чтобы создать сеанс входа в Windows?Мне нужен способ, который работает из приложения WinForms, из приложения Console и (что наиболее важно) из службы Windows.

Еще одно требование заключается в том, что он необходим для работы в локальной системе, в которой работает программа./ служба включена, а также для удаленных систем.

Если есть способ сделать это с помощью API pInvoke / Win32, я тоже открыт для этого.

Я нашел подобные вопросы / ответы вмое исследование:

Программно создать и запустить сеанс RDP (без графического интерфейса пользователя)

Ответ здесь говорит, что это возможно, но дает ссылку, но пример кода из ссылкине работает

Создание сеанса Windows из службы через Win32 API

Нет решения поставленного вопроса

Создание Windowsсеанс программно

Нет решения, но ФП упомянул в комментарии, что http://freerdp.com работает для него.

1 Ответ

0 голосов
/ 14 октября 2018

Я создал простую утилиту, которая, по моему мнению, отвечает всем требованиям, указанным в вопросе.Вам нужно будет добавить ссылку COM в библиотеку типов активного клиента Microsoft Terminal Services 1.0 (ActiveX).

Я подумал, что это может не сработать для создания сеанса на локальном компьютере, но я тестировал в 2012R2 под управлениемСервис, и это на самом деле может.Тот же точный метод может быть вызван из приложения WinForms или из консольного приложения.При запуске из приложения WinForms или Console форма отображается в течение нескольких секунд, поэтому я убедился, что для элемента управления установлено значение enable = false, чтобы с ним нельзя было взаимодействовать.

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using AxMSTSCLib;

namespace Utility.RemoteDesktop
{
    public class Client
    {
        private int LogonErrorCode { get; set; }

        public void CreateRdpConnection(string server, string user, string domain, string password)
        {
            void ProcessTaskThread()
            {
                var form = new Form();
                form.Load += (sender, args) =>
                {
                    var rdpConnection = new AxMSTSCLib.AxMsRdpClient9NotSafeForScripting();
                    form.Controls.Add(rdpConnection);
                    rdpConnection.Server = server;
                    rdpConnection.Domain = domain;
                    rdpConnection.UserName = user;
                    rdpConnection.AdvancedSettings9.ClearTextPassword = password;
                    rdpConnection.AdvancedSettings9.EnableCredSspSupport = true;
                    if (true)
                    {
                        rdpConnection.OnDisconnected += RdpConnectionOnOnDisconnected;
                        rdpConnection.OnLoginComplete += RdpConnectionOnOnLoginComplete;
                        rdpConnection.OnLogonError += RdpConnectionOnOnLogonError;
                    }
                    rdpConnection.Connect();
                    rdpConnection.Enabled = false;
                    rdpConnection.Dock = DockStyle.Fill;
                    Application.Run(form);
                };
                form.Show();
            }

            var rdpClientThread = new Thread(ProcessTaskThread) { IsBackground = true };
            rdpClientThread.SetApartmentState(ApartmentState.STA);
            rdpClientThread.Start();
            while (rdpClientThread.IsAlive)
            {
                Task.Delay(500).GetAwaiter().GetResult();
            }
        }

        private void RdpConnectionOnOnLogonError(object sender, IMsTscAxEvents_OnLogonErrorEvent e)
        {
            LogonErrorCode = e.lError;
        }
        private void RdpConnectionOnOnLoginComplete(object sender, EventArgs e)
        {
            if (LogonErrorCode == -2)
            {
                Debug.WriteLine($"    ## New Session Detected ##");
                Task.Delay(10000).GetAwaiter().GetResult();
            }
            var rdpSession = (AxMsRdpClient9NotSafeForScripting)sender;
            rdpSession.Disconnect();
        }
        private void RdpConnectionOnOnDisconnected(object sender, IMsTscAxEvents_OnDisconnectedEvent e)
        {
            Environment.Exit(0);
        }
    }
}

НаПримечание: я нашел этот вопрос, который говорит, что может быть способ использовать элемент управления ActiveX (для RDP) без использования формы Windows вообще.Я видел пример, который они привели, и я не был уверен, использовать их код для этой ситуации.

Элемент управления ActiveX без формы

Если есть кто-нибудь, кто понимает, какЧтобы сделать это без размещения элемента управления ActiveX в форме, пожалуйста, опубликуйте пример.

...