2016-05-04 3 views
1

物理ディスクのサイズ、または物理ディスクの一部である論理ドライブのサイズをプログラムで取得できます。不明なファイル形式のディスクやドライブのサイズを取得する、C#.NET Framework?

通常の状態では、論理ドライブのサイズを取得するのは簡単です。しかし、私が使用しているディスクについては、意図的に生データを書き込んでいるので、ドライブフォーマットがないと予想されますです。

Windowsではドライブのフォーマットが不明であるため、Windowsのドライブプロパティと.NET FrameworkのDriveInfoでは、この物理ディスクを構成する論理ドライブのサイズを知ることができません。 DriveInfo fooでは、フォーマットではfoo.DriveFormat、foo.IsReadyはfalse、foo.TotalSizeは例外をトリガーします。ドライブを右クリックするだけで、Windowsのプロパティオプションでサイズを手動で取得すると、ドライブのサイズが0バイトになります。

Windows 7システムでは、.NET Framework 4.0以前を使用してC#を使用することをお勧めします。物理ディスクまたはその物理ディスクを構成する論理ドライブのサイズを確認する方法既知のファイル構造はありませんか? 具体的には、物理​​ディスクのサイズが望ましいです。

私はアプリケーションが同じディスクの正確な物理ディスクサイズを与えるのを見ているので、一般的にWindows 7を使用する方法があることは知っています。

+2

この質問を見たか? http://stackoverflow.com/questions/4008620/getting-disk-size-properly –

+0

IO制御メッセージはおそらく? IOCTL_DISK_GET_LENGTH_INFO/IOCTL_DISK_GET_DRIVE_GEOMETRY –

+0

@ LasseV.Karlsen、前に質問が見つかりました。さらに努力した結果、.NET FrameworkでIOCTL_DISK_GET_LENGTH_INFOを正しく使用していないことがわかりました(ポインタと構造体のマーシャリングが正しくない)。それに応じて質問の回答を更新します。 –

答えて

1

ソリューションはかなり単純なことになった、そしておそらく完全なコードは、将来的に誰かを助けるよう、既存の質問Getting Disk Size Properly

からの拡張子は、ここに私の解決策を投稿:
(FYI:P /起動定義を得られ、最小限に修飾されたhttp://pinvoke.net

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
public static extern IntPtr CreateFile(
    [MarshalAs(UnmanagedType.LPTStr)] string filename, 
    [MarshalAs(UnmanagedType.U4)] FileAccess access, 
    [MarshalAs(UnmanagedType.U4)] FileShare share, 
    IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero 
    [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition, 
    [MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes, 
    IntPtr templateFile); 

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
static extern bool DeviceIoControl(IntPtr hDevice, uint dwIoControlCode, 
    IntPtr lpInBuffer, uint nInBufferSize, 
    IntPtr lpOutBuffer, uint nOutBufferSize, 
    out uint lpBytesReturned, IntPtr lpOverlapped); 

[DllImport("kernel32.dll", SetLastError = true)] 
static extern bool CloseHandle(IntPtr hObject); 

struct GET_LENGTH_INFORMATION 
{ 
    public long Length; 
}; 
long GetPhysDiskSize(string physDeviceID) 
{ 
    uint IOCTL_DISK_GET_LENGTH_INFO = 0x0007405C; 
    uint dwBytesReturned; 

    //Example, physDeviceID == @"\\.\PHYSICALDRIVE1" 
    IntPtr hVolume = CreateFile(physDeviceID, FileAccess.ReadWrite, 
     FileShare.None, IntPtr.Zero, FileMode.Open, FileAttributes.Normal, IntPtr.Zero); 

    GET_LENGTH_INFORMATION outputInfo = new GET_LENGTH_INFORMATION(); 
    outputInfo.Length = 0; 

    IntPtr outBuff = Marshal.AllocHGlobal(Marshal.SizeOf(outputInfo)); 

    bool devIOPass = DeviceIoControl(hVolume, 
         IOCTL_DISK_GET_LENGTH_INFO, 
         IntPtr.Zero, 0, 
         outBuff, (uint)Marshal.SizeOf(outputInfo), 
         out dwBytesReturned, 
         IntPtr.Zero); 

    CloseHandle(hVolume); 

    outputInfo = (GET_LENGTH_INFORMATION)Marshal.PtrToStructure(outBuff, typeof(GET_LENGTH_INFORMATION)); 

    Marshal.FreeHGlobal(hVolume); 
    Marshal.FreeHGlobal(outBuff); 

    return outputInfo.Length; 
} 
関連する問題