繁体   English   中英

可以使用 Windows 中的 CreateFile 以编程方式从 iPhone 读取图像吗?

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

当 iPhone 连接到 Win7 计算机时,可以使用资源管理器(以及我的应用程序的打开文件对话框)查看图像。 但是,文件位置不包含驱动器号。

例如Computer\\Apple iPhone\\Internal Storage\\DCIM\\800AAAAA\\IMG_0008.JPG而不是E:\\DCIM\\800AAAAA\\IMG_0008.JPG ,这是 sdcards、usb 驱动器等常见的...

我曾尝试使用 CreateFileW 从 iPhone 读取图像,但失败并显示“(错误代码:3)系统找不到指定的路径。” 我也试过用 Chrome 访问它们,但也失败了。

有什么建议?

该文件夹实际上就是所谓的“虚拟文件夹”,在文件系统上没有完整路径。 您将需要使用从打开对话框返回的 shell 项来获取文件的内容,而不是使用 CreateFile。

数据应该是可访问的,但您应该遵循MSDN 文档中的说明 我确信可能有更好的例子(因为这只是提供指导)。

编辑粗略的过程是从 IFileOpenDialog 获取 IShellItem,然后绑定到流,然后读取流(假设只读) - 请记住,此代码几乎没有错误处理或检查或安全性:

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();

大多数情况下,此类设备作为 Shell 命名空间扩展插入 Windows 资源管理器中,而不是像带有驱动器号的 U 盘。 大多数普通文件命令,如 CopyFile(..)、FindFirst() 或 GetFileInfo(..)不能直接在这样的 Shell 命名空间扩展中使用。 只有CopyHere(..)正在工作。 我需要很长时间才能弄清楚如何在数码相机上枚举文件,现在也在带有 vb.net 程序的 Android 设备上枚举文件,并将我的图片复制到我的 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

您可以添加以检查带有 y.Name.ToString="DCIM"(在 folderLevel=1 上)的文件夹和带有“.jpg”的文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM