使用Delphi查找特殊驱动器 [英] Use Delphi to Find Special Drives

查看:109
本文介绍了使用Delphi查找特殊驱动器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Delphi 2007中编写一个小程序,以便在将便携式USB驱动器插入Windows 7计算机时访问文件。但是,该驱动器未显示为标准驱动器号。它显示在Windows资源管理器中的便携式设备下。我编写了以下代码来枚举计算机下的所有项目:

I am trying to write a small program in Delphi 2007 to access files off of a portable USB drive whenever it is plugged in to a Windows 7 machine. This drive does not show up as a standard drive letter though. It appears under Portable Devices in Windows Explorer. I have written the following code to enumerate all the items under 'Computer':

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输出一条消息。)

(note: the Status procedure just outputs a message to a TMemo.)

只要Windows Shell子系统通知我的应用程序有更改,就会调用此方法。它枚举了所有本地驱动器和网络驱动器,但没有其他枚举(也缺少iCloud Photos驱动器)。

This is called whenever my application is notified of a change by the Windows shell subsystem. It enumerates all of the local drives and network drives but nothing else (iCloud Photos drive is missing as well).

有人知道我如何访问这些虚拟驱动器上的文件

Does anyone know how I can access the files on these virtual drives?

推荐答案

您很有可能没有正确初始化COM。如果您不调用 CoInitializeEx 或如果您用不好的值来调用它,但便携式设备驱动程序需要单元线程才能工作。

You more than likely aren't initializing COM correctly. Your code will work as-is if you don't call CoInitializeEx or if you call it with a bad value, but the Portable Device drivers require apartment threading to work.

根据您的代码,这是一个示例应用程序,可以正常运行并显示便携式设备。如果您注释掉 CoInitializeEx / CoUninitialize 调用或传递 COINIT_MULTITHREADED

Based on your code, here's a sample app that works correctly and shows portable devices. If you comment out the CoInitializeEx/CoUninitialize calls or pass in COINIT_MULTITHREADED instead it will still work, but it only shows the drives.

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.

这篇关于使用Delphi查找特殊驱动器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