<head>
<title>WMI オブジェクト調べ - HTA</title>
<!--<object classid="clsid:76A64158-CB41-11D1-8B02-00600806D9B6" id="SWbemLocator"></object>-->
<script type="text/javascript">
// 最後に、少しメモあり。

var SWbemServices
//var SWbemServices = SWbemLocator.connectserver() //上のobjectタグでなら
//var SWbemServices = new ActiveXObject("WbemScripting.SWbemLocator").connectserver()
//var SWbemServices = GetObject("winmgmts:") //
//var SWbemServices = GetObject("winmgmts:root\\default") //
function サービスの取得(){ // 入力欄を使って
      try{  SWbemServices = GetObject(text2.value) }catch(e){ alert(e.description); return }
      text2P.style.display='none';  return true;
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 左面の初期表示
var 設_階層化, 通_深度, 通_パス配, 通_深配, 通_階別配
function パス配作り(objSet, 標){
      if( ! objSet.Count) return;
      var 集 = new Enumerator(objSet), 配 = (通_階別配[通_深度] =[])
      for(; ! 集.atEnd(); 集.moveNext()) 配.push( 集.item() )
      for(var i=0, 副級;  i< 配.length;  i++){
            配.現番 = i;
            if(設_階層化) for(var j=0; j< 通_深度; j++)
                  for(var k=(通_階別配[j].現番+1);  k< 通_階別配[j].length;  k++)
                        if( 配[i].CompareTo_(通_階別配[j][k]) ){ 通_階別配[j].splice(k,1); break }
                        //if( 配[i].Path_.Path==通_階別配[j][k].Path_.Path ){ 通_階別配[j].splice(k,1); break }// 同じく遅い
            通_深配.push(通_深度);
            通_パス配.push( 配[i].Path_.RelPath ); //通_パス配.push( 配[i].Path_.Path );
            if(設_階層化 && (副級= 配[i].Subclasses_()).Count ){
                  通_深度++;  パス配作り(副級);  通_深度--;  }//
      }///
}///
function 左面の表示(){
      if(!SWbemServices){ if(!サービスの取得())return }
      通_深度 = 0, 通_パス配 =[], 通_深配 =[], 通_階別配 =[]
      var objSet = SWbemServices.SubclassesOf()
      パス配作り(objSet);  通_階別配= null;
      var str =''
      for(var i=0, 差, esc; i< 通_パス配.length; i++){
            差 = 通_深配[i] - 通_深配[i+1] // 次は?
            esc = 通_パス配[i].replace(/\\/g,'\\\\').replace(/\x22/g,'\\x22')
            str += '<div id="">' + (差 < 0 ? '<b class="dispbtn" onclick="下位の表示('+i+')">+</b>': '<b>&nbsp;</b>')
                  + '<span onclick="詳細を表示(\''+ esc +'\')" class="namebtn">'
                  + 通_パス配[i].replace(/^.*?:/,'') +'</span></div>'
            if(差 < 0)str += '<div class="L'+ 通_深配[i+1] +'" id="sub'+i+'" style="display:none;">'
            else if(差 > 0) for(var j=0; j< 差; j++) str += '</div>'
      }///
      通_パス配= 通_深配= null
      if(設_階層化) str = '<div style="text-align:right;"><span class="zkbtn" onclick="全開に()">全開</span></div>'+ str;
      document.getElementById('dispL').innerHTML = str
}///
function 下位の表示(番){ var ele = document.getElementById('sub'+番)
      ele.style.display = (ele.style.display ? '': 'none')  }//
function 全開に(){
      var 集 = document.getElementById('dispL').getElementsByTagName('div')
      for(var i=0; i< 集.length; i++)
            if(/^sub/.test(集[i].id)) 集[i].style.display = (憶_全開 ? 'none': '')
      憶_全開 = (憶_全開 ? 0 : 1)
}var 憶_全開;//
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 調査と表示
function 詳細を作文(obj, 再){
      var プロパ又メソ = function(objSet, 標){
            if( ! objSet.Count) return;
            var str ='', item, 集 = new Enumerator(objSet)
            for(; ! 集.atEnd(); 集.moveNext()){ item = 集.item()
                  str += '<span class='+ (標=='m' ? '"MName">': '"PName">') + item.Name +'</span>'
                        //+( 標=='p' && ! obj.Path_.IsClass ?  ' :  '+ item.Value: '' ) +'<br>'// 下のテストの為
                  if(標=='p' && ! obj.Path_.IsClass){
                        if(item.Value+'') str += ' :  '+ item.Value
                        else try{ str += ' :  '+ item.Value.toArray().join(', ') }catch(e){}// テスト、多分ない、無用か、
                  }str += '<br>'
                  if(標=='m'){  str += '<div class="margin">'
                        + '<div>InParameters' + ( item.InParameters ?
                              '</div>'+ 詳細を作文(item.InParameters, '再'): ' 、- </div>')
                        + '<div>OutParameters' + ( item.OutParameters ?
                              '</div>'+ 詳細を作文(item.OutParameters, '再'): ' 、- </div>')
                        + '</div>'  }///
            }return str
      }///
      var str ='', s, n;
      if(!再)str += '<div><b>'+ obj.Path_.RelPath +'</b>'
            + (obj.Path_.IsClass ? '  、IsClass':'')
            + (obj.Path_.IsSingleton ? '  、IsSingleton':'') +''
            + '<br>'+ obj.Path_.Path +'</div>'
      str += '<div class="margin">'//最後に閉じ
            + '<div class="moku'+ (再? 'M':'')+ '">Properties_ &nbsp;'+ (n= obj.Properties_.Count) +'</div>'
            + (n ? '<div class="margin">'+ プロパ又メソ(obj.Properties_, 'p') +'</div>': '')
      if(!再){  str += '<div class="moku'+ (再? 'M':'')+ '">Methods_ &nbsp;'+ (n= obj.Methods_.Count) +'</div>'
                  + (n ? '<div class="margin">'+ プロパ又メソ(obj.Methods_, 'm') +'</div>': '')  }///
      if(s= obj.Derivation_)str += '<div>Derivation</div><div class="margin">'+ s +'</div>'
      s = obj.GetObjectText_()
      if(s)str += '<div class="moku'+ (再? 'M':'')+ '">ObjectText</div><div class="margin">'
            + s.replace(/\t(.*?\])(.*)?\n/g,'<div class="indentR">$1<br>$2</div>').replace(/\n/g,'<br>\n')
            +'</div>'
      str += '</div>'//class="margin"の閉じ
      return str
}/////
function 副リスト表示(objSet){
      if( ! objSet.Count){ alert('なし'); return; }
      var str ='総数、'+ objSet.Count +'<br>\n';
      var 集 = new Enumerator(objSet);
      for(; ! 集.atEnd(); 集.moveNext()){
            str += '<div class="indentR"><span class="namebtnR" onclick="詳細を表示(\''
                  //+ 集.item().Path_.Path.replace(/\\/g,'\\\\').replace(/\x22/g,'\\x22') +'\', -1)">'
                  + 集.item().Path_.RelPath.replace(/\\/g,'\\\\').replace(/\x22/g,'\\x22') +'\', -1)">'
                  + 集.item().Path_.RelPath +'</span>'
                  + ( 集.item().Name ?  ' 、'+ 集.item().Name: '' )
                  + '</div>\n'  }///
      return str
}///
function 詳細を表示(path, 標){
      if(!標 || 標<0)document.getElementById('text1').value = path;
      if(!SWbemServices){ if(!サービスの取得())return  }
      var str, obj;
      try{ obj = SWbemServices.Get(path) }catch(e){ alert(e.description); return }
      if(標==2) str = 副リスト表示( obj.Subclasses_() )
      else if(標==3) str = 副リスト表示( obj.Instances_() )
      else str = 詳細を作文( obj )
      if( !str )return
      if(標 >1) document.getElementById('dispR2').innerHTML = ''+ str +''// 副リスト表示の時
      else document.getElementById('dispR1').innerHTML = ''+ str +''
      面切換え(標)
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
function 面切換え(要素){
      var 集 = document.getElementById('dispRTabs').getElementsByTagName('span')
      if(!要素 || typeof(要素)=='number'){ if(要素 >1)要素 = 集[1]; else 要素 = 集[0]; }
      if(要素.className=='tabbtnF')return;
      for(var i=0; i<集.length; i++)
            if(集[i]==要素){ 集[i].className = 'tabbtnF'
                  document.getElementById('dispR'+(i+1)).className = 'front' }
            else{ 集[i].className = 'tabbtn'
                  document.getElementById('dispR'+(i+1)).className = 'back' }
}///
function 指示イベント処理(){
      var ele = event.srcElement
      if( /btn/.test(ele.className) ){
            if(event.type=='mouseover'){ ele.style.color = 'window'
                  ele.style.backgroundColor = 'windowtext' }
            else ele.style.color = ele.style.backgroundColor = ''  }///
}///
onload = function(){  onload = null;
      document.onmouseover = document.onmouseout = 指示イベント処理
}///
</script>
<!--・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・-->
<style type="text/css">
body{ margin:0; overflow:hidden;
      background-color:window; color:windowtext; }
#ctrl0{ padding:0.5em; }
.inputText{ font-weight:bolder; font-family:monospace; }
/* 各面(レイヤー) */
#dispL, #dispR{ /* 左面、右面 */
      position:absolute; top:expression(disp0.offsetTop);
      height:expression(document.body.offsetHeight-disp0.offsetTop-3); }/*  */
