ディスクの空き容量を取得するには


やん  2008-07-24 22:48:45  No: 145007

VB2005 で、Windows にログインしているユーザが、
ハードディスクをあとどれぐらいのサイズを利用出来るかを
取得するにはどうすればよいでしょうか。

例えば、MicrosoftWindows2003 だと、C:\ドライブの空き容量が100GB
あったとしても、ユーザごとに使用量割り当てで 1GB しか
使えない状態に設定していた場合、1GB - 使っている分 = 空き容量
として取得したく思います。

宜しくお願いします。


シャノン  2008-07-25 00:06:56  No: 145008

My.Computer.FileSystem.GetDriveInfo("C:\").AvailableFreeSpace
でいいんじゃないでしょうか。


やん  2008-07-25 00:54:56  No: 145009

シャノンさんありがとうございます。
My.Computer.FileSystem.GetDriveInfo("C:\").AvailableFreeSpace
これですと、C:\ドライブの空き容量が100GBあった場合、
その100GB が返ってきます。
C:\Documents and Settings\myFolder\ を指定しても同じでした。

ユーザごとに使用量割り当てで 1GB しか
使えない状態に設定している場合は、空き容量1GB が
返ってきて欲しいのです。


やん  2008-07-25 00:58:29  No: 145010

MSDN で AvailableFreeSpace を調べましたが、
ディスククォータを考慮するとありました。
考慮されているなら1GB以下の数値が返ってきても良い気がしますが・・。


やん  2008-07-25 01:07:32  No: 145011

たびたびすみません。
サーバ管理者の話だと、WindowsServer2003 の管理ツールにある
「ファイルサーバリソースマネージャ」というところで
クォータの設定をしているようです。

マイコンピュータc:ドライブ右クリックで「クォータ」を開くと
クォータ管理は無効になっています。

これらは別物なんでしょうかね?


シャノン  2008-07-25 02:20:09  No: 145012

> これらは別物なんでしょうかね?

そのようですね。
http://www.atmarkit.co.jp/fwin2k/special/2003r2_02/2003r2_02_02.html

> Windows Server 2003 R2で導入されたクォータ機能(正確にはFSRMのクォータ管理機能)は、新しいサービス(「File Server Resource Manager」サービス)を使って実装されたものであり、従来のNTFSのディスク・クォータ機能とは別のものである。これは排他的に使用するものではなく、(実際には使うことはないだろうが)従来のクォータ機能もそのまま利用することができる。

だそうです。

ところで、そのクオータは、ハードクオータとソフトクオータのどちらですか?
違いは前掲の@ITのページ(とその次のページ)を参照してください。

> ハード・クォータの制限に達したフォルダをエクスプローラで見ても通常の場合と変わりはないが、コマンド・プロンプトを開いてdirコマンドを実行すると、ディスクの空き領域サイズが0になっていることが分かる。つまり、ハード・クォータの場合は、実際の空き領域サイズではなく、クォータの制限値が表示されていることになる。これに対してソフト・クォータの場合には、実際のボリュームの空きサイズが表示されている。

とあるのが気になっています。
もし、AvailableFreeSpace や、Windows API の方法である GetDiskFreeSpaceEx が FSRM を一切関知しないとしたら、Windows 2003 R2 の dir コマンドは FSRM 対応に作り直されていることになります。
しかし、正直、そんな作りになっているとは思えないのです。
こういうモノは、ユーザーはその存在を意識しなくていいように透過的に作られているべきで、AvailableFreeSpace でも制限後の値が取得できるべきだからです(そうでなければ、Windows 2003 R2 以降のソフトは、各々で FSRM に対応しなければなりません)。

ただし、クオータがソフトクオータであれば、dir でも制限された容量はわからないらしいですから、AvailableFreeSpace でもわからないのは妥当だと思います。
その場合は、FSRM の API を直接使うしかないでしょう。
API のドキュメントは MSDN にありましたが、
http://msdn.microsoft.com/en-us/library/bb972746.aspx
どういうわけか
> The FSRM API is available starting with Windows Server 2008.
と書かれています。2003 R2 の FSRM とはまた別物なのでしょうかね?


やん  2008-07-25 19:39:05  No: 145013

シャノンさん。詳しい解説サイトの紹介ありがとうございます。

> ところで、そのクオータは、ハードクオータとソフトクオータのどちらですか?

このサイトの説明によると、
ハードクォータ=容量一杯になった後の書き込みは不可。
ソフトクォータ=容量一杯になった後も警告は出るが書き込み可能。
ということなので、ソフトクォータでの AvailableFreeSpace 戻り値は
HDD全体の空き容量が返ってきても問題ないと思われます。

で、当方の環境はハードクォータになっていました。

確かに クォータ設定されているフォルダを dir で見ると
制限値内での空き容量が表示されますね。
しかし、AvailableFreeSpace に同じフォルダ名を渡してみると
HDD全体の空き容量が返ってきてしまいます。

ということは
> こういうモノは、ユーザーはその存在を意識しなくていいように透過的に作られているべきで
このようになっていないということですよね。

それとも何か見落としがあるのか・・。


シャノン  2008-07-25 21:01:33  No: 145014

> ということは
>> こういうモノは、ユーザーはその存在を意識しなくていいように透過的に作られているべきで
> このようになっていないということですよね。

えー。
それはいかんですねぇ。Microsoft に修正要望を出すべきだと思います。
が、ちょっと俺の手元に状況を再現できる環境が無いです。

最悪の場合、FSRM の API を直接実行するしかないわけですが、もし、第2、第3の FSRM のようなクオータサービス(Microsoft 製でないものも含む)が登場したときのことを考えると、頭が痛いですね。


魔界の仮面弁士  2008-07-25 21:04:22  No: 145015

> サーバ管理者の話だと、
サーバ管理者が設定しているのは、サーバ上のドライブに対する
クォータ設定ですか? それともクライアントに対する設定ですか?

また、作成したアプリは、各クライアントの上で動かすのでしょうか。
それとも各クライアント上のCPU にて実行されるのでしょうか。

> AvailableFreeSpace
System.IO.DriveInfo.AvailableFreeSpace は、GetDiskFreeSpaceEx API から
lpFreeBytesAvailable を返すような実装になっているようですね。

'-----------------
Imports System.Runtime.InteropServices
Module Module1

    Private Declare Auto Function GetDiskFreeSpaceEx Lib "kernel32" ( _
        ByVal directoryName As String, _
        ByRef freeBytesAvailable As ULong, _
        ByRef totalNumberOfBytes As ULong, _
        ByRef totalNumberOfFreeBytes As ULong _
    ) As <MarshalAs(UnmanagedType.Bool)> Boolean

    Sub Main()
        Dim a, b, c As ULong
        If GetDiskFreeSpaceEx("C:\", a, b, c) Then
            Console.WriteLine("AvailableFreeSpace ={0,20:#,0}", a)
            Console.WriteLine("         TotalSize ={0,20:#,0}", b)
            Console.WriteLine("    TotalFreeSpace ={0,20:#,0}", c)
        End If

        Dim d As New System.IO.DriveInfo("C")
        Console.WriteLine("AvailableFreeSpace ={0,20:#,0}", d.AvailableFreeSpace)
        Console.WriteLine("         TotalSize ={0,20:#,0}", d.TotalSize)
        Console.WriteLine("    TotalFreeSpace ={0,20:#,0}", d.TotalFreeSpace)
    End Sub

End Module


シャノン  2008-07-25 22:11:38  No: 145016

> System.IO.DriveInfo.AvailableFreeSpace は、GetDiskFreeSpaceEx API から
> lpFreeBytesAvailable を返すような実装になっているようですね。

はい。
.NET Framework のソースも見て確認しましたが、その通りです。

で、GetDiskFreeSpaceEx は FSRM を認識しないようです。

http://www.microsoft.com/communities/newsgroups/en-us/default.aspx?&query=GetDiskFreeSpaceEx&lang=en&cr=US&guid=&sloc=en-us&dg=microsoft.public.win2000.file_system&p=1&tid=3057c7a8-03d5-4b4e-9034-e66dd544ea52&mid=3057c7a8-03d5-4b4e-9034-e66dd544ea52


魔界の仮面弁士  2008-07-25 22:24:23  No: 145017

> FSRM を認識しないようです。
残念。SCRRUN.DLL も駄目でしょうか?
http://msdn.microsoft.com/ja-jp/library/cc428089.aspx

# 環境が無いので、試せない…。

> Microsoft に修正要望を出すべきだと思います。
フィードバック先としては、このあたり?
https://connect.microsoft.com/VisualStudio/Feedback
http://forums.microsoft.com/MSDN-JA/ShowForum.aspx?ForumID=183&SiteID=7


シャノン  2008-07-25 22:52:59  No: 145018

> フィードバック先としては、このあたり?

違う気がするなぁ。
そこにやったとして、AvailableFreeSpace は直してもらえるかもしれませんが、GetDiskFreeSpaceEx は直してもらえないでしょうね。
根本的には、FSRM を透過的にして欲しいという要望なので、
https://connect.microsoft.com/WindowsServerFeedback
このへんかなぁ。


やん  2008-07-25 23:35:23  No: 145019

魔界の仮面弁士さん、シャノンさん。
> サーバ管理者が設定しているのは、サーバ上のドライブに対する
> クォータ設定ですか? それともクライアントに対する設定ですか?
> また、作成したアプリは、各クライアントの上で動かすのでしょうか。
> それとも各クライアント上のCPU にて実行されるのでしょうか。

クォータ設定もアプリの実行環境も、WindowsServer2003 上です。
クライアントからは、ターミナルサービス接続で使用する形です。

> 残念。SCRRUN.DLL も駄目でしょうか?
http://msdn.microsoft.com/ja-jp/library/cc428089.aspx

結果は AvailableFreeSpace と一緒でした。

> Microsoft に修正要望を出すべきだと思います。

私もそう思っていたのですが、うちの環境だけの問題なのか
他でも同様なのかがわからなかったので躊躇しています。
お二方共環境が無いようですので他の方で試せる方が居ればいいのですが・・。

しかし、AvailableFreeSpace を仮に直してもらったとしても、
そのパッチを当てている環境と当てていない環境では結果が異なる
ことになりそうですからそれもちょっと頭の痛い問題のような気がします。


シャノン  2008-07-26 00:26:19  No: 145020

> お二方共環境が無いようですので他の方で試せる方が居ればいいのですが・・。

いい機会なので週末に環境作ってみます。

> それもちょっと頭の痛い問題のような気がします。

そうですね。
おそらく、直してもらえるとしても、小規模なパッチではなく、ServicePack か次期メジャーバージョンかという話になるでしょうね。


※返信する前に利用規約をご確認ください。




  


  このエントリーをはてなブックマークに追加