
No.6ベストアンサー
- 回答日時:
参考までに、途中まで成功するコードを記述してみました。
#include<windows.h>
const GUID CLSID_Locator =
{0x76A64158,0xCB41,0x11D1,{0x8B,0x02,0x00,0x60,0x08,0x06,0xD9,0xB6}};
const GUID IID_Locator =
{0x76A6415B,0xCB41,0x11D1,{0x8B,0x02,0x00,0x60,0x08,0x06,0xD9,0xB6}};
LCID id;
//メソッドを実行する
HRESULT exec(IDispatch *p,OLECHAR *m,DISPPARAMS *s,VARIANT *r) {
HRESULT retc = 0;
DISPID disp = 0;
retc = p->GetIDsOfNames(IID_NULL,&m,1,id,&disp);
if( ! SUCCEEDED( retc ) ) return retc;
VariantInit(r);
retc = p->Invoke(disp,IID_NULL,id,DISPATCH_METHOD,s,r,NULL,NULL);
return retc;
}
//プロパティを取得する
HRESULT getp(IDispatch *p,OLECHAR *m,VARIANT *r) {
HRESULT retc = 0;
DISPID disp = 0;
retc = p->GetIDsOfNames(IID_NULL,&m,1,id,&disp);
if( ! SUCCEEDED( retc ) ) return retc;
VariantInit(r);
DISPPARAMS s = {NULL,NULL,0,0};
retc = p->Invoke(disp,IID_NULL,id,DISPATCH_PROPERTYGET,&s,r,NULL,NULL);
return retc;
}
//中核処理
HRESULT sub(IDispatch *p) {
HRESULT retc = 0;
VARIANT rval;
{
DISPPARAMS param = {NULL, NULL, 0, 0};
retc = exec(p,L"ConnectServer",¶m,&rval);
}
if( ! SUCCEEDED( retc ) ) return retc;
p = (IDispatch *)rval.ulVal;
{
VARIANT sql;
sql.vt = VT_BSTR;
sql.bstrVal = SysAllocString(L"SELECT * FROM Win32_DiskPartition");
DISPPARAMS param = {&sql, NULL, 1, 0};
retc = exec(p,L"ExecQuery",¶m,&rval);
SysFreeString(sql.bstrVal);
}
if( ! SUCCEEDED( retc ) ) return retc;
p = (IDispatch *)rval.ulVal;
retc = getp(p,L"Count",&rval);
if( ! SUCCEEDED( retc ) ) return retc;
int cnt = rval.ulVal;
IDispatch *obj;
for( int i = 0 ; i < cnt ; i++ ) {
VARIANT pos;
pos.vt = VT_I4;
pos.uintVal = i;
DISPPARAMS param = {&pos, NULL, 1, 0};
retc = exec(p,L"Item",¶m,&rval);//★ここで失敗する
if( ! SUCCEEDED( retc ) ) return retc;
obj = (IDispatch *)rval.ulVal;
}
return retc;
}
int WINAPI WinMain(HINSTANCE hi,HINSTANCE pi,LPSTR cp,int sw) {
id = GetUserDefaultLCID();
IDispatch *p = NULL;
HRESULT retc;
CoInitialize(0);//★必須
retc = CoCreateInstance(CLSID_Locator,0, CLSCTX_INPROC_SERVER,
IID_Locator, (void **)&p);
if( SUCCEEDED( retc ) ) retc = sub(p);
if( ! SUCCEEDED( retc ) ) {
char msg[128];
wsprintf(msg,"ERROR occured = %08x\n",retc);
MessageBox(NULL,msg,"Error",0);
}
CoUninitialize();
return 0;
}
ExecQueryに成功し、結果のオブジェクト数(Countプロパティ)を取得
するところまでは出来るんですが、やはり、For Each に相当する処理
が分かりません。オブジェクトには他にItemメソッド、Securityプロパティが
あります。後出しですが、Itemメソッドのパラメータに下記文字列を
指定すると、オブジェクトが取得でき、CaptionやSizeが取れます。
\\.\root\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #0"
でも、Diskが2個あるとか、パーティションがn個あるとどうなるか、
実際の環境が無いので、分かりません。上記文字列も結果を知ってから
コーディングしました。(だから後出しジャンケンなんですが・・・)
回答ありがとう御座います。
わざわざコードまで頂き大変有り難く思います。
なにやら、随分と難しそうですが、やはりディスクの情報なんかはディスクパラメータがない場合、
結構深いところまで探る必要があるわけですね。
OSがサービスを提供してくれるのはうれしいですが、
C言語でサクッと弄れるほど甘くはないですね。
知的好奇心はワクワクなのですが、
あまりに複雑怪奇だと結構時間が必要に思います。
スクリプトでサクッとファイルに出力してから
C言語側でファイルから情報を頂く感じで妥協するしかないですかね。
いやはや、ここまでしていただき感謝、感謝です。
本当にありがとう御座いました。
No.5
- 回答日時:
思い出したんですが、以前にCOMコンポーネントをCからイジろうとして
挫折したことがあります。その時に参照したページを紹介します。
http://www.asahi-net.or.jp/~kv8s-yjm/another/yja …
WBemScripting.SWBemLocator のIDを載せておきます。
CLSID:76A64158-CB41-11D1-8B02-00600806D9B6
TYPELIB:565783C6-CB41-11D1-8B02-00600806D9B6
回答ありがとう御座います。
中々、興味深いですね。
COMの知識は殆ど無いので一朝一夕で出来るとは思いませんが、
じっくりと調べて後試してみたいと思います。
貴重な情報ありがとうございました。

