PostThreadMessage здесь не идеален. Получение идентификатора потока действительно является проблемой, так как вашему сервису придется запускать более одного потока. Один для реализации сервиса, другой для прокачки цикла сообщений, который необходим для чтения сообщений. CreateToolHelp32Snapshot () может перечислять потоки, но вы все равно не будете знать, какой из этих двух потоков является перекачивающим.
Вместо этого используйте именованный канал. Вызовите CreateNamedPipe () в вашем сервисе, используйте режим сообщений и дайте каналу имя с префиксом «Global \», чтобы оно было видно в сеансе пользователя. Пользовательский код может подключаться к каналу, используя хорошо известное имя канала. Вы можете отправлять все, что хотите, по каналу, но вам придется избегать указателей, так как они не будут действительны в процессе обслуживания. Та же проблема, что и при маршалинге сообщений.
Другие возможности - это сокет, очень похожий на канал, но использующий общеизвестный номер порта вместо имени, и внепроцессный COM. Использование COM является преимуществом, если у вас есть сложные объекты, которые необходимо маршалировать через границу процесса. Избегайте этого, если у вас нет навыков COM.