#dispL{ width:35%; overflow:scroll; padding:0.5em; padding-top:0; }/* 左面 */
#dispR{ left:35%; width:65%; }/* 右面 */
.front, .back{ /* 右面中の前後面 */
      overflow:auto; padding:0.5em; padding-top:0;
      position:absolute; background-color:window; z-index:0;
      top:expression(dispRTabs.offsetTop+dispRTabs.offsetHeight);
      width:100%; height:expression(dispR.offsetHeight-dispRTabs.offsetHeight);/* -5 */
      }
.front{ z-index: 1; }
/* ボタン類 */
.namebtn{ cursor:pointer; }/* 左面のクラス名の部分 */
.dispbtn{ cursor:pointer; }/* 左面の + 節の表示ボタン */
.namebtnR{ cursor:pointer; font-weight:bolder; }/* 右面のリスト中のボタン */
.tabbtn{ cursor:pointer; }/* 右面前後の切換えボタン */
.tabbtnF{ background-color:windowtext; color:window;  }/* 〃 (現) */
.btn{  font-weight:bolder; font-size:smaller; white-space:nowrap; /* 3Dボタン */
      border-style:outset;  border-color:threedlightshadow; cursor:pointer;  }
/* 各面中の部分 */
.L1,.L2,.L3,.L4,.L5,.L6{ margin-left:1em; }/* 左面の表示階層 */
.margin{ margin-left:1em; }/* 右面の表示の字下げ */
.indentR{ margin-left:2em; text-indent:-1em; }/* 右面の表示の字下げ */
.moku{ margin-top:1em; font-weight:bolder; }/* 右面の表示中の項目見出し部分 */
.mokuM{  }/* 〃 、メソッドの項中のそれ */
.MName{ font-weight:bolder; }/* 右面の表示中のメソッド名 */
.PName{  }/* 右面の表示中のプロパティー名 */
</style>
<!--・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・-->
</head><body>
<div id="ctrl0">
      パス <input type="text" id="text1" size="50" class="inputText">
      <span class="btn" onclick="詳細を表示(text1.value, 1)" title="SWbemServices.Get(パス)">自身</span>
      <span class="btn" onclick="詳細を表示(text1.value, 2)" title="SWbemServices.Get(パス).Subclasses_()">サブクラス</span>
      <span class="btn" onclick="詳細を表示(text1.value, 3)" title="SWbemServices.Get(パス).Instances_()">インスタンス</span>
      <!--<span class="btn" onclick="xxx(text1.value)" title="">...</span>-->
