Файл 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 для простоты. В реальных приложениях рекомендуется использовать асинхронные вызовы для избежания блокировок.