5

iPhone が Win7 コンピューターに接続されている場合は、エクスプローラー (およびアプリの [ファイルを開く] ダイアログ) を使用して画像を表示できます。ただし、ファイルの場所にはドライブ文字が含まれていません。

たとえば、sdcards、usb ドライブなどの一般的なものではComputer\Apple iPhone\Internal Storage\DCIM\800AAAAA\IMG_0008.JPGなく...E:\DCIM\800AAAAA\IMG_0008.JPG

CreateFileW を使用して iPhone から画像を読み込もうとしましたが、「(エラー コード: 3) 指定されたパスが見つかりません」というエラーが表示されて失敗します。また、Chromeでアクセスしようとしましたが、失敗します。

助言がありますか?

4

2 に答える 2

3

このフォルダは、実際には「仮想フォルダ」と呼ばれるものであり、ファイル システムに完全なパスはありません。ファイルの内容を取得するには、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();
于 2012-06-13T15:47:17.643 に答える
2

ほとんどの場合、このようなデバイスは Windows エクスプローラーにシェル名前空間拡張として挿入され、ドライブ文字付きの USB スティックとは異なります。CopyFile(..)、FindFirst()、GetFileInfo(..) などの通常のファイル コマンドのほとんどは、このようなシェル名前空間拡張では直接使用できません。のみ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" のファイルをチェックするために追加できます。

于 2015-07-28T22:34:18.043 に答える