</div>
<div id="disp0">
      <div id="dispL">
            <div style="line-height:1.6">
                  <div id="text2P"><small>GetObject</small><br>
                        <input type="text" id="text2" size="25" class="inputText" value="winmgmts:"></div><br>
                  <span onclick="this.onclick=null; 左面の表示();" class="btn" >全?クラス群の表示</span><br>
                  <span onclick="this.onclick=null; 設_階層化=true; 左面の表示();" class="btn" > 〃 、階層で 表示</span>
                  <br> ↑ <small>20〜30秒 かかる...</small>
            </div>
      </div>
      <div id="dispR">
            <div id="dispRTabs" class="" style="text-align:right;">
                  <span onclick="面切換え(this)" class="tabbtnF" title="クラスかインスタンスの詳細">[1]</span>
                  <span onclick="面切換え(this)" class="tabbtn" title="サブクラスかインスタンスのリスト">[2]</span>
            </div>
            <div id="dispR1" class="front"></div>
            <div id="dispR2" class="back"></div> <div id="dispR3" class="back"></div>
      </div>
</div>
<!--・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・-->
<!--
      File や Directory の付くクラスのインスタンス集を取ろうとすると、固まってしまう様。
      Instances_() まではいいけど、.Instances_().Count とするとだめ?。
      SWbemServices.Get('クラス.Name="C:\\\\tmp"') とか特定するのは大丈夫。
            Win32_LogicalDiskRootDirectory とか数が限られているのも大丈夫。
     
      その時の強制終了は、これでなく、Winmgmt (WMI)自体を
            終了させないと、だめかも知れない。
     
      右面の結果表示を、コピーすると、字下げが消えてしまう。margin で指定しているだけなので。
            書いてる時は、そこまで気付かなかったが、不便。(クエリ・テスト.hta の方は維持されるようにしたが)
-->