Спасибо всем за ваши предложения. Ричард & переполнен, ссылка, которую вы предоставили в комментариях, была очень полезна. Кроме того, мне не нужно было позволять службе взаимодействовать с рабочим столом, чтобы вручную запустить насос сообщений с помощью Application.Run. По-видимому, вам нужно только разрешить службе взаимодействовать с рабочим столом, если вы хотите, чтобы Windows автоматически запускала насос сообщений для вас.
Для назидания каждого, вот что я в конечном итоге делает, чтобы вручную запустить насос сообщение для этого 3 партии API:
internal class MessageHandler : NativeWindow
{
public event EventHandler<MessageData> MessageReceived;
public MessageHandler()
{
CreateHandle(new CreateParams());
}
protected override void WndProc(ref Message msg)
{
// filter messages here for your purposes
EventHandler<MessageData> handler = MessageReceived;
if (handler != null) handler(ref msg);
base.WndProc(ref msg);
}
}
public class MessagePumpManager
{
private readonly Thread messagePump;
private AutoResetEvent messagePumpRunning = new AutoResetEvent(false);
public StartMessagePump()
{
// start message pump in its own thread
messagePump = new Thread(RunMessagePump) {Name = "ManualMessagePump"};
messagePump.Start();
messagePumpRunning.WaitOne();
}
// Message Pump Thread
private void RunMessagePump()
{
// Create control to handle windows messages
MessageHandler messageHandler = new MessageHandler();
// Initialize 3rd party dll
DLL.Init(messageHandler.Handle);
Console.WriteLine("Message Pump Thread Started");
messagePumpRunning.Set();
Application.Run();
}
}
мне пришлось преодолеть несколько препятствий, чтобы получить эту работу. Во-первых, вам нужно создать определенную форму для создания формы в том же потоке, который вы выполняете Application.Run. Вы также можете получить доступ только к свойству Handle из того же потока, поэтому мне было проще просто инициализировать DLL в этом потоке. Насколько я знаю, он все равно будет инициализирован из потока графического интерфейса.
Кроме того, в моей реализации класс MessagePumpManager является экземпляром Singleton, так что для всех экземпляров моего класса устройств запускается только один насос сообщений. Убедитесь, что вы действительно ленивы инициализируете свой экземпляр singleton, если вы начинаете поток в своем конструкторе. Если вы запускаете поток из статического контекста (например, private static MessagePumpManager instance = new MessagePumpManager();), среда выполнения никогда не переключит контекст во вновь созданный поток, и вы будете заторможены, ожидая запуска насоса сообщений.
Отметьте эту тему, это может оказаться полезным: http://connect.microsoft.com/VisualStudio/feedback/details/241133/detecting-a-wm-timechange-event-in-a-net-windows-service – overslacked
@overslacked, это действительно так. Он точно говорит, как это сделать. –
@overslacked Я знаю, что это старый вопрос, поэтому неудивительно, что ссылка MS Connect больше не работает. Но поскольку содержание этой ссылки, по-видимому, имеет решающее значение для обсуждения здесь, мне было интересно, есть ли новая связь. Извините, что вы вызываете хлопот! – Sabuncu