Cell Phone als USB device

  • VB.NET

Es gibt 22 Antworten in diesem Thema. Der letzte Beitrag () ist von Peter329.

    Ich freue mich, dass das klappt. Hat @-Franky- ja auch echt gut beschrieben. Ich habe es gestern mal probiert mit dem Directory.Exists und ich glaube es liegt an der CLSID. Er kann zwar damit umgehen aber in der Prüfung funktioniert es nicht.
    Sollte ich mich irren bitte ich um Verbesserung.

    Edit: Also ich habe es gerade nochmal getestet. Die komplette DirectoryInfo kann nicht mit CLSID umgehen. Man kann zwar über Netzwerkverbindungen und ähnliches prüfen aber im Prinzip brauch es immer einen festen Angelpunkt für Windows - sprich ein Laufwerksbuchstaben o.ä.. Und eine CLSID ist ja im Prinzip nur eine feste Verknüpfung in der Registry, mit der die Shell, sprich der Explorer, arbeiten kann aber sonst führt sie ins leere.

    Edit2: Ich habe es jetzt mal anders probiert - schau mal ob das funktioniert:

    VB.NET-Quellcode

    1. Dim DevPath = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer) &"\" & strDeviceID & "\Phone\DCIM"

    oder halt zur (in meinen Augen) Verbesserung der Lesbarkeit

    VB.NET-Quellcode

    1. Dim DevPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyComputer), strDeviceID, "Phone", "DCIM")


    Das Environment.SpecialFolder.MyComputer gibt dir eine Integer Zahl aus = 17. Das war auch das, was @VaporiZed gesagt hatte - ist ein festgelegter Wert in Windows.
    Das Environment.GetFolderPath macht dir daraus ein Verzeichnis - somit übergeht man den Laufwerksbuchstaben und findet trotzdem was man sucht.
    Du könntest es somit in der Kombination auch anstelle der CLSID nutzen.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „ThomasG82“ ()

    @Peter329

    Geduld hab ich eine Menge. Daran soll es nicht scheitern. :) Nur bin ich die nächsten 3 Wochen in Urlaub und kann da nicht weiterhelfen wenn weitere Fragen von Dir kommen. Da werden Dir sicher die anderen Mitstreiter hier helfen können.

    Vorweg: Vergiss alles was Du in .NET über ermitteln ob ein Ordner vorhanden ist, wie man Dateien kopiert/löscht usw weist/kennst. Zumindest wenn Du Dich in den Bereich WPD bewegst. Du wirst in diesem Bereich nur weiter kommen, wenn Du Dich darauf einlässt ausschließlich mit COM-Interfaces zu arbeiten. Du hast zwei Möglichkeiten: Entweder Du arbeitest ausschließlich mit den WPD-COM-Interfaces (recht aufwendig und für das was Du vorhast zu zu umständlich, es sei denn Du installierst Dir das NuGet-Paket das ich ja schon hier verlinkt hatte), oder mit den entsprechenden Shell-COM-Interfaces. Wenn ich immer lese, der Explorer kann das ja auch, dann denke ich immer, na dann verwende auch die entsprechenden COM-Interfaces, die der Explorer auch verwendet.

    Zu den Shell-COM-Interfaces: Auch hier hast zwei Möglichkeiten. Entweder Du verwendest die entsprechenden Verweise, oder Du programmierst direkt ohne Verweis (so wie mit dem IPortableDeviceManager). Das mal so als Vorwarnung worauf Du Dich einlassen müsstest um Dein Ziel zu erreichen. Jetzt aber zu Deinem Problem.

    Ob das WPD-Gerät angeschlossen ist, kannst Du ja per IPortableDeviceManager ermitteln. Auch die GeräteID. Das hast ja schon. Ob ein bestimmter Ordner, unter dem virtuellem Ordner "Dieser PC" auf einem WPD-Gerät vorhanden ist, prüfst Du am besten mit einer Shell-API.

    VB.NET-Quellcode

    1. Option Strict On
    2. Option Explicit On
    3. Imports System.Runtime.InteropServices
    4. Public Class Form1
    5. Private Const S_OK As Integer = 0
    6. <DllImport("Shell32.dll", EntryPoint:="SHParseDisplayName")>
    7. <PreserveSig> Private Shared Function SHParseDisplayName(<[In], MarshalAs(UnmanagedType.LPWStr)> ByVal pszName As String,
    8. <[In]> ByVal pbc As IntPtr,
    9. <Out> ByRef ppidl As IntPtr,
    10. <[In]> ByVal sfgaoIn As IntPtr,
    11. <Out> ByRef psfgaoOut As IntPtr) As Integer
    12. End Function
    13. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    14. Dim pPIDL As IntPtr = IntPtr.Zero
    15. If SHParseDisplayName("[Hier den Pfad zum Ordner DCIM]", IntPtr.Zero, pPIDL, IntPtr.Zero, IntPtr.Zero) = S_OK Then
    16. Debug.Print("OK")
    17. Marshal.Release(pPIDL)
    18. Else
    19. Debug.Print("NOK")
    20. End If
    21. End Sub
    22. End Class

    Ab hier kann ich Dir nur weitere Hinweise geben wie Du weiter verfahren kannst (bin ja dann im Urlaub). Vergiss den Shell.BrowseForFolder. Der ist altbacken und nicht mehr Zeitgemäß. Wenn schon dann den, den @VaporiZed verlinkt hatt. Nur ich würde nicht dieses WindowsAPICodePack-Paket verwenden. Viel zu groß um nur einen Dialog aufzurufen. Stattdessen kannst auch direkt das COM-Interface IFileDIalog/IFileDialog2 verwenden. Der Vorteil an diesem Dialog ist (neben anderen Sachen), Du kannst hier direkt über IFileDialog bzw IFileDialog2 und SetFolder bzw. SetNavigationRoot direkt die PIDL setzen, die Du von der Shell-API SHParseDisplayName zurück bekommst und bist direkt im Ordner DCIM bzw kannst den Ordner DCIM auswählen. Bei klick im Dialog auf OK, wird Dir ein IShellItem, oder bei Mehrfachauswahl ein IShellitemArray, zurück geliefert. Dieses kannst Du für das COM-Interface IFileOperation für das kopieren/löschen, verschieben usw. verwenden (IFileOperation.CopyItem, .CopyItems, .DeleteItem, .DeleteItems, .MoveItem, .MoveItems, .RenameItem, .RenameItems). Es geht aber auch ohne IFileDialog.

    Zum kopieren, verschieben, löschen usw von Dateien auf/von einem WPD-Gerät ohne Dialog: Hol Dir per Shell-API SHGetDesktopFolder ein COM-Interface IShellFolder. Per IShellFolder.ParseDisplayName und dem Pfad zu Deinem DCIM Ordner eine relative PIDL. Per IShellFolder.BindToObject mit der relativen PIDL und IID_IShellFolder2 ein COM-Interface IShellFolder2. Per IShellFolder2.EnumObjects ein COM-Interface IEnumIDList. Per Do/Loop IEnumIDList.Next jeweils eine relative PIDL auf die im Ordner DCIM enthaltenen Objekte. Per IShellFolder2.GetDetailsOf(PIDL, 0, SHELLDETAILS) -> SHELLDETAILS.STRRET.cbStr den FriendlyName des Objektes. Ob Du letzteres brauchst, musst selbst entscheiden wie Du dann weiter Verfahren möchtest. Da wäre zB. per API ILCombine aus den beiden relativen PIDLs eine absolute PIDL machen oder Du holst Dir per API SHParseDisplayName und dem kompletten Pfad zu DCIM & FriendlyName des Objektes eine absolute PIDL. Diese absolute PDIL schaufelst in ein Array. Aus dem Array holst Dir per API SHCreateShellItemArrayFromIDLists ein COM-Interface IShellItemArray. Dieses IShellItemArray kannst dann wieder für das COM-Interface IFileOperation verwenden um zb per CopyItems/PerformOperations die Objekte in DCIM zu kopieren oder per DeleteItems/PerformOperations zu löschen. Hierbei wird auch der Standard Windows Copy/Delete usw Dialog angezeigt.

    Klingt alles recht kompliziert, ich weis, ist es aber nicht wenn man weis welche COM-Interfaces benötigt werden. Vllt geht es über Verweise auf entsprechende COM-Interfaces einfacher. k.A. Ich arbeite ja nicht mit solchen Verweisen oder Fremdpaketen. What ever. Die Richtung hab ich Dir gezeigt und ich denke das auch andere hier anhand dieses Planes sagen können wie es mit entsprechenden Verweisen geht.

    Ich bin dann erstmal für 3 Wochen raus und genieße die Sonne. Werde zwar ab und zu mal in dieser Zeit reinschauen, aber nicht antworten. So, viel Text: Macht was draus. :)
    Mfg -Franky-

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

    @-Franky-

    wow ... das ist ja ein kollossaler Beitrag ! Schade, dass ich dir nur EIN "hilfreich" spendieren kann ... :)

    Gut, das habe ich jetzt final verstanden: der kryptische String ist ein "COM-Pfad". Und der hat mit einem Windows-Verzeichnis Pfad soviel zu tun, wie eine Kuh mit dem Schachspielen. Und deshalb klappt das mit dem Directory.Exists auch nicht. Jetzt ist Katze aus dem Sack.

    Um da voran zu kommen, braucht es also eine ganz andere Programmierung ... mit den üblichen .Net Methoden kommt man da definitiv nicht weiter. (Deshalb klappt übrigens auch der jüngste Vorschlag aus Post #21 nicht - Environment.GetFolderPath(Environment.SpecialFolder.MyComputer) liefert einen Null-String).

    Tja ... insofern ist das von @petaod ganz zu Anfang des Threads angeregte Vorgehen über die Shell BrowseForFolder, m.E. der Ansatz der ersten Wahl.

    Dank @VaporiZed verwende ich

    VB.NET-Quellcode

    1. Dim FromFolder = shell.BrowseForFolder(Hwnd, "Choose folder", 0, 17)


    um den Dialog bei "This PC" starten zu lassen ...

    Und Dank @ThomasG82 weiß ich jetzt, dass die 17 für

    VB.NET-Quellcode

    1. Environment.SpecialFolder.MyComputer


    steht.

    Danke, ihr Lieben ! Ich hab viel gelernt ... :)

    Ich habe damit eine sehr zufriedenstellende Lösung für mein Problem herstellen können ... Schon toll, wie aus der Vielzahl der Beiträge in einem Forum, dann letzten Endes eine sehr brauchbare Lösung entsteht.

    Tja ... aber ich lote eben immer gern die Grenzen aus. Und da hat mir @-Franky- noch einige sehr wichtige Anregungen geben, wie ich das Dingens möglicherweises noch verbessern könnte.

    Das werde ich mir alles in Ruhe anschauen. Und natürlich werde ich dann in jedem Fall abwägen, ob Aufwand und Nutzen in vernünftiger Relation stehen !

    Also, vielen Dank, ihr habt mir unendlich viel weiter geholfen ! Daumen hoch und Problem gelöst.

    Dann bleibt nur noch @-Franky- einen recht schönen und sonnigen Urlaub zu wünschen ! Viel Spaß und bleib gesund !

    Danke an alle Ratgeber !

    LG
    Peter