Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
皆さんごきげんよう。ういこです。
さらに WMI ネタ「Windows XP SP3 だと Win32_LogicalDisk が FDD のデータを取れないことがある」をご紹介させていただきます。
どうも、最近気づいたのが、Win32_LogicalDisk とフロッピーディスクドライブとの相性が良くないっぽい様子で、Windows XP SP3 以降だと、例えば空き容量とかが取れないことがあるみたいです。私の Virtual PC の環境と、同じチームの人から無理やり借りた実機では取れませんでした。ただ、環境によって取れることもあるらしい(私の手元では未確認)ので、障害かどうかについては後日判明したら掲載する予定です。
さてその場合の代替手段ですが、ズバリ "Win32 API の GetDiskFreeSpaceEx() を使うこと" です。C++ 使ってるなら楽なんですが、.NET の場合、.NET Framework 2.0 以降なら System.IO.DriveInfo が使えるかもしれませんが、未確認です。実際使って取れたよ!というかたはこっそり教えてください。(後日一応試す予定です)また、それ以前のバージョンの場合は使えないので、環境がどれか怪しい場合は Win32 API を使うのがよさそうです。ちなみに、.NET Framework のドキュメントには GetDiskFreeSpaceEx() の変わりに WMI を使えと書いてあるんですが、残念です…。 スクリプトの場合は…ちょっと方法を考えます…。
プラットフォーム SDK
GetDiskFreeSpaceEx
指定されたディスクの容量に関する情報を取得します。ディスク全体の容量、全体の空き容量、呼び出し側スレッドに関連するユーザーが利用できる空き容量を取得します。
https://msdn.microsoft.com/ja-jp/library/cc429308.aspx
※ 注意
Windows XP では、ディスククォータ機能によって利用できるディスク容量を制限されたユーザで GetDiskFreeSpaceEx() を実行した結果と、実際の空き容量の値が異なる可能性がありますので、総空き容量を示す lpTotalNumberOfFreeBytes 引数ではなく、呼び出し側が利用できる空き容量を示す lpFreeBytesAvailable 引数の値を利用することをお勧めいたします。
以下、コード例です。Win32 API のほうは MSDN に例があるので、C# をご紹介させていただきます。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
namespace GetDiskFreeSpaceEx_CS
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
[DllImport("kernel32.dll", BestFitMapping = false , CharSet = CharSet.Auto ,
EntryPoint = "GetDiskFreeSpaceEx", SetLastError = true)]
public static extern bool GetDiskFreeSpaceEx(
[MarshalAs(UnmanagedType.LPWStr)] string lpDirectoryName,
[Out] out long lpFreeBytesAvailable,
[Out] out long lpTotalNumberOfBytes,
[Out] out long lpTotalNumberOfFreeBytes
);
private void button1_Click(object sender, EventArgs e)
{
long lpFreeBytesAvailable; // ドライブ名。C: とか、A: とか。
long lpTotalNumberOfBytes;
long lpTotalNumberOfFreeBytes;
string lpbuf;
GetDiskFreeSpaceEx(@"A:\", out lpFreeBytesAvailable,
out lpTotalNumberOfBytes, out lpTotalNumberOfFreeBytes);
lpbuf = lpFreeBytesAvailable + " : 呼び出し側が利用できるバイト数 (単位 : Byte)" + "\r\n" +
lpTotalNumberOfBytes + " : ディスク全体のバイト数 (単位 : Byte)" + "\r\n" +
lpTotalNumberOfFreeBytes + " : ディスク全体の空きバイト数 (単位 : Byte)";
MessageBox.Show(lpbuf);
}
}
}
VB.NET の場合はこんな感じ(色は許してください)↓
<DllImport("kernel32.dll", BestFitMapping:=False, CharSet:=CharSet.Auto, EntryPoint:="GetDiskFreeSpaceEx", SetLastError:=True)> _
Public Shared Function GetDiskFreeSpaceEx(<MarshalAs(UnmanagedType.LPWStr)> ByVal lpDirectoryName As String, ByRef lpFreeBytesAvailable As Long, ByRef lpTotalNumberOfBytes As Long, ByRef lpTotalNumberOfFreeBytes As Long) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
Dim lpFreeBytesAvailable As Long '呼び出し側が利用できるバイト数
Dim lpTotalNumberOfBytes As Long 'ディスク全体のバイト数
Dim lpTotalNumberOfFreeBytes As Long 'ディスク全体の空きバイト数
Dim lpbuf As String
GetDiskFreeSpaceEx("C:\", lpFreeBytesAvailable, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes)
lpbuf = lpFreeBytesAvailable.ToString() + " 呼び出し側が利用できるバイト数 (単位 : Byte)" + ControlChars.CrLf _
+ lpTotalNumberOfBytes.ToString() + "ディスク全体のバイト数 (単位 : Byte)" + ControlChars.CrLf _
+ lpTotalNumberOfFreeBytes.ToString() + "ディスク全体の空きバイト数 (単位 : Byte)"
MessageBox.Show(lpbuf)
これで実際、ういこうの環境で空き容量は取れたので、お困りの方はお試しください。また、間違ってたらこっそり教えてください。(“EntryPoint” は、別に宣言してる関数名と対応する Win32 API の名前一緒なんだけどなんとなくつけちゃいました。癖で…)
アップデートがありましたら随時更新しますです。それでは、また!
ういこう@ドクター中松発明の傑作「しょうゆちゅるちゅる(多分正式名称)」を去年の出張の時に US に持って行きました
(残念なおまけ) Microsoft Win32 と Microsoft .NET Framework API との対応
https://msdn.microsoft.com/ja-jp/library/aa302340.aspx
GetDiskFreeSpaceEx |
ディスクの空き容量など、指定されたディスクに関する情報を取得します。 |
System.Management.ManagementObject("Win32_LogicalDisk.DeviceID=\"C:\"").Get System.Management.ManagementObject.Properties |
…なんてこったいです… orz