UPSの状態確認

[戻る]
sys 2010/02/08(月) 12:31:17
質問させて頂きます。

UPS電源を搭載したPC(XP Pro)上では、
コントロールパネルの電源項目で、
UPS機能の設定が行えます。

主な機能としては、
主電源が落ちた時に自動的にシャットダウンするのですが、

このUPS電源・機能が期待している設定を
行われているかどうか確認するAPI等、
ご存知でしたら教えて頂けませんか?

aetos 2010/02/08(月) 13:20:49
UPSを持ってないので検証できませんが、WMIでできるみたいです。
http://msdn.microsoft.com/en-us/library/aa394503.aspx
http://msdn.microsoft.com/en-us/library/aa394074.aspx

sys 2010/02/08(月) 15:04:48
早速のお返事有難うございます。

Win32_UninterruptiblePowerSupply Classの情報で
十分今回行いたい事が可能で驚きました。

ただ、WMIを1度も使った事がないので、
そこで不安が。。。

VC++2008(C++)の環境でも、
スムーズにWMIを実装する事が可能でしょうか?

aetos 2010/02/08(月) 15:19:48
WMI では何らかのイベントが発生するまで待機というのもできます。
UPS で可能かどうかはわかりませんが、「UPSの状態が変化するまで待つ」というのもで
きるかもしれません。

WMI を使うのに楽な言語は? というと、まずは VBScript ですね。あとは C# や 
VB.NET なども。
C++ でももちろんできますが、面倒臭さではトップだと思います。
サンプルはやはり VBScript 等が多いと思います。
まずはいきなり目的を達成しようとせず、簡単なサンプルで VBScript を C++ に翻訳で
きるようになっておくと、後々役立つと思います。

http://www.wmifun.net/
http://www.codeproject.com/KB/system/Using_WMI_in_Visual_C__.aspx
http://www.codeproject.com/KB/system/UsingWMI.aspx

sys 2010/02/08(月) 18:44:04
[[解決]]
aetosさん
度々のお返事有難うございます。

早速ですがご紹介頂いたサイトを拝見させて頂きました。

どうやらCOM操作に似ているコードでしたので、
少し試してみてみます。

もし複雑でしたら、仰る通り
VBスクリプトからの翻訳の様な流れで
進めていこうと思います。
(何せあまり時間がないもので・・・)


今回非常に助かりました。
(一応解決済みという事で。)
また、分からない点がありましたら、
書き込ませて頂くので、
宜しくお願いします。

subaru 2010/02/09(火) 00:22:14
VBスクリプトから利用される WMI は Microsoft WMI Scripting というもので
VC++で使われる WMI とは微妙に違うインターフェースだったりします。

VBS版の方を忠実に翻訳するならこんな感じになるかと思います。
#UPS環境はないので検証はしてません。

#include <tchar.h>
#include <windows.h>
#include <atlbase.h>
#include <atlcom.h>
#include <wbemdisp.h>
#include <comdef.h>

int _tmain()
{
    if(FAILED(CoInitialize(NULL))) {
        return EXIT_FAILURE;
    }
    try {
        CComPtr<ISWbemLocator> loc;
        HRESULT hr = loc.CoCreateInstance(L"WbemScripting.SWbemLocator");
        _com_util::CheckError(hr);
        
        CComBSTR nameSpace(L"ROOT\\CIMV2");
        CComPtr<ISWbemServices> service;
        hr = loc->ConnectServer(
            NULL, nameSpace, NULL, NULL, NULL, NULL, 0, NULL, &service);
        _com_util::CheckError(hr);
        
        CComPtr<ISWbemObjectSet> objectSet;
        CComBSTR query(L"SELECT * FROM Win32_UninterruptiblePowerSupply");
        CComBSTR lang(L"WQL");
        hr = service->ExecQuery(query, lang, 0x30, NULL, &objectSet);
        _com_util::CheckError(hr);
        
        CComPtr<IUnknown> unkEnum;
        hr = objectSet->get__NewEnum(&unkEnum);
        _com_util::CheckError(hr);
        
        CComPtr<IEnumVARIANT> enumerator;
        hr = unkEnum->QueryInterface(&enumerator);
        _com_util::CheckError(hr);
        
        CComVariant v;
        hr = enumerator->Next(1, &v, NULL);
        _com_util::CheckError(hr);
        while(hr == S_OK) {
            CComPtr<IDispatch> item(v.pdispVal);
            v.vt = VT_EMPTY;
            
            CComVariant value;
            hr = item.GetPropertyByName(L"Availability", &value);
            _com_util::CheckError(hr);
            
            ATLTRACE2(_T("%d"), value.uiVal);
            ATLTRACE2(_T("\r\n"));
            
            hr = enumerator->Next(1, &v, NULL);
            _com_util::CheckError(hr);
        }
    }
    catch(_com_error& e) {
        ATLTRACE2(e.ErrorMessage());
        ATLTRACE2(_T("\r\n"));
    }
    CoUninitialize();
    return EXIT_SUCCESS;
}

古いスレッドには追加発言できません。