@Ergistael

Как передать информацию о событии с клиента по RDP (без особых прав)?

По факту некоего события (напр., получен емейл или отработала программа) в сессии RDP есть возможность сформировать штатными средствами короткий запрос (запустить bat-файл или ps-скрипт), некий результат работы которого нужно отследить на другом устройстве (т. е. узнать хоть бит о факте свершения события). Как передать информацию, если экран не активен? Звуковой карты нет. Писать на диск некуда (т. к. он удаленный). Возможно, писать в буфер обмена? Интернет есть. Отдельного своего сервера нет.

Как вариант (не обязательно основной), думаю о некоем онлайн-блокноте с API, где можно сформировать короткую заметку буквально из 1 слова, а на другом устройстве периодически проверять, что изменилось (появилась заметка). Красиво выглядит сайт anotepad.com, но не понятно, как работает (нет нормальной документации, примеры "левые"). Pastebin очень замороченный (извините, не осилил интерфейс доступа).
  • Вопрос задан
  • 101 просмотр
Пригласить эксперта
Ответы на вопрос 2
@NortheR73
системный инженер
в сессии RDP есть возможность сформировать штатными средствами короткий запрос (запустить bat-файл или ps-скрипт)
PowerShell умеет письма отправлять...
Ответ написан
@rPman
нагуглил, есть виртуальные каналы, которые можно поднимать между терминальной сессией и машиной клиента.
На основе этого кода claude ai (после некоторой беседы со мной, как же это шикарно что теперь так можно) вот тебе два приложения, не проверял:

Файл server.cpp (запускается на сервере терминальных служб):
#include <windows.h>
#include <wtsapi32.h>
#include <stdio.h>

#pragma comment(lib, "wtsapi32.lib")

DWORD OpenDynamicChannel(LPCSTR szChannelName, HANDLE *phFile);

int main(int argc, char* argv[])
{
    if (argc < 2) {
        printf("Usage: server.exe <message>\n");
        return 1;
    }

    HANDLE hFile;
    DWORD rc = OpenDynamicChannel("DVC_Sample", &hFile);
    if (ERROR_SUCCESS != rc) {
        printf("Failed to open dynamic channel. Error: %lu\n", rc);
        return 1;
    }

    printf("Waiting for client to connect...\n");

    // Wait for the client to connect and read something
    char buffer[1];
    DWORD bytesRead;
    ReadFile(hFile, buffer, 1, &bytesRead, NULL);

    // Send the message to the client
    const char* message = argv[1];
    DWORD bytesWritten;
    WriteFile(hFile, message, strlen(message), &bytesWritten, NULL);

    CloseHandle(hFile);
    return 0;
}

// Open a dynamic channel (same as in the original code)
DWORD OpenDynamicChannel(LPCSTR szChannelName, HANDLE *phFile)
{
    // ... (implementation same as in the original code)
}

Файл client.cpp (запускается на клиентской машине):
#include <windows.h>
#include <wtsapi32.h>
#include <stdio.h>

#pragma comment(lib, "wtsapi32.lib")

DWORD OpenDynamicChannel(LPCSTR szChannelName, HANDLE *phFile);

int main()
{
    HANDLE hFile;
    DWORD rc = OpenDynamicChannel("DVC_Sample", &hFile);
    if (ERROR_SUCCESS != rc) {
        printf("Failed to open dynamic channel. Error: %lu\n", rc);
        return 1;
    }

    printf("Connected to server. Waiting for message...\n");

    // Notify the server that we're ready
    const char ready = 'x';
    DWORD bytesWritten;
    WriteFile(hFile, &ready, 1, &bytesWritten, NULL);

    // Read the message from the server
    char buffer[1024];
    DWORD bytesRead;
    ReadFile(hFile, buffer, sizeof(buffer), &bytesRead, NULL);
    buffer[bytesRead] = '\0';

    MessageBoxA(NULL, buffer, "Message from Server", MB_OK);

    CloseHandle(hFile);
    return 0;
}

// Open a dynamic channel (same as in the original code)
DWORD OpenDynamicChannel(LPCSTR szChannelName, HANDLE *phFile)
{
    // ... (implementation same as in the original code)
}

Сценарий работы:
* Сначала запускается server.exe на сервере терминальных служб с аргументом - текстовым сообщением, которое нужно отправить клиенту.
* Серверное приложение ожидает, пока клиент не подключится и не отправит символ 'x', указывающий, что он готов принять сообщение.
* Затем серверное приложение отправляет указанное в командной строке сообщение клиенту и завершается.
* Клиентское приложение запускается на клиентской машине, подключается к тому же виртуальному каналу "DVC_Sample" и отправляет серверу символ 'x'.
* Клиентское приложение ожидает получения сообщения от сервера.
* После получения сообщения, клиентское приложение показывает его в MessageBox и завершается.

Обратите внимание, что в этом примере я использовал синхронные вызовы ReadFile/WriteFile для простоты. В реальных приложениях рекомендуется использовать асинхронные вызовы для избежания блокировок.

p.s. кранты нашей цивилизации, мы разучимся думать, ведь это так удобно, когда машина за тебя вот ТАКОЕ делает.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы