Can images be read from an iPhone programmatically using CreateFile in Windows?

前端 未结 2 940
北海茫月
北海茫月 2021-01-06 00:22

When an iPhone is connected to a Win7 computer, the images can be viewed using Explorer (and the open file dialog of my app). However, the file location does not contain a

相关标签:
2条回答
  • 2021-01-06 01:05

    The folder is actually what is referred to as a 'Virtual Folder' and does not have a full path on the file system. You will need to use the shell item returned from the open dialog to get the content of the file rather than using CreateFile.

    The data should be accessible, but you should follow the instructions from the MSDN documentation. I'm sure there are probably better examples (as this only gives guidelines).

    edit the rough process is to get the IShellItem from IFileOpenDialog, then to bind to the stream and then read the stream (assuming reading only) - bear in mind that this code is pretty much without error handling or checking or safety:

    if (pitem->GetDisplayName(SIGDN_NORMALDISPLAY, &destName) == S_OK) {
        std::cout << destName << std::endl;
        CoTaskMemFree(destName);
    }
    IStream *pistream;
    if (pitem->BindToHandler(0, BHID_Stream, IID_PPV_ARGS(&pistream)) == S_OK) {
        char input[1024];
        long to_read = 1024;
        unsigned long read;
        while (S_OK == pistream->Read(input, to_read, &read)) {
           std::cout << input << std::endl;
        }
        pistream->Release();
    }
    pitem->Release();
    
    0 讨论(0)
  • 2021-01-06 01:18

    Most often such a device is inserted in the Windows Explorer as a Shell Namespace Extension and not like an USB stick with drive letter. Most of the normal file commands like CopyFile(..), FindFirst() or GetFileInfo(..) can not be used directly in such a Shell Namespace extension. Only the CopyHere(..) is working. I needed long time to figure out how to enumerate the files on a digicam and now also on an Android device with an vb.net program and to copy my pictures to my Windows PC:

    Public Const MyComputer As Integer = &H11&
    
    Sub EnumMyComputer()
      Dim oItem As Object
      Dim res As Integer
    
      For Each oItem In DirectCast(CreateObject("Shell.Application").Namespace(MyComputer).Items, System.Collections.IEnumerable)
        Debug.Print(oItem.Type.ToString)
        if oItem.Type.ToString="Tragbares Medienwiedergabegerät" then '<- check, adopt!
          res = EnumNamespaceItems(oItem, "", oItem.Name.ToString, 0)
        End If
      Next oItem
    End Sub
    
    Function EnumNamespaceItems(oItem As Object, SrcCPath As String, SrcDPath As String, folderLevel As Integer) As Integer
      Dim y As Object
      Dim tempFullFileName As String
    
      Debug.Print(StrDup(folderLevel, "  ") & "\" & oItem.Name.ToString & "  (" & oItem.Path.ToString & ")")
      For Each y In DirectCast(oItem.GetFolder.items, System.Collections.IEnumerable)
        'Debug.Print(StrDup(folderLevel, "  ") & SrcDPath & y.Name.ToString)
        If y.IsFolder = True Then
          Dim n1 As Integer
          n1 = EnumNamespaceItems(y, SrcCPath & y.Path.ToString & "\", SrcDPath & y.Name.ToString & "\", 1 + folderLevel)
          If n1 < 0 Then 'failure: Cancel
            EnumNamespaceItems = n1
            Exit Function
          End If
        Else 'it's a file:
          Debug.Print(StrDup(folderLevel, "  ") & " " & y.Name.ToString)
          tempFullFileName = System.IO.Path.GetTempPath() & y.Name.ToString
          ' CopyFile is not possible here if SrcCPath is like "::{…}…":
          ' My.Computer.FileSystem.CopyFile(SrcCPath & y.Name.ToString , fFile.FullName)
          Dim suc As Integer = CopyHereFileWait(y, My.Computer.FileSystem.SpecialDirectories.Temp)
          If suc >= 0 Then 'now we can do things like this:
            Dim MyFileInfo As System.IO.FileInfo = My.Computer.FileSystem.GetFileInfo(tempFullFileName)
            Dim fileDate As Date = MyFileInfo.LastWriteTime
          End If 'suc
        End If 'else y.IsFolder
      Next y
      EnumNamespaceItems = 0
    End Function
    
    Function CopyHereFileWait(sourceNamespaceObject As Object, targetFolder As String) As Integer
      Dim fsMyStream As System.IO.FileStream
      Dim n1 As Integer
      Dim taregetFullFileName As String
    
      n1 = Len(targetFolder)
      If Mid(targetFolder, n1, 1) = "\" Then
        targetFolder = Microsoft.VisualBasic.Left(targetFolder, n1 - 1)
      End If
      taregetFullFileName = targetFolder & "\" & sourceNamespaceObject.Name.ToString
      Dim oNsTargetFolder As Object
      oNsTargetFolder = CreateObject("Shell.Application").Namespace(CStr(targetFolder))
      oNsTargetFolder.copyHere(sourceNamespaceObject)
      'returns immediately and is doing the work in the background
      n1 = 0
      Do
        Threading.Thread.Sleep(50) 'ms
        Try
          fsMyStream = System.IO.File.Open(taregetFullFileName, IO.FileMode.Open, IO.FileAccess.ReadWrite)
          fsMyStream.Close()
          CopyHereFileWait = n1
          Exit Function
        Catch ex As Exception
          Debug.Print(ex.Message)
        End Try
        n1 = n1 + 1
      Loop While n1 < 400 'timeout 400*50ms = 20s
      CopyHereFileWait = -n1
    End Function
    

    You may add to check for folders with y.Name.ToString="DCIM" (on folderLevel=1) and for files with ".jpg".

    0 讨论(0)
提交回复
热议问题