3

次のようなパスを変換するにはどうすればよいですか

\Device\HarddiskVolume3\Windows

対応する仮想パスに? (この場合は c:\Windows のように)

4

2 に答える 2

6

個人的に私はネイティブな方法を好みます:

function GetHDDDevicesWithDOSPath:TStringlist;
var
  i: integer;
  root: string;
  device: string;
  buffer: string;
begin
  setlength(buffer, 1000);
  result:=TStringlist.create;
  for i := Ord('c') to Ord('z') do
  begin
    root := Char(i) + ':';
    if (QueryDosDevice(PChar(root), pchar(buffer), 1000) <> 0) then
    begin
      device := pchar(buffer);
      result.add(format('%s = %s\',[device, root ]));
    end;
  end;
end;

注意:このコードサンプルは、http ://www.delphipraxis.net/165249-auflistung-devices.htmlから取得されます。

これにより、論理ドライブとパスの間のマップが返されます。私の場合:

\Device\HarddiskVolume2 = c:\
\Device\HarddiskVolume3 = d:\
\Device\IsoCdRom0 = e:\
\Device\CdRom0 = f:\
\Device\hgfs\;Z:0000000000084af9\vmware-host\Shared Folders = z:\

パス内の「\device\harddisk」の部分を対応するドライブ文字に置き換える必要があります。

ドライブ文字はユーザーによって異なることに注意してください。いくつかの便利なリンク:

于 2012-12-04T06:32:41.590 に答える
2

アプローチの 1 つは、たとえばhttp://www.magsys.co.uk/delphi/magwmi.aspなどの WMIを使用することです。これには、コード サンプルを取得するために使用できるデモもあります。

多数の WMI エクスプローラーを見つけて、構成クラスを探索し、クエリを構築できます。無料のものをいくつか挙げると:

  • Microsoft WMI CIM Studio はクエリを作成するのは苦手ですが、クラスを表示するには便利です
  • www.ks-soft.net の WMI Explorer が、私が最もよく使用するものになりました。

また、Google で WMI クエリ言語の例を探して仕様を読む必要があります。WMI 言語は SQL クエリに似ていますが、構文が少し異なり、一様でない制限を予測するのが困難です。


個人的には、別の方向に使用しました。物理ディスクまたはネットワーク サーバーごとにグループ化されたボリューム (ドライブ文字) のリストを作成する必要がありました。

私は以下のようなユニットで終了しました(速くてかなり醜いですが、プログラムの初期化での1回限りの作業には十分です)。その上で合理化を行うことができますが、リクエストと機能を逆にする必要があることは間違いありません。

unit WMI_Helper;

interface

function WMINetDiskName(const disk: string { 'C:' - w/o slash } ): string;
function WMIPhysDiskName(const disk: string { 'C:' - w/o slash } ): string;
function WMIGetVolumeName(const disk: string { 'C:' - w/o slash } ): string;

implementation

uses magwmi, SysUtils, StrUtils, Windows, IOUtils;

function WMIGetProp(const query, param, resultProp: string): string;
begin
  if MagWmiGetOneQ(StringReplace(query, '%s', param, []), resultProp, Result) <= 0
  then
    Result := '';
  Result := Trim(Result);
end;

function WMINetDiskName(const disk: string { 'C:' - w/o slash } ): string;
const
  req = 'select ProviderName from Win32_MappedLogicalDisk where DeviceID = "%s"';
  prop = 'ProviderName';
var
  i: integer;
begin
  Result := WMIGetProp(req, disk, prop);

  If not TPath.IsUNCPath(Result) then
    exit('');

  i := PosEx('\', TPath.GetPathRoot(Result), 3);
  if i <= 0 then
    exit('');

  SetLength(Result, i - 1);
end;

function WMIPhysDiskName(const disk: string { 'C:' - w/o slash } ): string;
const
  resultProp = 'DeviceID';
  reqPart = 'ASSOCIATORS OF {Win32_LogicalDisk.DeviceID="%s"} WHERE ResultClass=Win32_DiskPartition';
  reqDisk = 'ASSOCIATORS OF {Win32_DiskPartition.DeviceID="%s"} WHERE ResultClass=Win32_DiskDrive';
begin
  Result := WMIGetProp(reqPart, disk, resultProp);
  if Result > '' then
    Result := WMIGetProp(reqDisk, Result, resultProp);
end;

function WMIGetVolumeName(const disk: string { 'C:' - w/o slash } ): string;
const
  prop = 'VolumeName';
  reqNet = 'select VolumeName from Win32_MappedLogicalDisk where DeviceID = "%s"';
  reqPhy = 'select VolumeName from Win32_LogicalDisk where DeviceID = "%s"';

begin
  Result := WMIGetProp(IfThen(GetDriveType(PChar(disk)) = DRIVE_REMOTE, reqNet,
    reqPhy), disk, prop);
end;

end.

文字のないボリューム (c:\ と c:\Windows が 1 つのパーティションになり、c:\Windows\Temp がまったく別のディスクに存在するなど) は試していませんが、そのような構成を考慮する必要がある場合は、 WMI Explorer で適切なクエリを作成し、それをプログラムに追加できると信じています。

于 2012-12-04T06:04:34.163 に答える