Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen.
Einstecken von SD Karte erkennen Nicht USB Stick
- VB.NET
- .NET (FX) 4.0
Sie verwenden einen veralteten Browser (%browser%) mit Sicherheitsschwachstellen und können nicht alle Funktionen dieser Webseite nutzen.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Hier erfahren Sie, wie einfach Sie Ihren Browser aktualisieren können.
Es gibt 65 Antworten in diesem Thema. Der letzte Beitrag () ist von Amelie.
-
-
@Amelie In Post #6 und Post #9 sind ein paar lokale Konstanten drinne, in Post #12 hast Du festgestellt, dass auf einige nicht verwiesen wird.
@-Franky- meint, dass Du die von ihm aufgelisteten mal da abfragen solltest.
Die Wedrte stehen hier: pinvoke.net/default.aspx/Enums/SHCNE.html
@-Franky- Beim nächsten mal schreibst Du die Werte gleich hin.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
Hi
Ich hab mal meinen VB6 Code auf .NET umgeschrieben. Unwichtiges habe ich dabei mal rausgelassen und es werden nur die Events SHCNE_MEDIAINSERTED und SHCNE_MEDIAREMOVED abgefragt bzw ausgewertet. Der Code erkennt auch das einlegen einer CD in das CD-Rom Laufwerk. Deswegen müsstest Du das ermittelte Laufwerk noch auswerten ob es ein Removable-Laufwerk und kein CD-Rom Laufwerk ist. Ausgaben erfolgen im Debug-Fenster!
Spoiler anzeigen
VB.NET-Quellcode
-
- Option Strict On
- Option Explicit On
- Imports System.Runtime.InteropServices
- Public Class Form1
- Private Const S_OK As Integer = &H0
- Private Const WM_DESTROY As Integer = &H2
- Private Const WM_SHNOTIFY As Integer = &H488
- Private Const CSIDL_DESKTOP As Integer = &H0
- Private Const GPFIDL_DEFAULT As Integer = &H0
- Private Const SHCNE_MEDIAREMOVED As Integer = &H40
- Private Const SHCNE_MEDIAINSERTED As Integer = &H20
- Private Enum SHCNRF As Integer
- SHCNRF_InterruptLevel = &H1
- SHCNRF_ShellLevel = &H2
- SHCNRF_RecursiveInterrupt = &H1000
- SHCNRF_NewDelivery = &H8000
- End Enum
- <StructLayout(LayoutKind.Sequential)>
- Private Structure SHChangeNotifyEntry
- Dim pidl As IntPtr
- <MarshalAs(UnmanagedType.Bool)> Dim fRecursive As Boolean
- End Structure
- <StructLayout(LayoutKind.Sequential)>
- Private Structure SHNOTIFYSTRUCT
- Dim dwItem1 As IntPtr
- Dim dwItem2 As IntPtr
- End Structure
- <DllImport("ole32.dll", EntryPoint:="CoTaskMemFree")>
- Private Shared Sub CoTaskMemFree(
- <[In]> ByVal hMem As IntPtr)
- End Sub
- <DllImport("shell32.dll", EntryPoint:="SHChangeNotifyRegister")>
- Private Shared Function SHChangeNotifyRegister(
- <[In]> ByVal hWnd As IntPtr,
- <[In]> ByVal fSources As SHCNRF,
- <[In]> ByVal fEvents As Integer,
- <[In]> ByVal wMsg As Integer,
- <[In]> ByVal cEntries As Integer,
- <[In]> ByVal lpps As SHChangeNotifyEntry) As Integer
- End Function
- <DllImport("shell32.dll", EntryPoint:="SHChangeNotifyDeregister")>
- Private Shared Function SHChangeNotifyDeregister(
- <[In]> ByVal hNotify As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
- End Function
- <DllImport("shell32.dll", EntryPoint:="SHGetFolderLocation")>
- Private Shared Function SHGetFolderLocation(
- <[In]> ByVal hwndOwner As IntPtr,
- <[In]> ByVal nFolder As Integer,
- <[In]> ByVal hToken As IntPtr,
- <[In]> ByVal dwReserved As Integer,
- <Out> ByRef pidl As IntPtr) As Integer
- End Function
- <DllImport("shell32.dll", EntryPoint:="SHChangeNotification_Lock")>
- Private Shared Function SHChangeNotification_Lock(
- <[In]> ByVal hChange As IntPtr,
- <[In]> ByVal dwProcId As Integer,
- <Out> ByRef ppidl As IntPtr,
- <Out> ByRef plEvent As Integer) As IntPtr
- End Function
- <DllImport("shell32.dll", EntryPoint:="SHChangeNotification_Unlock")>
- Private Shared Function SHChangeNotification_Unlock(
- <[In]> ByVal hLock As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
- End Function
- <DllImport("shell32.dll", EntryPoint:="SHGetPathFromIDListEx")>
- Private Shared Function SHGetPathFromIDListEx(
- <[In]> ByVal pidl As IntPtr,
- <[In]> <MarshalAs(UnmanagedType.LPWStr)> ByVal pszPath As String,
- <[In]> ByVal cchPath As Integer,
- <[In]> ByVal uOpts As Integer) As <MarshalAs(UnmanagedType.Bool)> Boolean
- End Function
- Private m_hSHNotify As Integer = 0
- Private m_hNotifyLock As IntPtr = IntPtr.Zero
- Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
- m_hSHNotify = RegisterNotify()
- End Sub
- Protected Overrides Sub WndProc(ByRef m As Message)
- Select Case m.Msg
- Case WM_SHNOTIFY
- ProcessShellNotify(m)
- Case WM_DESTROY
- UnregisterNotify()
- End Select
- MyBase.WndProc(m)
- End Sub
- Private Function RegisterNotify() As Integer
- Dim hSHNotify As Integer = 0
- Dim pPIDL As IntPtr = IntPtr.Zero
- Dim tSHCNE As SHChangeNotifyEntry = New SHChangeNotifyEntry
- If SHGetFolderLocation(IntPtr.Zero, CSIDL_DESKTOP,
- IntPtr.Zero, 0, pPIDL) = S_OK Then
- With tSHCNE
- .pidl = pPIDL
- .fRecursive = True
- End With
- CoTaskMemFree(pPIDL)
- hSHNotify = SHChangeNotifyRegister(Me.Handle,
- SHCNRF.SHCNRF_ShellLevel Or
- SHCNRF.SHCNRF_InterruptLevel Or
- SHCNRF.SHCNRF_RecursiveInterrupt Or
- SHCNRF.SHCNRF_NewDelivery,
- SHCNE_MEDIAINSERTED Or
- SHCNE_MEDIAREMOVED,
- WM_SHNOTIFY, 1, tSHCNE)
- End If
- Return hSHNotify
- End Function
- Private Sub UnregisterNotify()
- If m_hSHNotify <> 0 Then
- If SHChangeNotifyDeregister(m_hSHNotify) = True Then
- m_hSHNotify = 0
- End If
- End If
- End Sub
- Private Shared Sub ShellNotifyEvent(ByVal intEvent As Integer,
- ByVal tSHNS As SHNOTIFYSTRUCT)
- Dim strNullChar As Char = Convert.ToChar(0)
- Dim strPath1 As String = New String(strNullChar, 255)
- Dim strPath2 As String = New String(strNullChar, 255)
- If tSHNS.dwItem1 <> IntPtr.Zero Then
- If SHGetPathFromIDListEx(tSHNS.dwItem1, strPath1,
- strPath1.Length, GPFIDL_DEFAULT) = True Then
- strPath1 = strPath1.Substring(0, strPath1.IndexOf(strNullChar))
- Debug.Print(strPath1 & " " & LookUpSHCNE(intEvent))
- End If
- End If
- If tSHNS.dwItem2 <> IntPtr.Zero Then
- If SHGetPathFromIDListEx(tSHNS.dwItem2, strPath2,
- strPath2.Length, GPFIDL_DEFAULT) = True Then
- strPath2 = strPath2.Substring(0, strPath2.IndexOf(strNullChar))
- Debug.Print(strPath2 & " " & LookUpSHCNE(intEvent))
- End If
- End If
- End Sub
- Private Sub ProcessShellNotify(ByVal m As Message)
- Dim intEvent As Integer = 0
- Dim pPIDL As IntPtr = IntPtr.Zero
- If m_hNotifyLock = IntPtr.Zero Then
- m_hNotifyLock = SHChangeNotification_Lock(m.WParam, m.LParam.ToInt32,
- pPIDL, intEvent)
- If m_hNotifyLock <> IntPtr.Zero Then
- Dim tSHNS As SHNOTIFYSTRUCT = CType(Marshal.PtrToStructure(pPIDL,
- GetType(SHNOTIFYSTRUCT)), SHNOTIFYSTRUCT)
- If SHChangeNotification_Unlock(m_hNotifyLock) = True Then
- m_hNotifyLock = IntPtr.Zero
- End If
- ShellNotifyEvent(intEvent, tSHNS)
- End If
- End If
- End Sub
- Private Shared Function LookUpSHCNE(ByVal intEvent As Integer) As String
- Dim strRet As String = String.Empty
- Select Case intEvent
- Case SHCNE_MEDIAINSERTED
- strRet = "MEDIA INSERTED"
- Case SHCNE_MEDIAREMOVED
- strRet = "MEDIA REMOVED"
- End Select
- Return strRet
- End Function
- End Class
Mfg -Franky- -
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
Win10-64, Studio 2017, AnyCPU.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
Hi
So. Test auf meinem Laptop war auch erfolgreich. Hab aber eine kleine Änderung am Code vorgenommen. Könnte sein das das ganze deswegen zum Fehler führte. Hier die geänderte Funktion RegisterNotify.
VB.NET-Quellcode
-
- Private Function RegisterNotify() As Integer
- Dim hSHNotify As Integer = 0
- Dim pPIDL As IntPtr = IntPtr.Zero
- Dim tSHCNE As SHChangeNotifyEntry = New SHChangeNotifyEntry
- If SHGetFolderLocation(IntPtr.Zero, CSIDL_DESKTOP,
- IntPtr.Zero, 0, pPIDL) = S_OK Then
- With tSHCNE
- .pidl = pPIDL
- .fRecursive = True
- End With
- hSHNotify = SHChangeNotifyRegister(Me.Handle,
- SHCNRF.SHCNRF_ShellLevel Or
- SHCNRF.SHCNRF_InterruptLevel Or
- SHCNRF.SHCNRF_RecursiveInterrupt Or
- SHCNRF.SHCNRF_NewDelivery,
- SHCNE_MEDIAINSERTED Or
- SHCNE_MEDIAREMOVED,
- WM_SHNOTIFY, 1, tSHCNE)
- Marshal.FreeCoTaskMem(pPIDL) ' <- erst nach SHChangeNotifyRegister freigeben
- 'CoTaskMemFree(pPIDL) ' <- API CoTaskMemFree durch Marshal.FreeCoTaskMem ersetzt.
- End If
- Return hSHNotify
- End Function
Mfg -Franky- -
@-Franky-
SHChangeNotifyRegister()
knallt, das ist vor Deiner Änderung.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
@-Franky-
Auch ich hab den Code ausprobiert, und es knallt auch bei mir. Aber trotzdem Danke.
Ich hätte aber noch ne Frage. Ist es möglich das die ADMIN-Rechte gefordert sind? -
Ich glaube der letzte Parameter von
SHChangeNotifyRegister()
muss alsByRef
übergeben werden,
Edit: Und laut codeproject.com/Articles/3054/Shell-Notifications-in-C muss man beimDllImport
-Attribut noch den EntryPoint manuell setzen, das könnte man evtl. auch noch probieren. -
Hi
@RodFromGermany Ich verstehe Deine Aussage jetzt so, das nach der Änderung im Code, das bei Dir nun läuft? Warum das vor der Änderung bei mir ebenfalls lief kann ich Dir nicht sagen.Mfg -Franky- -
-Franky- schrieb:
Ich verstehe Deine Aussage jetzt so,
Du hast Code geändert, der im Code nach der Exception steht, also noch gar nicht ablief.
@nafets Jou, hier stehts auch:
docs.microsoft.com/en-us/windo…re-shchangenotifyregister
====
@-Franky- Also:
Stecken SD-Adapter: Keine Reaktion.
Stecken SD-Karte in Adapter: Wird angezeigt.
Abmelden SD-Karte: Keine Reaktion.
Abziehen SD-Karte: Keine Reaktion.
Stecken USB-Stick: Keine Reaktion.
Abmelden USB-Stick: Keine Reaktion.
Abziehen USB-Stick: Keine Reaktion.
Fazit:
Da wäre noch was zu tun.
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert!Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „RodFromGermany“ ()
-
Hi
@nafets Letzter Parameter ByRef kann sein. Wenn man es aber genau nimmt, müsste im letzten Parameter ein Array von SHChangeNotifyEntry übergeben werden. Da hier aber nicht mehrere Sachen überwacht werden (Laufwerksüberwachung und Überwachung eines Ordner zB. gleichzeitig), geht es auch so. In VB6 hab ich das ByVal und Übergebe einen Pointer auf das erste Element vom SHChangeNotifyEntry-Array. Das mit dem EntryPoint #2 war zu Zeiten als die API SHChangeNotifyRegister noch nicht offiziell von MS dokumentiert war bzw. es den Einsprungspunkt mit Namen "SHChangeNotifyRegister" in der Shell32.dll noch nicht gab. Man konnte diese Funktion aber schon über deren Ordinalzahl #2 aufrufen.
@RodFromGermany Stecken SD-Adapter/Abmelden SD-Karte (CardReader auswerfen!)/Stecken USB-Stick usw: Keine Reaktion. Jupp weil nur SHCNE_MEDIAREMOVED und SHCNE_MEDIAINSERTED überwacht werden und nicht ob ein Laufwerk entfernt oder hinzugefügt wurde. Du kannst ja, falls Du das auch haben möchtest, noch SHCNE_DRIVEADD und SHCNE_DRIVEREMOVED hinzufügen. Ich hab das weggelassen weil im Ausgangspost vom "Einstecken von SD Karte erkennen" die Rede war. Stecken SD-Karte in Adapter: Wird angezeigt. Na dann läuft doch mein Code. Dann sollte auch das rausziehen der SD-Karte aus dem CardReader angezeigt werden solange der CardReader selbst noch nicht ausgeworfen wurde.Mfg -Franky- -
-Franky- schrieb:
Wenn man es aber genau nimmt, müsste im letzten Parameter ein Array von SHChangeNotifyEntry übergeben werden
Ja, da hast du Recht. Effektiv macht es aber, wenn man nur ein Element übergibt, keinen Unterschied, ob man die Elementanzahl auf 1 setzt und den einen Eintrag per ByRef übergibt oder man alternativ die Elementzahl und ein Array (das dann ByVal) übergibt - am Ende wird bei beidem ein Pointer auf das erste Element übergeben. -
-Franky- schrieb:
weil nur SHCNE_MEDIAREMOVED und SHCNE_MEDIAINSERTED überwacht werden
Manchmal lasse ich andere für mich denken.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
-
@Amelie Poste mal die Deklaration der Proedur.Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert! -
@RodFromGermany
Hatte den Code aus Nr 23 und die Änderungen Nr 27 genommen. Habe aber das ganze Projekt gelöscht weil es wohl irgendwie nicht geht.Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. -
-
@Amelie Nicht schreiben, dass Du Änderungen gemacht hast, sondern welche.
Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch
Ein guter .NET-Snippetkonverter (der ist verfügbar).
Programmierfragen über PN / Konversation werden ignoriert!
-
Ähnliche Themen
-
Loquax - - Sonstige Problemstellungen
-
10 Benutzer haben hier geschrieben
- Amelie (24)
- RodFromGermany (23)
- -Franky- (8)
- nafets (3)
- exc-jdbi (3)
- petaod (1)
- FormFollowsFunction (1)
- EaranMaleasi (1)
- Dksksm (1)
- Bartosz (1)