ネットワークアダプタを無効に

解決


なるみ  2003-12-05 20:12:25  No: 52757

現在ある状態になったら、ネットワークを停止(ネットワークアダプタの無効化)するプログラムを作成中なのですが、やり方が分かりません。どなたかご存じの方がいらっしゃいましたら、宜しくお願い致します。
WMIとかで可能のようなのですが、具台的な内容が分かりませんでした。
【環境】
 使用OS   : Windows98,2000,XP
 使用言語 : VC++ 6.0 or VB


なーめ  2003-12-06 05:42:39  No: 52758

VC++でWMIをするなら WMISDK が必要でしょうね。
HELP の MSDN ライブラリにあったMSサイトへのリンクは切れてました。
サブスクリプションしてるなら、

Microsoft Platform SDK - November 2001 Edition
English Disk 0004-4 February 2002

に入ってましたが.....


なーめ  2003-12-07 01:31:29  No: 52759

訂正
>>サブスクリプション
サブスクライブ


なるみ  2003-12-08 18:34:12  No: 52760

なーめさん、有り難う御座います。
早速探してみます。


なーめ  2003-12-09 04:56:45  No: 52761

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-09 16:56:47  No: 52762

[なーめ 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();
}


sh  2003-12-09 19:14:05  No: 52763

同様にVC6.0 or VB6.0でネットワークアダプターを無効にしたく参考にさせていただいたのですが,CoCreateInstanceでどうしても失敗してしまいます。なにかOCXをインストールしておかなければいけないのでしょうか?

開発環境は下記で行っております。

W2K 
Visual Stadio6.0 
Microsoft Platform SDK February 2003


ボコノン教徒  2003-12-10 00:20:27  No: 52764

CoInitializeEx()を事前にCallする、とか。エラーの戻りは何?

なーめさんのサンプルは、アダプタ名を列記するサンプルみたい。
アダプタの設定はどうやるんだ。俺も知りたい。
「Networking Device Classes」あたりがあやしそうだが、そもそもC++から
メソッドを呼び出す方法がわからん。


なーめ  2003-12-10 09:34:38  No: 52765

>> なにか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 されていないだけかもしれない。(^^;;


なーめ  2003-12-10 15:39:29  No: 52766

>> 「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:「うべむ」「うーべん」
だめですかね。


sh  2003-12-10 18:33:23  No: 52767

なーめさん>
丁寧なご回答ありがとうございます。
すみません。単純にCOMの初期化が行われていなかったために
失敗していました。
"::CoInitialize(0);"の追記でエラーなく動作しました。

>Name プロパティを持つものを集めてきて表示しています。
↑と言うと,お題とはちょっと違う内容と思っていいのでしょうか?

一応,WMIもMicrosoftからDLしたのですが,よくよく見ると
Microsoft Platform SDK February 2003にもちゃんと入っていました。


ボコノン教徒  2003-12-10 18:44:02  No: 52768

> Microsoft Platform SDK February 2003にもちゃんと入っていました。

サンプルとしては  Samples\sysmgmt\WMI\VC\SimpleClient
が一番簡単そうなので、この辺から少しずつ攻めて行ってる状態です。
インクルードのパスがおかしいぞ。
他のサンプルを見るとメソッドの呼び出しもやってるみたい。
まあ、ぼちぼちいってみます。

以下念のため。まだ2月のままかよ。早く10月になーれ。

http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm


なーめ  2003-12-10 21:25:32  No: 52769

>>  >Name プロパティを持つものを集めてきて表示しています。
>>  ↑と言うと,お題とはちょっと違う内容と思っていいのでしょうか?

はい。
動作は確認しています。
WMI/WBEM の使い方のサンプルが
あったほうがいいかと思いましたので。
(説明なしですが、その前の ASP の例を 
  VC++ 化したという流れでした。)
>> Microsoft Platform SDK February 2003にもちゃんと入っていました。
よかったですね。
なるみさんも早くここチェックしてほしいなっと。


なるみ  2003-12-10 22:20:54  No: 52770

体調不良でレスができませんでした。知らない間にたくさんの情報提供があり、感謝しております。なーめさんどうもありがとうございました。


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








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