次のようなパスを変換するにはどうすればよいですか
\Device\HarddiskVolume3\Windows
対応する仮想パスに? (この場合は c:\Windows のように)
個人的に私はネイティブな方法を好みます:
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」の部分を対応するドライブ文字に置き換える必要があります。
ドライブ文字はユーザーによって異なることに注意してください。いくつかの便利なリンク:
アプローチの 1 つは、たとえばhttp://www.magsys.co.uk/delphi/magwmi.aspなどの WMIを使用することです。これには、コード サンプルを取得するために使用できるデモもあります。
多数の WMI エクスプローラーを見つけて、構成クラスを探索し、クエリを構築できます。無料のものをいくつか挙げると:
また、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 で適切なクエリを作成し、それをプログラムに追加できると信じています。