SilentDemise Geschrieben 13. Mai 2014 Geschrieben 13. Mai 2014 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) Zitieren
Klotzkopp Geschrieben 13. Mai 2014 Geschrieben 13. Mai 2014 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] Zitieren
Klotzkopp Geschrieben 13. Mai 2014 Geschrieben 13. Mai 2014 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 Zitieren
SilentDemise Geschrieben 13. Mai 2014 Autor Geschrieben 13. Mai 2014 okay hab ich verstanden, schlag mich jetzt grade noch damit rum, dass der callback nicht getroffen wird. Mal weiter debuggen Zitieren
SilentDemise Geschrieben 13. Mai 2014 Autor Geschrieben 13. Mai 2014 3 Stunden debugging später ... läuft War ein guter Ansatz, hab jetzt verstanden was ich falsch gemacht habe. Erledigt Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.