No.4
- 回答日時:
こんにちは。
物理ドライブのジオメトリ情報を取得することでも取得できますね。
CreateFileで "\\\\.\\PHYSICALDRIVEn"をファイルパスに指定することで、物理ドライブをオープンすることができます。
オープンできたらDeviceIoControlでIOCTL_DISK_GET_DRIVE_GEOMETRY_EXまたはIOCTL_DISK_GET_DRIVE_GEOMETRYを使って、希望の情報を取得できます。
開発環境によっては、Microsoft Windows SDKが必要かもしれません。
回答ありがとう御座います。
フォーマットされている場合には、ジオメトリ情報を読み込めますが
未フォーマットの状態では無理ですね。
ディスクパラメータも0で埋めてありますので、ディスクから情報を取り出すといった手法は取れません。
特に公開する訳でも無いので少々トリッキーな方法であっても
Win32APIを使ってC言語で組めればよいので
何か方法がありましたら、教えて頂けると幸いです。
No.3
- 回答日時:
未フォーマットだと、ディスクにアクセスした時点でエラーが出てしまう気がするので。
WMIを使うのが簡単かと。
お使いのC言語からWMIを呼び出せるか分かりませんが。
スクリプトですけど以下のサイトが参考になると思います。
11番目のWin32_DiskDriveのスクリプトを読んでみてください。
http://www.anchorsystems.jp/anchor/ashp/netmon/s …
回答ありがとう御座います。
大変参考になるWebサイトを教えていただき感謝いたします。
他にも色々あるようですので、じっくり見て学習していきたいと思います。
No.2
- 回答日時:
>ディスクは未フォーマット
フォーマットされていないと、「ドライブ」として認識されていない
ので、ドライブコード("C:"など)やディレクトリ名をパラメータと
するAPIは使用不可能です。
こういう場合はWMIを使って情報を収集します。
'★注意 == インデントに漢字空白を使用しています ==
Dim Q, A
Set Q = CreateObject("WBemScripting.SWBemLocator"). _
ConnectServer("."). _
ExecQuery("SELECT * FROM Win32_DiskPartition")
For Each A In Q
WScript.Echo "Name=""" & A.Caption & """" & _
",Size=" & CStr(A.Size)
Next
上記をコピペし、漢字空白を半角空白に変換してから、x.vbsとして
保存します。次にコマンドプロンプトから cscript x.vbs と入力
します。
結果は見てのお楽しみということで、必要な情報のヒントが得られる
のではないかと思います。実は上記オブジェクト(A)には34個の
プロパティがありまして、他に質問者さんの知りたそうなネタが
あるのですが、全部は紹介しきれませんので、ご了承ください。
WMIには他にデバイス情報、ディスク関連の種情報を得るものなどが
多数あります。("Win32_DiskPartition"以外に沢山あるということ)
他情報のオブジェクトにも多数のプロパティがあるので、調べれば
大抵のことは知ることができます。検索キーワードは"WMI"です。
尚、VBScriptなので、For Each 文でプロパティ名が不明であっても
内容を取得できますが、C言語でこれをやる方法を寡聞にして知り
ません。こちらは別途、お調べください。
回答ありがとう御座います。
できました。
こんな面白い機能があったなんて驚きです。
もっと詳しく知りたいですが、そこは自分で勉強いたします。
コマンドラインから情報を取得するのは自分で何とかできそうです。
ただ、C言語で同じようなことをするにはどうするんでしょうね。
色々調べて見たいと思います。
大変ありがたい情報、感謝いたします。
No.1
- 回答日時:
>C言語、WindowsXP環境での方法を教えてください。
「C言語」だけではありません。
開発環境として「VisualStudio」を使用していれば「GetDiskFreeSpaceEx」あたりが使用できるかもしれませんが、
それ以外の開発環境については専用のライブラリ等は知りません、
回答ありがとう御座います。
説明不足で申し訳ありません。
WindowsXPでWin32APIを使用できるC言語環境です。
VisualSutdioは使用していませんが、Win32APIは使えるので
教えていただいた関数を使ってみました。
>test.exe
このボリュームは認識可能なファイル システムではありません。
必要なファイル システム ドライブがすべて読み込まれているか、ボリュームが壊れていないか確認してください。
と詳細なエラーを吐き出しました。
ファイルシステムはゼロ・クリアしてあるので読み込めないようです。
ためしに他のボリュームを指定したところ上手く読み込めました。
これはこれで、勉強になりました。
ありがとうございます。
未フォーマットのディスクの容量を調べられる方法もありましたら
よろしくお願いいたします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- UNIX・Linux VirtualBox ゲストOSにPC内蔵HDDのパーティションをマウントする方法は? 2 2023/05/06 22:52
- ドライブ・ストレージ 外付けSSD(500GB)の接続で、PCストレージの C ディスク容量を増やせますか? 4 2022/09/12 17:59
- ドライブ・ストレージ 光学ベイに取り付けたSSDからWINDOWS10を起動したい。 10 2023/05/01 18:04
- その他(パソコン・周辺機器) 起動中のパソコンから外付けHDDを取り外すとき、電源を抜いたときにディスクとヘッドが接触しますか? 2 2023/07/12 19:04
- Mac OS 外部HDディスクの変更したファイルうを保存できないトラブル 3 2022/05/25 11:25
- Windows 10 新しく購入したWindowsパソコンのディスクの容量を変更しています。 Cドライブの容量が元々1TB 9 2023/08/09 16:39
- バックアップ Cドライブが満杯になり過去のバックアップと思われる領域を削除したい 3 2022/08/15 11:53
- UNIX・Linux LINUXでのパーティション追加について 1 2022/12/09 11:15
- ネットワーク syslog保存サーバーに蓄積するログファイル容量について 3 2023/01/09 20:13
- Mac OS パソコンに詳しい方教えてください 現在MacBookを使ってるんですがiTunesで曲をダウンロード 2 2022/06/18 18:41
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA エンターキーでイベントに...
-
Excel VBAでマウスの左クリック...
-
アクセスVBAのMe!と[ ]
-
起動済のIEから.NET Framework...
-
オブジェクト
-
Accessのフォーム上にエクセル...
-
VBでExcelの表形式の様なデザイ...
-
エクセルVBAでセル番地を指定し...
-
VBAでオブジェクトを小数点で位...
-
Imageコントロールにグラフを表...
-
【エクセルのマクロ】クリップ...
-
コードでオブジェクトを最前面に
-
【VBA】ワークシート上に画像フ...
-
認識するイベントの範囲を制限...
-
サブルーチンにオブジェクト名...
-
エクセルVBA初心者です。オブジ...
-
SQLの更新の時、記号 ’ について
-
Excel2007 でのチェックボック...
-
DLLの共有メモリと排他処理???
-
「ご処理進めて頂きますようお...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA エンターキーでイベントに...
-
アクセスVBAのMe!と[ ]
-
エクセルVBAでセル番地を指定し...
-
Excel VBAでマウスの左クリック...
-
Accessのフォーム上にエクセル...
-
日本語の文字化けを直す方法
-
文字列で小数点以下の0を削除し...
-
コードでオブジェクトを最前面に
-
Excel2007 でのチェックボック...
-
ExcelのシートをAccessで表示し...
-
【エクセルのマクロ】クリップ...
-
LoadImage関数について(VC++)
-
【エクセル】複数のTextBoxに共...
-
[C#] DataGridViewの項目名
-
現在アクティブになっているオ...
-
Webbrowserで完全にHPを表示さ...
-
サブルーチンにオブジェクト名...
-
ユーザーフォームのインポート...
-
ビデオキャプチャについて
-
代入しているのになぜnullのま...
おすすめ情報