以下の各入力を考慮して、その場所に空き領域を取得したいと思います。何かのようなもの
long GetFreeSpace(string path)
入力:
c:
c:\
c:\temp
\\server
\\server\C\storage
これは私のために働く...
using System.IO;
private long GetTotalFreeSpace(string driveName)
{
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
if (drive.IsReady && drive.Name == driveName)
{
return drive.TotalFreeSpace;
}
}
return -1;
}
幸運を!
GetDiskFreeSpaceEx
RichardODによるfromリンクを使用した作業コードスニペット。
// Pinvoke for API function
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetDiskFreeSpaceEx(string lpDirectoryName,
out ulong lpFreeBytesAvailable,
out ulong lpTotalNumberOfBytes,
out ulong lpTotalNumberOfFreeBytes);
public static bool DriveFreeBytes(string folderName, out ulong freespace)
{
freespace = 0;
if (string.IsNullOrEmpty(folderName))
{
throw new ArgumentNullException("folderName");
}
if (!folderName.EndsWith("\\"))
{
folderName += '\\';
}
ulong free = 0, dummy1 = 0, dummy2 = 0;
if (GetDiskFreeSpaceEx(folderName, out free, out dummy1, out dummy2))
{
freespace = free;
return true;
}
else
{
return false;
}
}
DriveInfoはそれらのいくつかに役立ちます (ただし、UNC パスでは機能しません) が、実際にはGetDiskFreeSpaceExを使用する必要があると思います。おそらく、WMI を使用していくつかの機能を実現できます。GetDiskFreeSpaceEx が最善の策のようです。
おそらく、パスを適切に機能させるためにパスをクリーンアップする必要があるでしょう。
GB 単位のサイズを探していたので、上記の Superman のコードを次の変更で改善しました。
public double GetTotalHDDSize(string driveName)
{
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
if (drive.IsReady && drive.Name == driveName)
{
return drive.TotalSize / (1024 * 1024 * 1024);
}
}
return -1;
}
未テスト:
using System;
using System.Management;
ManagementObject disk = new
ManagementObject("win32_logicaldisk.deviceid="c:"");
disk.Get();
Console.WriteLine("Logical Disk Size = " + disk["Size"] + " bytes");
Console.WriteLine("Logical Disk FreeSpace = " + disk["FreeSpace"] + "
bytes");
ところで、 c:\temp の空きディスク領域の結果はどうなりますか? c:\ の空き領域が得られます
私のプロジェクトでも同様の方法が必要でしたが、私の場合、入力パスはローカル ディスク ボリュームまたはクラスター化されたストレージ ボリューム (CSV) からのものでした。そのため、DriveInfo クラスは機能しませんでした。CSV には、別のドライブ (通常は C:\ClusterStorage\Volume*) の下にマウント ポイントがあります。C: は、C:\ClusterStorage\Volume1 とは異なるボリュームになることに注意してください。
これが私が最終的に思いついたものです:
public static ulong GetFreeSpaceOfPathInBytes(string path)
{
if ((new Uri(path)).IsUnc)
{
throw new NotImplementedException("Cannot find free space for UNC path " + path);
}
ulong freeSpace = 0;
int prevVolumeNameLength = 0;
foreach (ManagementObject volume in
new ManagementObjectSearcher("Select * from Win32_Volume").Get())
{
if (UInt32.Parse(volume["DriveType"].ToString()) > 1 && // Is Volume monuted on host
volume["Name"] != null && // Volume has a root directory
path.StartsWith(volume["Name"].ToString(), StringComparison.OrdinalIgnoreCase) // Required Path is under Volume's root directory
)
{
// If multiple volumes have their root directory matching the required path,
// one with most nested (longest) Volume Name is given preference.
// Case: CSV volumes monuted under other drive volumes.
int currVolumeNameLength = volume["Name"].ToString().Length;
if ((prevVolumeNameLength == 0 || currVolumeNameLength > prevVolumeNameLength) &&
volume["FreeSpace"] != null
)
{
freeSpace = ulong.Parse(volume["FreeSpace"].ToString());
prevVolumeNameLength = volume["Name"].ToString().Length;
}
}
}
if (prevVolumeNameLength > 0)
{
return freeSpace;
}
throw new Exception("Could not find Volume Information for path " + path);
}