Veröffentlicht 13. Mai 201411 j Tag, folgendes szenario: windows service im system context, desktop interaction ist allowed. ich habe ein USB device, dass beim ein und abstecken bestimmte schritte am system erfordert. Das Event kann man abonieren, z.B. über c# - Check for device change (add/remove) events - Stack Overflow ich hab versucht, die device detection über wmi zu machen ... der sendet aber multiple events. pro device knoten ein event, was zu witzigen phänomenen führt, wenn man in virtuellen Umgebungen ist, ist also keine Alternative. Statt einem Window Handle kann ich auch ein Service Handle angeben, siehe auch RegisterDeviceNotification function (Windows). Die Frage ist, wie komme ich an den Callback im Handler? HandlerEx callback function (Windows)
13. Mai 201411 j Nicht schön, aber der Callback kommt immerhin. Das sollte eine Starthilfe sein. using System; using System.Runtime.InteropServices; namespace ServiceTest { [StructLayout(LayoutKind.Sequential)] struct DevBroadcastDeviceinterface { internal int Size; internal int DeviceType; internal int Reserved; internal Guid ClassGuid; internal short Name; } public class MyService : System.ServiceProcess.ServiceBase { private const int DbtDevtypDeviceinterface = 5; private static readonly Guid GuidDevinterfaceUSBDevice = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); // USB devices private const int SERVICE_CONTROL_STOP = 0x00000001; private const int SERVICE_CONTROL_DEVICEEVENT = 0x0000000B; private delegate int Callback(int control, int eventType, IntPtr eventData, IntPtr context); [DllImport("kernel32.dll", SetLastError = true)] static extern unsafe int GetLastError(); [DllImport("advapi32.dll", SetLastError = true)] static extern unsafe IntPtr RegisterServiceCtrlHandlerEx(string lpServiceName, Callback cbex, IntPtr context); [DllImport("user32.dll", SetLastError = true)] static extern IntPtr RegisterDeviceNotification(IntPtr hRecipient, IntPtr NotificationFilter, uint Flags); [DllImport("user32.dll", SetLastError = true)] static extern bool UnregisterDeviceNotification(IntPtr Handle); private IntPtr _statusHandle = IntPtr.Zero; private IntPtr _notificatioNHandle = IntPtr.Zero; private static MyService _instance = null; public static int callbackexfunc(int control, int eventType, IntPtr eventData, IntPtr context) { switch (control) { case SERVICE_CONTROL_STOP: _instance.Stop(); break; case SERVICE_CONTROL_DEVICEEVENT: // Jetzt du break; } return 0; } public MyService() { ServiceName = "MyService"; _instance = this; } protected override void OnStart(string[] args) { Callback myCallback = new Callback(MyService.callbackexfunc); _statusHandle = RegisterServiceCtrlHandlerEx(this.ServiceName, myCallback, IntPtr.Zero); DevBroadcastDeviceinterface dbi = new DevBroadcastDeviceinterface { DeviceType = DbtDevtypDeviceinterface, Reserved = 0, ClassGuid = GuidDevinterfaceUSBDevice, Name = 0 }; dbi.Size = Marshal.SizeOf(dbi); IntPtr buffer = Marshal.AllocHGlobal(dbi.Size); Marshal.StructureToPtr(dbi, buffer, true); _notificatioNHandle = RegisterDeviceNotification(_statusHandle, buffer, 1); } protected override void OnStop() { UnregisterDeviceNotification(_notificatioNHandle); _notificatioNHandle = IntPtr.Zero; } } } [/code]
13. Mai 201411 j Man kann die Referenz auf die Dienst-Instanz bestimmt auch irgendwie in den context-Parameter des Callback fummeln. Der statische Member ist die faule Lösung
13. Mai 201411 j Autor okay hab ich verstanden, schlag mich jetzt grade noch damit rum, dass der callback nicht getroffen wird. Mal weiter debuggen
13. Mai 201411 j Autor 3 Stunden debugging später ... läuft War ein guter Ansatz, hab jetzt verstanden was ich falsch gemacht habe. Erledigt
Erstelle ein Konto oder melde dich an, um einen Kommentar zu schreiben.