使用Delphi查找特殊驱动器

我试图在Delphi 2007中编写一个小程序,以便在插入Windows 7机器时从便携式USB驱动器访问文件。 虽然这个驱动器不会显示为一个标准的驱动器号。 它出现在Windows资源pipe理器的便携式设备下。 我写了下面的代码枚举“计算机”下的所有项目:

Procedure TfrmMain.ComputerChanged(Var Msg: TMessage); Var Enum: IEnumIDList; Fetched: Longword; Item: PItemIDList; Path: String; Computer: IShellFolder; StrRet: TSTRRET; Begin Status('Computer changed... Checking folders.'); fDesktop.BindToObject(fCompPidl, Nil, IID_IShellFolder, Computer); If Assigned(Computer) And (Computer.EnumObjects(Self.Handle, SHCONTF_FOLDERS, Enum) = NOERROR) Then Begin While (Enum.Next(1, Item, Fetched) = NOERROR) Do Begin FillChar(StrRet, SizeOf(StrRet), #0); Computer.GetDisplayNameOf(Item, SHGDN_FORADDRESSBAR or SHGDN_NORMAL, StrRet); Path := StrRetToStr(StrRet, Item); Status(Path); End; End; End; 

(注意:“状态”过程只是将消息输出到TMemo。)

每当通过Windowsshell程序子系统通知我的应用程序发生更改时,都会调用此方法。 它枚举所有的本地驱动器和networking驱动器,但没有别的(iCloud照片驱动器也是如此)。

有谁知道我可以如何访问这些虚拟驱动器上的文件?

Solutions Collecting From Web of "使用Delphi查找特殊驱动器"

你很可能不正确初始化COM。 如果您不调用CoInitializeEx,或者调用的值不正确,但是便携式设备驱动程序需要使用公寓线程工作,则您的代码将按原样工作。

根据您的代码,这里是一个示例应用程序,正常工作,并显示便携式设备。 如果您注释掉CoInitializeEx / CoUninitialize调用或传递COINIT_MULTITHREADED ,它将仍然有效,但它只显示驱动器。

 program ListMyComputer; {$APPTYPE CONSOLE} uses ComObj, ShlObj, ShellApi, ShLwApi, ActiveX, Windows, SysUtils; var Enum: IEnumIDList; Fetched: Longword; CompPidl, Item: PItemIDList; Path: PWideChar; Desktop, Computer: IShellFolder; StrRet: TSTRRET; begin CoInitializeEx(nil, COINIT_APARTMENTTHREADED); try WriteLn('Computer changed... Checking folders.'); SHGetDesktopFolder(Desktop); SHGetFolderLocation(0, CSIDL_DRIVES, 0, 0, CompPidl); Desktop.BindToObject(CompPidl, Nil, IID_IShellFolder, Computer); CoTaskMemFree(CompPidl); If Assigned(Computer) And (Computer.EnumObjects(0, SHCONTF_FOLDERS, Enum) = NOERROR) Then Begin While (Enum.Next(1, Item, Fetched) = NOERROR) Do Begin FillChar(StrRet, SizeOf(StrRet), #0); Computer.GetDisplayNameOf(Item, SHGDN_FORADDRESSBAR or SHGDN_NORMAL, StrRet); StrRetToStr(@StrRet, Item, Path); WriteLn(Path); CoTaskMemFree(Path); End; End; WriteLn('Enumeration complete'); ReadLn; finally CoUninitialize end; end. 

感谢@SertacAkyuz指出需要使用Windows便携式设备API,这导致我到这个专家交流问题讨论同样的事情。 Sinisa Vuk提供了一个很棒的代码示例来回答我已经链接的这个问题(嵌入的时间太长了),请点击这里http://pastebin.com/0hSWv5pE