現在ある状態になったら、ネットワークを停止(ネットワークアダプタの無効化)するプログラムを作成中なのですが、やり方が分かりません。どなたかご存じの方がいらっしゃいましたら、宜しくお願い致します。
WMIとかで可能のようなのですが、具台的な内容が分かりませんでした。
【環境】
使用OS : Windows98,2000,XP
使用言語 : VC++ 6.0 or VB
VC++でWMIをするなら WMISDK が必要でしょうね。
HELP の MSDN ライブラリにあったMSサイトへのリンクは切れてました。
サブスクリプションしてるなら、
Microsoft Platform SDK - November 2001 Edition
English Disk 0004-4 February 2002
に入ってましたが.....
訂正
>>サブスクリプション
サブスクライブ
なーめさん、有り難う御座います。
早速探してみます。
http://www011.upp.so-net.ne.jp/oshieru/note/Scripting.txt
参考になるかな。
以下はローカルサーバでテストした ASP の一部です。
response.write("<body bgcolor=black text=white link=yellow vlink=yellow alink=red>")
response.write("<center><h3>【ネットワークアダプタリスト】</h3></center>")
response.write("<hr>")
response.write("<center><table border=1 cellpadding=1 cellspacing=1>")
response.write("<tr><th>Name</tr>")
set obj = GetObject("winmgmts:{impersonationLevel=impersonate}").InstancesOf("Win32_NetworkAdapter")
for each ob in obj
response.write( "<tr><th>" )
response.write( ob.name )
next
response.write("</table></center>")
set obj = Nothing
response.write("<hr>")
response.write("</body>")
[なーめ 2003/12/08(月) 19:56:45]
を VisualC++ 6.0 のダイアログアプリの OnOK() にて
書いてみました。
#include <Wbemcli.h>
#include <WbemProv.h>
void ReportError( HRESULT hr )
{
char * msg;
switch( hr )
{
case WBEM_E_ACCESS_DENIED:
msg = "The current or specified user name and password were not valid or authorized to make the connection.";
break;
case WBEM_E_FAILED:
msg = "This indicates other unspecified errors.";
break;
case WBEM_E_INVALID_NAMESPACE:
//msg = "The specified namespace did not exist on the server.";
msg = "サーバにそのような名前空間はありません";
break;
case WBEM_E_INVALID_PARAMETER:
msg = "An invalid parameter was specified.";
break;
case WBEM_E_INVALID_QUERY:
msg = "The query was not syntactically valid.";
break;
case WBEM_E_INVALID_QUERY_TYPE:
msg = "The requested query language is not supported.";
break;
case WBEM_E_OUT_OF_MEMORY:
msg = "There was not enough memory to complete the operation.";
break;
case WBEM_E_SHUTTING_DOWN:
msg = "Windows Management service was probably stopped and restarted. A new call to ConnectServer is needed.";
break;
case WBEM_E_TRANSPORT_FAILURE:
msg = "This indicates the failure of the remote procedure call (RPC) link between the current process and Windows Management.";
break;
case WBEM_E_NOT_FOUND:
msg = "The query specifies a class that does not exist.";
break;
case WBEM_E_LOCAL_CREDENTIALS:
msg = "WMI is passing the user credential on local connection.\n";
break;
case WBEM_E_UNEXPECTED:
msg = "An object in the enumeration has been deleted, destroying the validity of the enumeration.";
break;
case WBEM_S_FALSE:
msg = "WBEM_S_FALSE(The number of objects returned was less than the number requested. WBEM_S_FALSE is also returned when this method is called with a value of 0 for the uCount parameter.)";
break;
case WBEM_S_TIMEDOUT:
msg = "A time-out occurred before you obtained all the objects.";
break;
default:
case WBEM_S_NO_ERROR:
//msg = "The call succeeded.";
msg = "呼び出しは正常に処理されました";
break;
}
TRACE("%s\n", msg );
}
#if 0
case :
msg = "";
break;
#endif
#ifndef WBEM_MAX_OBJECT_NESTING
#define WBEM_MAX_OBJECT_NESTING 256
#endif
void CW02Dlg::OnOK()
{
DWORD dwCTX = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER;
IWbemServices * pWbemServices = NULL;
IWbemLocator * pWbemLocator = NULL;
IWbemContext * pWbemContext = NULL;
// IWbemClassObject* m_pIWbemObject[WBEM_MAX_OBJECT_NESTING];
IWbemClassObject* pIWbemObject;
CStringArray acsNames;
int nCntNames = 0;
// NameSpace に "winmgmts:" はつけない。
// BSTR bstrNamespace = L"winmgmts:{impersonationLevel=impersonate}";
// BSTR bstrNamespace = SysAllocString(L"{impersonationLevel=impersonate}");
BSTR bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2");
BSTR bstrUser = SysAllocString(L"tutumi");
BSTR bstrPasswd = SysAllocString(L"Logical");
BSTR bstrLocale = NULL;
long lSecurityFlags = 0; // WBEM_FLAG_CONNECT_USE_MAX_WAIT;
BSTR bstrAuthority = NULL;
HRESULT hr;
if(( hr = CoCreateInstance( CLSID_WbemAdministrativeLocator,NULL,dwCTX,IID_IUnknown ,(void **) &pWbemLocator )) == S_OK )
{
if(( hr = pWbemLocator->ConnectServer( bstrNamespace, bstrUser, bstrPasswd, bstrLocale, lSecurityFlags, bstrAuthority, pWbemContext, &pWbemServices )) == S_OK )
{
CComBSTR ccbsQueryLanguage = L"WQL";
// CComBSTR ccbsQuery = L"Select IPAddress from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE";
CComBSTR ccbsQuery = L"Select Name from Win32_NetworkAdapter";
long lFlags = WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY;
IWbemContext* pCtx = NULL;
IEnumWbemClassObject * pEnum;
if(( pWbemServices->ExecQuery( ccbsQueryLanguage, ccbsQuery, lFlags, pCtx, &pEnum )) == S_OK )
{
unsigned long bGotton;
unsigned long bFound = 0;
while( pEnum->Next( WBEM_INFINITE, 1, &pIWbemObject, &bGotton ) == WBEM_S_NO_ERROR )
{
long cimtype;
CComVariant v;
CComBSTR ccbsName;
_bstr_t bs;
pIWbemObject->BeginEnumeration( 0 );
while( pIWbemObject->Next( 0, &ccbsName, &v, &cimtype, NULL ) == WBEM_S_NO_ERROR )
{
char s[1024];
strcpy( s, (char *)( bs = ccbsName ));
if( s[0] != '_')
{
if(! strcmp( s, "Name" ))
{
if(( pIWbemObject->Get(L"Name",0,&v,0,0)) == WBEM_S_NO_ERROR )
{
_bstr_t bstName = v;
//TRACE("Name: %s\n", (char *)bstName );
acsNames.SetAtGrow( nCntNames++, (char *)bstName );
}
}
else
{
TRACE("XXX[%08X]: %s\n", cimtype, s );
}
}
}
pIWbemObject->EndEnumeration();
pIWbemObject->Release();
bFound ++;
}
pEnum->Release();
if( bFound == 0 )
{
TRACE("ENUM: NoData Found.\n");
}
}
else
{
TRACE("ExecQuery - Failed.\n");
TRACE("HR=0x%08X.\n", hr );
ReportError( hr );
}
pWbemServices->Release();
}
else
{
TRACE("ConnectServer - Failed.\n");
TRACE("HR=0x%08X.\n", hr );
ReportError( hr );
}
pWbemLocator->Release();
//
}
else
{
MessageBox("IWbemLocator: Failed.", "ERROR", MB_ICONSTOP );
TRACE("HR=0x%08X.\n", hr );
}
SysFreeString( bstrPasswd );
SysFreeString( bstrUser );
SysFreeString( bstrNamespace );
int c;
for( c = 0; c < nCntNames; c ++ )
{
TRACE("NAME: %s\n", acsNames[c] );
}
//CDialog::OnOK();
}
同様にVC6.0 or VB6.0でネットワークアダプターを無効にしたく参考にさせていただいたのですが,CoCreateInstanceでどうしても失敗してしまいます。なにかOCXをインストールしておかなければいけないのでしょうか?
開発環境は下記で行っております。
W2K
Visual Stadio6.0
Microsoft Platform SDK February 2003
CoInitializeEx()を事前にCallする、とか。エラーの戻りは何?
なーめさんのサンプルは、アダプタ名を列記するサンプルみたい。
アダプタの設定はどうやるんだ。俺も知りたい。
「Networking Device Classes」あたりがあやしそうだが、そもそもC++から
メソッドを呼び出す方法がわからん。
>> なにかOCXをインストールしておかなければいけないのでしょうか?
最初に発言した WMISDK が入っています。
MSDN は OCTOBER 2001 <-↑↓ Visual Studio.Net Pro をサブスクライブして得たもの。
Visual C++ 6.0 SP5 です。
それだけです。
で、WMISDK はなるみさんのレスがないので、見つかっていないのかもしれません。
でも、
>> Microsoft Platform SDK February 2003
これには WMI も入ってるかもしれませんね。
#include <Wbemcli.h>
#include <WbemProv.h>
は問題なかったんですよね。
wbem で winnt 以下を検索すると、\winnt\system32\wbem 以下に
タイプライブラリが2個ほどはいっていますよね。
これをクラスウィザード Ctrl+W でクラスの作成/タイプライブラリから
を使用すると、似たクラスのラッパができます。
機能は酷似しているようだが、別物なので、CLSID や IID は異なると思われます。
それらをインポート(#import)して tlh や tli を確認してみてはいかがかと。
得られた CLSID や IID が レジストリに登録されているかどうか検索してみると確実ですね。
>> CoInitializeEx()を事前にCallする、とか。
それでいいはず。で、UnInitialize() も書くべきか。
上のVC++6.0 のサンプルはテストなんで、プログラム自体はへんてこなんです。
まともにやると面倒なんで、ここでは次のようにしています。
MFC AppWizard(exe) でダイアログアプリを選択。
全てデフォルトでできあがったプロジェクトに
[挿入][ATLオブジェクトの新規作成]
そして、オブジェクトの作成ダイアログができますが、ここでキャンセルします。
キャンセルしても、ATLオブジェクトを使う環境になりますので、
COM+ の初期化系(CoInitializeEx)は今後追加不要となります。
その後、
stdafx.h にて comdef.h comutil.h をインクルード。
さらに
[プロジェクト][設定][C++][プリプロセッサ][インクルードファイルのパス]
に SDK のインクルードのディレクトリ。
そして、CLSID_xxxxx の実体を含むライブラリをリンク
[プロジェクト][設定][リンク][一般][オブジェクト/ライブラリモジュール]
WbemUuid.Lib
で、
[プロジェクト][設定][リンク][インプット][追加ライブラリのパス]
にライブラリの入っているフォルダ(ディレクトリ)を指定する。
う゛ーん接続語がいいかげん。
その上で、上記のコードを
OnOK() のところに書いたものです。
結果はデバッグ窓へ。
>> アダプタ名を列記するサンプルみたい。
Name プロパティを持つものを集めてきて表示しています。
(なーめプロパティ (^^;; )
Win32_NetworkAdapter でぐーぐる(日本語サイトに限ると3件しか出てこない)
# ってことはしばらくするとこのページも4件目に登録されるかな。
http://www011.upp.so-net.ne.jp/oshieru/note/Scripting.txt
ここで VB からの使い方がわかります。
MSDN2001/10月なら
キーワード Win32_NetworkAdapter を入力ここで、プロパティやメソッドがわかります。
[同期]を押すと似たようななまえが一杯並びますので、ほかのオブジェクトについてもわかります。
同じく IWbemClassObject でキーワード、そして同期を押して、本のアイコンを開く。
すると、IWbemClassObject のメソッド一覧が出るので、所定のパラメタを与えてよびだせばよい。
COM ご存知なら、
CComBSTR や CComVariant, _bstr_t, _variant_t は大丈夫ですよね。
ちなみに char -> wchar_t なんぞはお手軽に _bstr_t にやらせたりして手を抜いています。
SAFEARRAY が出てきたら面倒ですね。
OLE2 のプログラマーズリファレンスII 参照か。(白+わさび色のあの本ね)
設定可能なプロパティをもつオブジェクトを集めてきて、オブジェクトに対して、
GetではなくPutを使えばよいですね。
詳しくは上記ヘルプを読んでください。(えーごだー!...とはいわないでね) (^^;; >> ギャラリー
>> エラーの戻りは何?
REGDB_E_CLASSNOTREG : 0x80040154L : レジストリにない。
CLASS_E_NOAGGREGATION : 0x80040110L : 集成(アグリ)できない。
E_NOINTERFACE : 0x80004002L : インターフェースがない、見えない
おそらく 0x80040154L かな。
regsvr32 されていないだけかもしれない。(^^;;
>> 「Networking Device Classes」あたりがあやしそうだが、
どっとねっとですね。あるいは MSDN 2002.07
上記を作成した VC6.0のマシンでは見つからず、
別マシンに入っているVisualStudio.NETのヘルプで確認しました。
あやしいどころか、上のプログラムはこれそのものです。
アダプタとかコンフィギュレーションとか入ってます。
これをクリックすると、WMIの項目の下に飛びました。
要するにWMI/WBEMから使うものということです。
結局OS管理下のリソースはWMI/WBEMという統一的なインターフェースを通じて
行うということですね。
>> そもそもC++からメソッドを呼び出す方法がわからん。
それが WBEM のインターフェース/メソッドで上に示したものです。
面倒ですね。せめてレジストリと同じ様にアクセスしたい。
# なんていうか、VCから見ると、VBの CreateObject() ってすっごくずるいよねー。
# C♯持ってらっしゃるなら、試してくださいよ、是非是非。
上の Put/Get のほかに PutMethod/GetMethod なんてのがありますが、
試していません。
これがダメなら、
IDispatch の vtbl と ITypeInfo を使って強引に Invoke() するとか。
手はありそうですが。
ところで、Invoke は適用するとか発動するという意味(こりゃ英和)ですが
古い辞書では「呪い出す」なんて載ってます。昔のVOS3のときに
PLIコンパイラをINVOKEしたとか、メッセージが出て妙に楽しかった。
ちなみに
WMI:「わみ」
WBEM:「うべむ」「うーべん」
だめですかね。
なーめさん>
丁寧なご回答ありがとうございます。
すみません。単純にCOMの初期化が行われていなかったために
失敗していました。
"::CoInitialize(0);"の追記でエラーなく動作しました。
>Name プロパティを持つものを集めてきて表示しています。
↑と言うと,お題とはちょっと違う内容と思っていいのでしょうか?
一応,WMIもMicrosoftからDLしたのですが,よくよく見ると
Microsoft Platform SDK February 2003にもちゃんと入っていました。
> Microsoft Platform SDK February 2003にもちゃんと入っていました。
サンプルとしては Samples\sysmgmt\WMI\VC\SimpleClient
が一番簡単そうなので、この辺から少しずつ攻めて行ってる状態です。
インクルードのパスがおかしいぞ。
他のサンプルを見るとメソッドの呼び出しもやってるみたい。
まあ、ぼちぼちいってみます。
以下念のため。まだ2月のままかよ。早く10月になーれ。
http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm
>> >Name プロパティを持つものを集めてきて表示しています。
>> ↑と言うと,お題とはちょっと違う内容と思っていいのでしょうか?
はい。
動作は確認しています。
WMI/WBEM の使い方のサンプルが
あったほうがいいかと思いましたので。
(説明なしですが、その前の ASP の例を
VC++ 化したという流れでした。)
>> Microsoft Platform SDK February 2003にもちゃんと入っていました。
よかったですね。
なるみさんも早くここチェックしてほしいなっと。
体調不良でレスができませんでした。知らない間にたくさんの情報提供があり、感謝しております。なーめさんどうもありがとうございました。
編集 削除