シーズー大好き さん (null) 2005年 04月 12日 11時 04分 22秒
URL:null

はじめまして。
現在複数あるWindows2000サーバの監視ツールをVBSで作成しております。
プロセス、SQL Serverの監視に関する方法を検索していたところ、
この掲示板に出会いました。私から質問させて頂いて宜しいでしょうか。

javaw.exeというプロセスが8つ起動しているか監視する方法を模索しています。タスクマネージャのアプリケーションウィンドウに8個のプログラムが常駐していることを確認したいのですが、これらはJAVAコンソールなので、プロセスウィンドウにjavaw.exeという名前で表示されます。

任意のプロセスの稼働状況を取得する方法は以前の投稿記事から学ばせて
頂いたのですが、同じプロセスが一定個数稼動しているかを取得するには
どのようにすればいいのでしょうか?

ばんのしゃーによかばんた さん 2005年 04月 11日 15時 18分 13秒

File/Folderを一つの関数にするメリットはあまりなさそうだし、
使われ方を考えると、別のほうがよさそう。

そこで、フォルダロック関数です。
先のファイルロック関数の"File"を"Folder"に全置換しただけのような。:-p

Function GetFolderLock(Folder)は、
Folderのロックに成功するとテンポラリフォルダ名を返し、
失敗するとEmptyを返します。

a.vbs
――――――――――――――――――――――――――――――――――――――
Dim fso
Dim k
On Error Resume Next
Main
WScript.Echo k

Sub Main
Set fso=CreateObject("Scripting.FileSystemObject")
temp="temp.dir"
For k=0 To 100
If fso.FolderExists(temp) Then
 Folder=GetFolderLock(temp)
 If Folder<>"" Then
  fso.DeleteFolder Folder
  d=d+1
 End If
Else
On Error Resume Next
 fso.CreateFolder temp
On Error GoTo 0
 c=c+1
End If
Next
End Sub

Function GetFolderLock(Folder)
Dim Name
Name=Left(File,InStrRev(Folder,"\"))&fso.GetTempName()
On Error Resume Next
fso.MoveFolder Folder,Name
If Err.Number Then Exit Function
WScript.Sleep 10
If fso.FolderExists(Name) Then GetFolderLock=Name
End Function
――――――――――――――――――――――――――――――――――――――
b.vbs こっちを起動
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
For k=1 To 2
wShell.Run "a.vbs"
Next
――――――――――――――――――――――――――――――――――――――
Emptyの、
 If Not IsEmpty(Folder) Then
は、
 If Folder<>"" Then
と書けます。愛い奴。:-)

一方、Nullは曲者ですね。
 x=Null
 If x="" Then
 If x<>"" Then
はどちらもElseになります。知らないと苦労します。(しました。:-<)

TempNameを使っているのは、以下を考慮してます。
簡単に連想できる名前は誤ってユーザに使われるリスクを増やす。
ネットワーク環境では、長い名前や英大文字数字以外はなるべく避ける。
トラブル予防。

Cなどコンパイラ言語の場合は、関数はブラックボックスなので、
丁寧なパラメータチェックやエラーハンドリングが必要ですが、
スクリプトの関数はホワイトボックスなので、
関数の中でエラーになれば、なったでデバッグ可能なので、
パラメータチェックやエラーハンドリングなしで済ませることが出来て、
スクリプトはよい哉。


ばんのしゃーによかばんた さん 2005年 04月 11日 15時 17分 46秒

パイプで思い出しましたが、An HTTPDの件。

>管理人むたぐち さん 2004年 11月 16日 14時 34分 23秒
>いえ、さすがにそこまで融通の利かない実装はされてないでしょう。
>つまり、まず#!の行を読み取って、その次の行からをcscriptに渡している、はずです…。
>つまり、#!行の読み込みはうまくいってるものの、次行からの内容をcscriptに渡す際、
>何らかの不具合が生じており、その結果、
>「Windows Script Host の実行に失敗しました。 (この操作を完了するのに十分な記憶域がありません。 ) 」
>というエラーが出るのだと思われます。

これは、当たりですね。

>ばんのしゃーによかばんた さん 2004年 12月 16日 19時 20分 37秒
>同じメッセージに遭遇しました。
>cscript -e:vbs con

つまり、An HTTPDはnamed pipeを使って2行目以降のスクリプトを渡しているのでしょう。
\\.\pipe\name

ところが、WSHはスクリプトファイルにnamed pipeを許してないか(仕様)、想定してないか(バグ)。

>管理人むたぐち さん 2004年 12月 11日 23時 29分 19秒
>となると、VBS on WSHがダメだった理由は、やっぱりWSHに由来する
>何らかの問題があるんだと思われます。
>さて、どこに報告すればいいのかな?

MSに言っても、たぶん仕様通りと言うでしょうし。
考えにくいですが、たとえ、障害と認めても、修正がいつになることやら。

An HTTPDに言ったほうが、対応が早いかも。
WSHが読めないからnamed pipeをやめて一時ファイルに変えてくれ、て。

でも、やはり、この実装は筋が悪かったんだと思いますよ。

>ばんのしゃーによかばんた さん 2004年 11月 17日 20時 11分 25秒
>OSにこういう機能がない、Windowsの場合、アプリ側、AnHTTPDで代行します。
>そのとき、本家と異なる実装をするとは、考えにくいです。

本家の実装であれば、こういうトラブルも起きず、筋が良かったと思いますね。

筋の良し悪しというのはなかなか論理的に説明しにくいのですが、
ソフトウェアの基本設計で最も重要なことだと思っています。
硬く言うと、将来の諸々(想定外)のリスクの評価なんてところでしょうが、
さすがに、想定外なので、難しい。
なので、基本設計書には、筋の良し悪しなんて表立って書けないので、
裏設計書(添付検討資料)でいろんな評価尺度の形を借りて比較検討してました。

こういう話(筋の良し悪しの検討)は今まで見聞したことがないのですが、
博識のいりやさんは、そういう記事や文献をご存知ではないでしょうか?
もし、あったら紹介をお願いします。


ばんのしゃーによかばんた さん 2005年 04月 11日 15時 17分 09秒

>ばんのしゃーによかばんた さん 2005年 04月 01日 12時 29分 51秒
>これを見て、思い付いたのですが、贋物のパイプが作れますね。
>しかもこのパイプは分岐もできます。

パイプで思い出しましたが、

Command.comの擬似パイプは、
 C:\Windows\Temp\ABCDEFGH
のような名前ですが、

CMD.EXEが16ビットアプリを相手にするときの擬似パイプは、
 C:\Windows\Temp\scs14B7.tmp
のような名前です。

もし、この擬似パイプのファイル名が、なんらかの方法で、分かれば、
 Echo スクリプト | Command.com /cCScript.EXE -E:VBS C:\Windows\Temp\scs14B7.tmp
みたいなことが出来るかも知れません。


ばんのしゃーによかばんた さん 2005年 04月 11日 15時 16分 39秒

>管理人むたぐち さん 2005年 04月 10日 07時 59分 10秒
>PDF Writer あるいはPDF Distillerですね。

Distiller?

PDF「蒸留酒製造業者/蒸留器」?なんのこっちゃ?ですね。

TV CMでよく耳にする「京都郊外(*1)サントリー山崎ディスティラリ」のdistilleryですね。

(*1)
実際には、京都府乙訓郡大山崎町ではなく、大阪府三島郡島本町字山崎にあるのに。。。
「大阪郊外」では名水のイメージが湧かないもんね。でも地元の両町に失礼なのでは?
因みに、阪急大山崎駅は京都側、JR山崎駅は大阪側か府境線上。

脱線ついでに、大山崎町民はこの名水を享受しているのか、と思いきや、町は上水需要予測を
過大に誤り、府営水道を導入して、山(天王山)の向こうの遥か遠く(つまり高い)の貯水池
(つまり不味い)の水を飲んでるらしい。美味い名水を享受しているのは、爆発的ヒットの
ペット茶の愛飲者で、安い名水を享受しているのは、そのメーカだけ。嗚呼、可哀相な町民。

話を戻して、印刷プレビューの代替として、
PostScriptプリンタのドライバを使って、ファイルに出して、GS(GhostScript)Viewで見る。
という方法もあります。

また、別の方法として、
デフォルトのPREVIEW.DLGを(手直しして)呼び出すというのはどうでしょう。
res://shdoclc.dll/preview.dlg
フィージビリティは不明ですが、面白そうなテーマではないでしょうか。


ばんのしゃーによかばんた さん 2005年 04月 11日 15時 16分 00秒

HTAの印刷プレビュー機能実装のサンプルです。

printpreview.hta
――――――――――――――――――――――――――――――――――――――
<html>
<script language=vbscript>
Dim ie
Sub preview()
Set win=open
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows
If TypeName(ie.document)="HTMLDocument" Then
  If TypeName(ie.document.parentWindow.opener)="HTMLWindow2" Then
   If ie.document.parentWindow.opener Is window Then Exit For
  End If
End If
Next
ie.Visible=False
win.document.open
win.document.write document.documentElement.outerHTML
win.document.close
ie.ExecWB 7,1
setTimeout "PreviewEnd",1000
End Sub

Sub PreviewEnd()
If ie.Busy Then
 setTimeout "PreviewEnd",1000
Else
 ie.Quit
End If
End Sub
</script>
<body>
<button onclick=preview>preview</button>
aaaaaaaa
</body>
</html>
――――――――――――――――――――――――――――――――――――――
ここで、ie.Visible=Falseがないと、
win.document.writeでマイコンピュータゾーンのロックダウンダイアログが出て、
そのあとのie.ExecWBでプレビュー画面が出て、先にプレビュー画面をクローズすると、
ie.ExecWBがエラーになります。
そこで、ie.Visible=Falseしておくと、ロックダウンダイアログが出ません。


つちや さん 2005年 04月 11日 14時 56分 46秒

 唐突ですが、スクリプトエンコーダ作ってみました。スクリプトをD&Dすると実行ファイルを一つ作ります。スクリプトは実は暗号化されて実行ファイルにくっついているだけです。
 その実行ファイルは、実行の際にスクリプトを復号してファイルに書き出して実行します。スクリプトは実行後に削除します(よって、もとのスクリプトが同じフォルダにあったりすると上書きして削除しますので要注意)。
ファイル -> http://kajika.tk/fio/?%A5%C0%A5%A6%A5%F3%A5%ED%A1%BC%A5%C9
コメント -> http://d.hatena.ne.jp/Fio/20050411
 試しにちょっと作ってみただけ、という代物です。珍しいことが好きな人向け。

ばんのしゃーによかばんた さん 2005年 04月 10日 15時 51分 55秒

HTAのHTMLWindow2オブジェクトを外部(WSH)から参照できるようにする方法。

HTAからwindow.openする。

open.hta
――――――――――――――――――――――――――――――――――――――
<html>
<script language=vbscript>
Sub window_onload()
open
End Sub
</script>
</html>
――――――――――――――――――――――――――――――――――――――
外部(WSH)からHTAのHTMLWindow2オブジェクトを参照する方法。

Shell.Windows()から、上記windowのopenerを参照する。

opener.vbs
――――――――――――――――――――――――――――――――――――――
Set Shell=CreateObject("Shell.Application")
ReDim Rows(Shell.Windows.Count)
Rows(0)=Array("#","LocationURL","opener")
For Each ie In Shell.Windows
 k=k+1
 If TypeName(ie.document.parentWindow.opener)="HTMLWindow2" Then
  opener=ie.document.parentWindow.opener.location
  ie.document.parentWindow.opener.document.title="change!"
 Else
  opener=TypeName(ie.document.parentWindow.opener)
 End If
 Rows(k)=Array(k,ie.LocationURL,opener)
Next
For k=0 To UBound(Rows)
 Rows(k)=Join(Rows(k),vbTab)
Next
WScript.Echo Join(Rows,vbCrLf)
WScript.Quit
――――――――――――――――――――――――――――――――――――――
この例(WSH)ではHTAのタイトルを変更します。


ばんのしゃーによかばんた さん 2005年 04月 10日 15時 51分 31秒

HTMやHTAで使えるSleep代替関数。HTMで使えるQuit代替関数。
――――――――――――――――――――――――――――――――――――――
<html>
<script language=vbscript>

Sub window_onload()
Sleep 5000
Quit
End Sub

Sub Sleep(millisecond)
Set wShell=CreateObject("WScript.Shell")
wShell.Run "MSHTA.EXE ""javascript:void(setTimeout('close();',"&millisecond&"));""",0,True
End Sub

Sub Quit()
document.body.insertAdjacentHTML "beforeEnd","<"&"object id=""WB"" classid=""clsid:8856F961-340A-11D0-A96B-00C04FD705A2""><"&"/object>"
WB.ExecWB 45,0
WB.outerHTML=""
End Sub

</script>
</html>
――――――――――――――――――――――――――――――――――――――


管理人むたぐち さん 2005年 04月 10日 07時 59分 10秒

To: SIGNAL9 さん

> …誠に申し訳ないです。公私共にもうDoodle2に割ける時間が確保できませんです。

いえいえ、こちらこそ無理なお願いで申し訳ありませんでした。
でもDoodle2は非常に便利で結構遊べるので、重宝してます。感謝です。


To: hidebou さん

はじめまして。サイトを拝見させていただきました。
JScriptで自動的にHTMLを生成するんですね。ズボラな人(私とか)には便利そうかも。
ブログ構築用のPerlスクリプト、blosxomとちょっと似てるかなーと思いました。
http://www.blosxom.org/


To: ばんのしゃーによかばんた さん 2005年 04月 05日 14時 05分 18秒

> 例えば、Adobe Acrobatに付属する、PDFなんとか(?忘れた)とか。

PDF Writer あるいはPDF Distillerですね。


To: もぐもぐたん さん

> 今、ファイルFTP後に、正しくファイルがFTPされたかどうか確認し、もし、
> されていなかった場合、再送する処理を作成しています。
> そこで、送信元のファイルと送信先のファイルのサイズを比較し、一致するか
> どうか確認する処理を考えているのですが、リモート上のファイルのサイズを
> 取得できなく、悩んでいるしだいです。

WshShell.ExecでFTPを実行し、その出力結果をWshScriptExecオブジェクトの
StdOutメソッドで拾えばいいのではないでしょうか?

ばんのしゃーによかばんた さん 2005年 04月 09日 17時 01分 02秒

>ばんのしゃーによかばんた さん 2005年 04月 05日 14時 05分 18秒
>>むちゃ さん 2005年 03月 07日 13時 58分 48秒
>>> >実は、HTA(*.hta)で ExecWB メソッドを使用したいと思いまして・・・
>>> document.execCommand()で代替出来ませんか?
>>execCommand メソッドではだめなようです。
>>印刷関連(特に印刷プレビュー)の識別子がないので;;
>HTAのメモリ中のHTMLソースを、IEを起こして、その中に直接書き込む、
>または、一時ファイル.HTMに書き出して、IEで印刷プレビューする、
>というのはどうでしょう?再現性があまりよくないかな。

どうも、この振る舞いは理解を超えています。

hoge.VBSから、
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.Navigate "about:blank"
Do While ie.Busy Or ie.ReadyState<>4
 WScript.Sleep 100
Loop
ie.Document.write "<script>alert(1);</script>"

なんてやっても、インターネットゾーンのままです。理解し易い仕様です。

ところが、これがhoge.HTM/hoge.HTAから、
<html>
<script language="vbscript">
<!--
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.Navigate "about:blank"
Do While ie.Busy Or ie.ReadyState<>4
Loop
ie.Document.write "<script>alert(1);</script>"
'-->
</script>
</html>
だと、マイコンピュータゾーンになります。
しかも、名前を付けて保存すると、その中身はhoge.HTMです。
なんで? マジックのようです。らしい情報を何も渡してないのに。
裏で実行環境の情報を拾って渡しているようです。

こういうのって、プログラムアーキ的に、なんか筋が悪そうな感じがします。
筋の悪い設計は後々、トラブルの尾を引くことになりますが、大丈夫?>MS

これを応用すると、
今まで、ローカルにテンポラリにでも、いちいち.HTMファイルを作らないと
マイコンピュータゾーンにはなれないと思っていたのは誤解で、
ローカルファイルを作ることなく、ie.Document.writeで
マイコンピュータゾーンになれますね。


あさじゃけん さん 2005年 04月 09日 16時 14分 08秒

■ちゃっぴさんへ
エラーがでなくなるだけで、根本的な解決にはならないと思うのですが・・・やってみました。
'==================================================
Test1
Name: DOMAINNET
Test2
Name: MAINPC
Test3
Name: SUBPC
Test3
End
'==================================================
やっぱり、スクリプトで異常発生しても処理を続けて、最後のEndが表示されるようになっただけですね。
Windows2000にはIADsResourceが実装されていないってことなのかな?汗

マイクロソフトのサイト内を検索してみたのですが、そういう記述を見つけられませんでした・・・(><

で、バージョンの問題なのかと思い、
http://www.microsoft.com/japan/technet/scriptcenter/scrptfaq.mspx
のスクリプトでバージョンを吸出しましたので、ここに出しておきます。
WSH Version: 5.6
VBScript Version: 5.6
WMI Version: 1085.0005
ADSI Version: 5,0,00,0
※もちろんOSはWindows2000です。

多分、最新だと思います(汗

ちゃっぴ さん 2005年 04月 08日 01時 30分 33秒

To あさじゃけん さん 2005年 04月 07日 23時 33分 17秒

> C:\test\test.vbs(39, 6) Active Directory: Active Directory
> プロパティがキャッシュに見つかりません。

そのErrorは発生しないのですが・・・
小手先ですが、On Error Resume Next をかましてみるとどうなります?

Remoteに呼び出しにいく場合、
「指定したFileが見つかりません」
というErrorは発生することがありますので・・・

あさじゃけん さん 2005年 04月 07日 23時 33分 17秒

またまた、お返事が遅くなってしまいました(汗

■ばんのしゃーによかばんたさんへ
GetFileLockをFolderにも対応するように自分なりに新規で作ってみました。

'==================================================
'ファイル及びフォルダをロックする。(移動)
'ロックできた場合はファイル名を返す。
'ロックできなかった場合はNULL文字を返す。
'※必ずフルパス指定する必要がある。
'※ドライブはロックできない。
'Memo
'Moveするまでに以下のようにObjectを取得しようとすると、
'排他で取得できない可能性があるので使えない。
'Set objTarget = objFso.GetFolder(strTargetName) 'ダメ
'Set objTarget = objFso.GetFile(strTargetName) 'ダメ
'objTarget.Move(strRetTmpName) 'ダメ
'そのため、文字列を直接判断する必要がある。
'==================================================
Function GetFileLock(strTargetName)
  Dim strRetTmpName

     Dim blnExecCheckFlg
     Dim blnFolderFlg
     Dim varRetInStr

     Dim strTargetYenCutName

     Dim strParentFolderPath
     Dim strName

     Dim lngCount

  strRetTmpName = ""
     strTargetYenCutName = ""
     strParentFolderPath = ""
     strName = ""

     blnExecCheckFlg = False
     blnFolderFlg = False

     'パラメータチェック
     If IsNull(strTargetName) = False Then
          If strTargetName <> "" Then
               If Right(strTargetName,1) = "\" Then
                    '最後の\マークを削除する。
                    strTargetYenCutName = Left(strTargetName,Len(strTargetName) - 1)
               Else
                    strTargetYenCutName = strTargetName
               End If

               varRetInStr = InStr(strTargetYenCutName,":") 'NULLはかえってこないはず。
               If varRetInStr = 0 Then
                    'ドライブ指定なし
                    If Left(strTargetYenCutName,2) = "\\" Then
                         'ネットワーク共有フォルダ指定
                         If objFso.FolderExists(strTargetYenCutName) Then
                              'フォルダとして存在する。
                              blnExecCheckFlg = True
                              blnFolderFlg = True
                         ElseIf objFso.FileExists(strTargetYenCutName) Then
                              'ファイルとして存在する。
                              blnExecCheckFlg = True
                              blnFolderFlg = False
                         Else
                              'ファイルもフォルダもない。
                              '処理なし
                              blnExecCheckFlg = False
                         End If
                    Else
                         'カレントフォルダからの相対指定
                         '処理なし
                         'ロック先が明確でない。
                         blnExecCheckFlg = False
                    End If
               Else
                    'ドライブ指定あり
                    If Len(strTargetYenCutName) <= 2 Then
                         'ドライブのみ
                         '処理なし
                         'ドライブはロックできません。
                         blnExecCheckFlg = False
                    Else
                         'ドライブ+フォルダあり
                         If objFso.FolderExists(strTargetYenCutName) Then
                              'フォルダとして存在する。
                              blnExecCheckFlg = True
                              blnFolderFlg = True
                         ElseIf objFso.FileExists(strTargetYenCutName) Then
                              'ファイルとして存在する。
                              blnExecCheckFlg = True
                              blnFolderFlg = False
                         Else
                              'ファイルもフォルダもない。
                              '処理なし
                              blnExecCheckFlg = False
                         End If
                    End If
               End If
          End If
     End If

     '処理が可能なら
     If blnExecCheckFlg = True Then
          strParentFolderPath = Left(strTargetYenCutName,InStrRev(strTargetYenCutName,"\") - 1)
          strName = Mid(strTargetYenCutName,InStrRev(strTargetYenCutName,"\") + 1)

          '実在しないテンポラリー名を作成する。
          Randomize
          lngCount = 0
          Do
'               strRetTmpName = objTarget.ParentFolder.Path & "\" & objFso.GetTempName()
'               strRetTmpName = objTarget.ParentFolder.Path & "\tmp" & CStr(lngCount) & "_[" & objTarget.Name & "]_" & CStr(CLng(99999 * Rnd) + 100000)
               strRetTmpName = strParentFolderPath & "\tmp" & CStr(lngCount) & "_[" & strName & "]_" & CStr(CLng(99999 * Rnd) + 100000)
               lngCount = lngCount + 1
          Loop While (objFso.FileExists(strRetTmpName) Or objFso.FolderExists(strRetTmpName))

          On Error Resume Next

          If blnFolderFlg = True Then
               objFso.MoveFolder strTargetYenCutName,strRetTmpName
          Else
               objFso.MoveFile strTargetYenCutName,strRetTmpName
          End If

          If Err.Number = 0 Then
               WScript.Sleep 10

               If Not (objFso.FileExists(strRetTmpName) Or objFso.FolderExists(strRetTmpName)) Then
                    '移動失敗の為、Lockできなかった。
                    strRetTmpName = ""
               End If
          Else
               '移動失敗の為、Lockできなかった。
               strRetTmpName = ""
          End If

     End If

     GetFileLock = strRetTmpName
End Function
'==================================================

テンポラリー名に元のファイル名を引き継ぎたかったので、独自で作成してチェックしています。
これで「ばんのしゃーによかばんた さん 2005年 03月 31日 18時 33分 28秒」のロジックで呼び出ししてもエラーは発生しません。
※フォルダでの多重排他呼び出しは確認していませんが・・・おそらく大丈夫でしょう。
※個人的に型は出来るだけVariant型は使いたくないので、戻り値にはLen=0の文字を返すようにしました。
※パラメータチェックはもっと厳密にやっていたのですが、ソースが長くなるので、少しカットして最低限のチェックにしています。
※前もって「Set objFso = CreateObject("Scripting.FileSystemObject")」で作っておく必要があります。


■ちゃっぴさん
んー、私の環境では、Resourcesが取得できないようです。

以下のようなVBSを作って確認してみました。

'==================================================
'==================================================
Sub smplADSIFunc()
     Dim objADsFSO
     Dim objADsResource

     Dim objTest
     Dim objComputer

  Dim objNameSpace
  Dim objDomain

  Dim strDomain
     Dim strComputer

     Wscript.Echo "Test1"
  Set objNameSpace = GetObject("WinNT:")
  For Each objDomain In objNameSpace
          strDomain = objDomain.Name
    WScript.Echo "Name: " & strDomain

          Wscript.Echo "Test2"
          Set objTest = GetObject("WinNT://" & strDomain)
          objTest.filter = Array("Computer")
          For Each objComputer In objTest
               strComputer = objComputer.Name
               WScript.Echo "Name: " & strComputer

               Wscript.Echo "Test3"

               Set objADsFSO = GetObject("WinNT://" & strComputer & "/LanmanServer")
               If (IsEmpty(objADsFSO) = False) Then
                    For Each objADsResource In objADsFSO.Resources
                         Wscript.Echo "Path  : " & objADsResource.Path
                         Wscript.Echo "User  : " & objADsResource.User
'                         Wscript.Echo "UserPath : " & objADsResource.UserPath
                         Wscript.Echo "LockCount : " & objADsResource.LockCount
                    Next
               End If
          Next
  Next
     Wscript.Echo "End"
End Sub
'==================================================

実行した環境は、ワークグループDOMAINNETです。
MAINPCとSUBPCの2台のWin2000ProSP4のPCがLAN上に接続されております。
実行したPCはMAINPCです。

CScriptで実行した出力結果は以下のようになりました。
'==================================================
Test1
Name: DOMAINNET
Test2
Name: MAINPC
Test3
Name: SUBPC
Test3
C:\test\test.vbs(39, 6) Active Directory: Active Directory プロパティがキャッシュに見つかりません。
'==================================================
ちなみに39行目は「Wscript.Echo "Path  : " & objADsResource.Path」の行です。

少なくともネットワーク名やマシン名が取得できているので、呼び出し方は間違ってはなさそうです。

もぐもぐたん さん 2005年 04月 07日 10時 11分 45秒

お世話になります。
今、ファイルFTP後に、正しくファイルがFTPされたかどうか確認し、もし、
されていなかった場合、再送する処理を作成しています。
そこで、送信元のファイルと送信先のファイルのサイズを比較し、一致するか
どうか確認する処理を考えているのですが、リモート上のファイルのサイズを
取得できなく、悩んでいるしだいです。
VBScriptのコーディング上で、リモート上のファイルサイズを取得し、後処理に使用できる何かよい方法はありませんでしょうか。どうぞご指導ご鞭撻よろしくお願いいたします。

いつも想定外 さん 2005年 04月 06日 12時 55分 19秒

TO ばんのしゃーによかばんた さん 2005年 04月 05日 14時 04分 59秒

ご返答有難うございます。

以下のスクリプトで確認しましたが、うまくいかないです。
スクリプトに埋め込むUser/Passwdとスクリプトを実行する
クライアントに現在ログオンしているUser/Passwdが違うためでしょうか。

「ログオンに失敗。ユーザ名が認識できないか、またはパスワードが
 間違っております」とエラーを返します。

Set WshNetwork = WScript.CreateObject("WScript.Network")
resalt1 = WshNetwork.MapNetworkDrive ("E:", "\\server\share", "TRUE", "User", "Passwd")
resalt2 = WshNetwork.RemoveNetworkDrive ("E:")

KIN さん 2005年 04月 05日 16時 31分 57秒

こちらの掲示板で教えて頂き簡単なサンプルを入手してWebサーバ(IIS)に対して実行かけられるようになりました。
ありがとうございました。
下記のロジックで実行要求をかけているのですが、Web先(ASP)に値を送信(SUBMIT)したいのですが、どのようにすれば実現できるか教えて頂けますでしょうか。(".send"にパラメータを設定するのでしょうか?)
宜しくお願い致します。
Set objHttpRequest = CreateObject("MSXML2.ServerXMLHTTP")
objHttpRequest.open "GET", strUrl, False
objHttpRequest.send

ばんのしゃーによかばんた さん 2005年 04月 05日 14時 05分 18秒

>むちゃ さん 2005年 03月 07日 13時 58分 48秒
>> >実は、HTA(*.hta)で ExecWB メソッドを使用したいと思いまして・・・
>> document.execCommand()で代替出来ませんか?
>execCommand メソッドではだめなようです。
>印刷関連(特に印刷プレビュー)の識別子がないので;;

HTAのメモリ中のHTMLソースを、IEを起こして、その中に直接書き込む、
または、一時ファイル.HTMに書き出して、IEで印刷プレビューする、
というのはどうでしょう?再現性があまりよくないかな。

忘れてましたが、
印刷機能はあるが、印刷プレビュー機能がないアプリに対して、
架空のプリンタに印刷して、その出力ファイルを表示する、
という代替方法がありますね。

例えば、Adobe Acrobatに付属する、PDFなんとか(?忘れた)とか。

あと、これがお勧めかな。
>ばんのしゃーによかばんた さん 2004年 05月 18日 18時 44分 42秒
>富士通なんたらソフトウェアのシェアウェアのPrintCoordinator、
>または、そのOEMでCanonプリンタに付属するPrintCast

テキストだけでよければ、Windowsに付属する、
>Generic / Text Onlyプリンタ以外に、
もあります。


ばんのしゃーによかばんた さん 2005年 04月 05日 14時 04分 59秒

>いつも想定外 さん 2005年 04月 03日 20時 23分 06秒
>> WshNetwork Class の MapNetworkDrive Method を使ってもいいでしょう。
>MSのページで確認しましたが、ネットワークドライブの設定ですよね。
>net useコマンドでもネットワークドライブの設定は出来ますが、
>出来れば単なる共有アクセスの設定が望みです。

思い付き、かつ、環境がないので、確認できませんが、
一度、MapNetworkDriveして、RemoveNetworkDriveしたら、
接続したのと同じ効果が残りません?


hidebou さん 2005年 04月 05日 13時 01分 12秒
URL:http://www5a.biglobe.ne.jp/~javajava/ari/

WSHはなかなか強力ですばらしい開発環境だという事を
こちらのサイトで知りました。私はVB派ではなくJS派
なのですが、スクリプトを主役にしたアプリケーション
開発を話題にしたサイトを作ってみました。
お時間がありましたどうそご覧になってください。
http://www5a.biglobe.ne.jp/~javajava/ari/

いつも想定外 さん 2005年 04月 04日 10時 11分 14秒

TO ちゃっぴ さん 2005年 04月 03日 22時 52分 30秒

ご返答有難うございます。
> Run Method の第二引数をご確認ください。
「IntWindowStyle」を"0"に設定することで、
ウィンドーが表示されないことを確認しました。

有難うございました。

hoshikuzu さん 2005年 04月 03日 23時 40分 04秒

>ばんのしゃーによかばんた さん 2005年 04月 03日 16時 05分 35秒
>ところで、sysimage://は、レジストリにはあるのに、なぜ駄目なんでしょう。

●Secunia - Advisories - Microsoft Internet Explorer "sysimage:" Local File Detection Weakness
http://secunia.com/advisories/13396/
ですのでXPwithSP2ではsysimage://は忌避されているようです。

ちゃっぴ さん 2005年 04月 03日 22時 52分 30秒

> この場合、コマンドプロンプトのウィンドーが一瞬表示されることは
> ないでしょうか。

Run Method の第二引数をご確認ください。

> 出来れば単なる共有アクセスの設定が望みです。

これはちょっと難しいでしょうね。
可能性とすればAPIとかになるかと思いますが、
WNetAddConnection3でも、結局は同じですし・・・

といゆうか、WSHではAPIを直接操作できなかったと思いますので・・・

いつも想定外 さん 2005年 04月 03日 20時 23分 06秒

TO ちゃっぴ さん 2005年 04月 01日 21時 47分 52秒

ご返答ありがとうございます。

> 別にWSHShell ClassのRun Method使って、Commandを呼び出しても
> いいかとは思いますが…
この場合、コマンドプロンプトのウィンドーが一瞬表示されることは
ないでしょうか。
batファイルでも良いのですが、コマンドプロンプトのウィンドーが
一瞬表示されるのが気になって。。。

> WshNetwork Class の MapNetworkDrive Method を使ってもいいでしょう。
MSのページで確認しましたが、ネットワークドライブの設定ですよね。
net useコマンドでもネットワークドライブの設定は出来ますが、
出来れば単なる共有アクセスの設定が望みです。

ちょっと難しいですかね?

ばんのしゃーによかばんた さん 2005年 04月 03日 16時 05分 35秒

>ばんのしゃーによかばんた さん 2005年 03月 29日 14時 55分 00秒
>ところで、sysimage://ファイル/[large|small]が使えなくなりました。
>res://ファイル/#番号とかでアイコンを参照できないものでしょうか。
>それができれば「名前を付けて画像を保存」でアイコンが簡単に取り出せるんですが。

res://File Name/[Resource Type (may not be needed)/]Resource ID

例えば、
res://notepad.exe/%233/2
で、メモ帳のアイコンが「取り出せる」ようです。

ここで、%23は#です。#3は#define RT_ICON 3です。

ただし、IEではアイコンが認識/表示できないようです。

>ばんのしゃーによかばんた さん 2004年 12月 07日 18時 08分 36秒
>以下を「お気に入り」に入れて、
>IEでWebページを表示し、「お気に入り」から実行すると、
>オリジナルHTMLソースをデスクトップにコピーします。
>Source.VBS

を使うと、バイナリが取り出せます。

これをnotepad.icoとリネームしてみましたが、そのままだと駄目です。
ほかの.ICOファイルからヘッダ?を取ってきて先頭にくっ付けるとうまく行きました。

また、
res://mshtml.dll/%2316/1
で、VersionInfoが取り出せます。%2316は#define RT_VERSION 16です。
取り出せると言ってもバイナリなので、ちょっと扱えないですが。。。

折角なので、何とか応用できませんかねぇ。

ところで、sysimage://は、レジストリにはあるのに、なぜ駄目なんでしょう。
セキュリティレベルかな。みなさんのところも同じですか?


ちゃっぴ さん 2005年 04月 01日 21時 47分 52秒

To いつも想定外 さん 2005年 04月 01日 16時 43分 20秒

> (Win32_Shareを使用すると思うのですが、いまいち使いかたが分からなくて)

Win32_Shareは、共有Folderを管理するClassであり、
すでに共有されているFolderに接続しにいくような機能はありません。

> DOSコマンド的には以下のなのですが、VB+WMIを使用すると
> どの様に行うのでしょうか

別にWSHShell ClassのRun Method使って、Commandを呼び出しても
いいかとは思いますが…

WshNetwork Class の MapNetworkDrive Method を使ってもいいでしょう。


ちゃっぴ さん 2005年 04月 01日 21時 41分 32秒

To あさじゃけん さん 2005年 03月 30日 20時 58分 33秒

>> NT系ならInstallされているはずなので、Defaultで使えるとおもます。
> Windows2000は、ADSIが標準ではないようですね。

標準ですよ?
http://www.microsoft.com/japan/technet/scriptcenter/scrptfaq.mspx

呼び出し方が悪いのかも?
もしかして、Remote Serverへ呼び出し行っていませんか?

いつも想定外 さん 2005年 04月 01日 16時 43分 20秒

ファイル共有接続をWMIクラスを利用してスクリプトを
行いたいと思っております。
DOSコマンド的には以下のなのですが、VB+WMIを使用すると
どの様に行うのでしょうか
(Win32_Shareを使用すると思うのですが、いまいち使いかたが分からなくて )
宜しくお願い致します。

DOSコマンド
net use \\サーバ名\共有名 パスワード /user:ユーザ名

KIN さん 2005年 04月 01日 15時 51分 08秒

魔界の仮面弁士さん、早速の回答ありがとうございます。
実はWSH(VBS)は超初心者です。

》魔界の仮面弁士 さん 2005年 04月 01日 15時 24分 54秒
ServerXMLHTTPオブジェクトなどを使えば良いと思います。

すみません、「ServerXMLHTTP」を使用したサンプルプログラムとかあれば
いいんですが。。。

魔界の仮面弁士 さん 2005年 04月 01日 15時 24分 54秒

》KIN さん 2005年 04月 01日 15時 03分 56秒
ASPのモジュール、というのが良く分かりませんが、
http://〜〜/test.asp などを呼び出したい、という意味であれば、
ServerXMLHTTPオブジェクトなどを使えば良いと思います。

KIN さん 2005年 04月 01日 15時 03分 56秒

ASPのモジュールをバッチ処理として実行させようと考えています。
WSH(VBS)からASPのモジュールを実行することは可能でしょうか?

ばんのしゃーによかばんた さん 2005年 04月 01日 12時 29分 51秒

>ばんのしゃーによかばんた さん 2005年 03月 30日 14時 25分 09秒
>Windowsのファイルopenの排他制御は以下のようです。
>   input   output
>input   o   o
>output   o   x

これを見て、思い付いたのですが、贋物のパイプが作れますね。
しかもこのパイプは分岐もできます。

pipein.vbs
――――――――――――――――――――――――――――――――――――――
Set fso=CreateObject("Scripting.FileSystemObject")
Set File=fso.OpenTextFile("pipe",2,True)
Do
 ans=InputBox("Enter")
 If IsEmpty(ans) Then Exit Do
 File.WriteLine ans
Loop
File.Close
――――――――――――――――――――――――――――――――――――――

pipeout.vbs x N
――――――――――――――――――――――――――――――――――――――
Set fso=CreateObject("Scripting.FileSystemObject")
Set File=fso.OpenTextFile("pipe",1,False)
Do
 If File.AtEndOfStream Then
  If EndOfPipe("pipe") Then If File.AtEndOfStream Then Exit Do
  WScript.Sleep 1000
 Else
  Line=File.ReadLine
  WScript.Echo Line
 End If
Loop
File.Close
WScript.Echo "EOF"

Function EndOfPipe(FilePath)
On Error Resume Next
Call fso.OpenTextFile(FilePath,8,False)
EndOfPipe=CBool(Err.Number<>70)
End Function
――――――――――――――――――――――――――――――――――――――

今まで、本物のパイプをスクリプトから使えないものかと思案して来ましたが、
無用なことでした。

というより、
本物のパイプはAtEndOfStreamでブロックされるのに対し、
贋物のパイプはunblocked readができるので、むしろ、贋物のほうがいいですね。

とは言え、オブジェクト参照までは渡せないので、IEのinterprocess通信機能の
代替にはなりません。

ところで、
ヘルプの「StdErr プロパティ (WshScriptExec)」のサンプルが謎でしたが。
これで解けるかも。あのサンプルは、WshScriptExecが一時期、贋物のパイプを
使っていたことを示しているのかも。

また、これで気が付いたのですが、コマンドプロンプトで、
ファイルにリダイレクトしていると、結果を見るのに、コマンドが終わるのを
待つ必要がなかったんですね。
more > file
a
b
として、別のコマンドプロンプトから、
more file
とすれば、中身が見えます。
wShell.Runでも、これを使えば、実行中に出力が見れます。
wShell.Execを使うよりいいかも。

それから、上のソースで、
Do
 If File.AtEndOfStream Then
  If EndOfPipe("pipe") Then If File.AtEndOfStream Then Exit Do
の部分は、ぱっと見、?ですが、よく考えられてますので、:-p
よく考えないで変えないでくださいね。


ばんのしゃーによかばんた さん 2005年 03月 31日 18時 33分 28秒

リネームを使うと、多重でもok。

Function GetFileLock(File)は、
Fileのロックに成功するとテンポラリファイル名を返し、
失敗するとEmptyを返します。

a.vbs
――――――――――――――――――――――――――――――――――――――
Set fso=CreateObject("Scripting.FileSystemObject")
temp="temp.tmp"
For k=1 To 100
If fso.FileExists(temp) Then
 File=GetFileLock(temp)
 If Not IsEmpty(File) Then
  fso.DeleteFile File
  d=d+1
 End If
Else
 fso.OpenTextFile temp,1,True
 c=c+1
End If
Next
WScript.Echo c,d,k

Function GetFileLock(File)
Dim Name
Name=Left(File,InStrRev(File,"\"))&fso.GetTempName()
On Error Resume Next
fso.MoveFile File,Name
If Err.Number Then Exit Function
WScript.Sleep 10
If fso.FileExists(Name) Then GetFileLock=Name
End Function
――――――――――――――――――――――――――――――――――――――
b.vbs こっちを起動
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
For k=1 To 2
wShell.Run "a.vbs"
Next
――――――――――――――――――――――――――――――――――――――
ただし、削除と違って、リネームは多重に平行に実行可能なようです。
アバウトですが、一呼吸置いて、最後のリネーム結果を得るようにしています。
リネーム者が一人ならこれは不要です。


SIGNAL9 さん 2005年 03月 31日 13時 54分 56秒
URL:http://signal9.exblog.jp/

>「本物の」icoファイルが作れるように、SIGNAL9さんを召還してお願いしてみましょうかw

呼ばれて飛び出てROM専門のSIGNAL9でございます。

>Doodle2の現在の構造では、複数の画像データが含まれるファイルを扱うように
>するのは難しそうですが…。
>もし可能なら、icoやアニメーションGIF、マルチページTiffなんかも使えるように
>なると嬉しいなぁ、なんて言ってみる。

…誠に申し訳ないです。公私共にもうDoodle2に割ける時間が確保できませんです。
Doodle2はDelphi6環境の産物なのですが、大バグもなさそうですし機能追加
もこれ以上はちょっと…と思い、既にメインの環境をDelphi2005にしてしま
いました。
あのソフトけっこう複雑で、Delphiのバージョンも4っつも上がるとリコン
パイルだけで済む…というものではないため、マジメに移植するかD6環境を
作らないといけないので…すみませんm(__)m

WSH初心者 さん 2005年 03月 31日 11時 48分 31秒

初めて投稿させていただきます。
WSHを使用して、ネットワークプリンタを作成しようと思っています。
その方法はLesson12を見て理解することができました。ありがとうございました。
ですが、あるプリンタサーバーでどんな名前で共有されているのかを取得し、
その後、Lesson12の方法でネットワークプリンタを作成したいのです。
(Const strShare="\\Server\Share" ここのShareの部分を取得したいのです)
ある特定のプリンタサーバーで、プリンタの共有名を取得する方法がありましたら
教えてください。
よろしくお願いします。

あさじゃけん さん 2005年 03月 30日 20時 58分 33秒

■ちゃっぴ さんへ
>> で・・・それでもやっぱり使えないですねぇ・・・
すみません。違う意味で捉えられてしまったようです。
私がここで言いたかったのは「私の環境では使えませんでした」という意味でした(><
不快な思いをされているかも知れないので、お詫び申し上げます。

>NT系ならInstallされているはずなので、Defaultで使えるとおもます。
Windows2000は、ADSIが標準ではないようですね。
SP4、IE6で、WindowsUpdateに何もでてこない状態でも、同じ現象になります。
3台の環境が異なるPCで試してみましたが、Windows2000の標準では動きませんでした。
おそらくWindowsXPから標準なのではないでしょうか。

仕事場のPCにADSIをインストールするような権限(立場的権限)はないので、実際に利用することはできそうにありません。


■ばんのしゃーによかばんた さんへ
大変お恥ずかしい・・・テストしてないのバレバレですね。
簡単に別のスクリプトで実行してテストした後に、いろいろ手直ししてから、動かすことなくそのままUPしてしまったので、「On Error GoTo 0」の位置がマズイところにいってしまったようです。(呼び出し元の関数名まで違ってますね。汗)

OnError関連の過去ログを拝見して、エラー処理中のエラー時の問題も理解しました。

排他についても、詳しく説明してもらってありがとうございます。
排他処理自体は理解していたのですが、このIsFileLock関数を作るさいにあまり深く考えていなかったこともあり、問題点に気がつかずに投稿してしまいました。

http://support.microsoft.com/default.aspx?scid=kb;ja;405455
いろいろ探している中、やっとの思いで、このサイトを見つけた段階で、「これでイケル!」と早合点してしまったのが原因ですね(汗
まったくダメダメでした。
Microsoftもそんな排他まで考えていないようですね。


■個人的にばんのしゃーによかばんたさんへ
正直、揚げ足とられ、言い方もきつく、少々ムっと腹も立ちましたが、ばんのしゃーによかばんたさんの言ってる通りで、内容にはどこにも非のつけようが無いです。
むしろ私の中途半端な知識が、浮き彫りになって恥ずかしい思いで一杯です(汗)

ただ、ここを見てる人が、みんな業務システム開発者ではない(いろんなLVの人がいる)ことと、私が「気持ち」でプログラムを作れる超能力者ではないことはご理解下さい(笑)
でも、私のために時間を割いてもらってるのは事実ですし、とても勉強になり感謝してます(^^;
そういう意味でも、私だけではなく、その人に合わせた発言をしてもらえるとありがたいです。(それを強要するつもりはありませんが・・・)
貴重な時間をかけていただいてありがとうございました。
これからもちょくちょく顔を出しますので、よろしくお願いします(^^;

管理人むたぐち さん 2005年 03月 30日 19時 39分 44秒

ばんのしゃーによかばんたさん、いつも有用なスクリプト部品を
公開していただいて感謝しています。

掲示板だとその性質上、過去の記事は参照されにくくなりますので、
Wiki(http://winscript.s41.xrea.com/wiki/index.php)に転載していこうと思います。
ただ、私ひとりだと大変なので、お手伝いいただける方を募集します。
といっても、この掲示板で宣言していただくだけで結構ですw

ばんのしゃーによかばんたさん作に限らず、汎用性のあるスクリプトはどしどし
転載していただくとありがたいです。

とりあえず私は新しい記事から遡ってやりたいと思っています。


To: ばんのしゃーによかばんた さん 2005年 03月 29日 14時 55分 00秒

> ところで、sysimage://ファイル/[large|small]が使えなくなりました。
> res://ファイル/#番号とかでアイコンを参照できないものでしょうか。
> それができれば「名前を付けて画像を保存」でアイコンが簡単に取り出せるんですが。

そんな裏技?があったんですね。私はIrfanViewというフリーソフトを使って、
shell32.dllからフォルダアイコンのアイコンリソースを、folder.bmp
として抽出して使いました。

「本物の」icoファイルが作れるように、SIGNAL9さんを召還してお願いしてみましょうかw
Doodle2の現在の構造では、複数の画像データが含まれるファイルを扱うように
するのは難しそうですが…。
もし可能なら、icoやアニメーションGIF、マルチページTiffなんかも使えるように
なると嬉しいなぁ、なんて言ってみる。

ばんのしゃーによかばんた さん 2005年 03月 30日 14時 25分 34秒

.HTAと.VBSの合体技です。IEのinterprocess通信機能を使います。

HTA.VBS
―――――――――――――――――――――――――――――――――――――
'<html><head><script language=vbs>For Each ie In CreateObject("Shell.Application").Windows():If Not IsEmpty(ie.GetProperty("VBS")) Then:Exit For:End If:Next:If IsEmpty(ie) Then:alert "ie not found.":close:End If:Set VBS=ie.GetProperty("VBS"):Call ie.PutProperty("window",window):VBS.WScript.Echo "from hta":</script></head><body>aaaaaaaaaaaa</body></html><!--
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
Call ie.PutProperty("VBS",Me)
Set wShell=CreateObject("WScript.Shell")
wShell.Run "MSHTA.EXE """&WScript.ScriptFullName&""""
Do While IsEmpty(ie.GetProperty("window"))
 WScript.Sleep(100)
Loop
Set window=ie.GetProperty("window")
ie.Quit()
window.alert TypeName(window)
Do While TypeName(window)<>"Object"
 WScript.Sleep(100)
Loop
WScript.Echo "WSH ended"
WScript.Quit()
'-->
―――――――――――――――――――――――――――――――――――――
VBS.HTA
―――――――――――――――――――――――――――――――――――――
'<html><head><script language=vbs>Set ie=CreateObject("InternetExplorer.Application"):ie.Visible=True:Call ie.PutProperty("window",window):CreateObject("WScript.Shell").Run("WScript.EXE //E:VBS """&UnEscape(location.pathname)&""""):</script></head><body>aaaaaaaaaaaa</body></html><!--
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows()
 If Not IsEmpty(ie.GetProperty("window")) Then Exit For
Next
Set window=ie.GetProperty("window")
ie.Quit()
window.alert TypeName(window)
Do While TypeName(window)<>"Object"
 WScript.Sleep(100)
Loop
WScript.Echo "WSH ended"
WScript.Quit()
'-->
―――――――――――――――――――――――――――――――――――――
補足

HTAは拡張子を変える必要がないみたいです。

VBScriptを1行に書くときの注意。
Ifは:で区切って、End Ifで閉める。
If 式 Then:文:文:::End If:
If 式 Then:文:文:::Else:文:文:::End If:


ばんのしゃーによかばんた さん 2005年 03月 30日 14時 25分 09秒

>あさじゃけん さん 2005年 03月 28日 20時 15分 51秒
>Function IsFileLock(strTargetFile)
>   On Error Resume Next
>   Set objFile = objFso.OpenTextFile(strTargetFile,8,False)
>   On Error GoTo 0
>   Select Case Err.Number
>     Case 0
は、
>   On Error GoTo 0
のせいで、必ず、0になります。

On Errorについては以下を参照。
>ばんのしゃーによかばんた さん 2004年 04月 10日 16時 13分 29秒
>On Error Resume Nextの正しい使い方について、

Windowsのファイルopenの排他制御は以下のようです。
     input     output
input     o     o
output     o     x

一般的な排他制御は、
          shared     exclusive
shared          o     x
exclusive     x     x

なので、この関数は、On Errorを修正すると、
ファイルがoutput openされていれば、Trueを返し、
ファイルがinput openされていれば、Falseを返します。

一方、削除/移動は、ファイルがoutputでもinputでもopenされていれば、
エラーになります。

なので、この関数は削除/移動のエラー予防としては、不十分です。

でも、業務用途やバッチ処理でない、個人の会話処理(=エラーがあっても、
リカバれる)などの用途では使えるかも。

あと、「状態の判定」と「状態の遷移」がロックシリアライズされてないと
多重環境で破綻するサンプルです。

a.vbs
――――――――――――――――――――――――――――――――――――――
Set fso=CreateObject("Scripting.FileSystemObject")
temp="temp.tmp"
For k=1 To 100
If fso.FileExists(temp) Then
 fso.DeleteFile temp
Else
 fso.CreateTextFile temp
End If
Next
MsgBox k
――――――――――――――――――――――――――――――――――――――
b.vbs こっちを起動してください。
――――――――――――――――――――――――――――――――――――――
Set wShell=CreateObject("WScript.Shell")
For k=1 To 2
wShell.Run "a.vbs"
Next
――――――――――――――――――――――――――――――――――――――
a.vbsはシングルでは、なんら問題なく動きますが、多重では破綻します。

これに、
>Function IsFileLock(strTargetFile)
を加えてみても、やっぱり破綻します。

a.vbs
――――――――――――――――――――――――――――――――――――――
Set fso=CreateObject("Scripting.FileSystemObject")
temp="temp.tmp"
For k=1 To 100
If fso.FileExists(temp) Then
 If Not IsFileLock(temp) Then
  fso.DeleteFile temp
 End If
Else
 fso.CreateTextFile temp
End If
Next
MsgBox k

Function IsFileLock(strTargetFile)
On Error Resume Next
Call fso.OpenTextFile(strTargetFile,8,False)
IsFileLock=Err.Number
End Function
――――――――――――――――――――――――――――――――――――――


すずん さん 2005年 03月 30日 08時 58分 26秒

WSHに関する知識が余りありません。どうか教えてください。
Win2Kを、複数ユーザが共有で利用しています。このPCでは、あるサービスが administrator で起動されています。
この状況で、ある通常の権限を持つユーザがログオンした時に、このサービスを止めたいと思っています。(サービスを止めるアプリは持っています)
が、起動したユーザと違う為、サービスが止められません。
WSHでは、通常ユーザがログイン後にadmin権限でサービスを止めるといった動作は出来ないでしょうか。

ちゃっぴ さん 2005年 03月 30日 00時 19分 39秒

> で・・・それでもやっぱり使えないですねぇ・・・

とりあえず、Windows XP Professional SP2 にて
動作確認済みです。

> Active Directory環境は必要なくても、クライアントマシンに
> ADSIはインストールされていないといけないような気がします。

ADSIを使用している以上、Installされていなければ
当然無理でしょう。

NT系ならInstallされているはずなので、Defaultで使えるとおもます。

きじ さん 2005年 03月 29日 20時 42分 53秒

魔界の仮面弁士 さん>
ありがとうございます<m(__)m>

無事バックアップが行えました!

ばんのしゃーによかばんた さん 2005年 03月 29日 19時 31分 48秒

>あさじゃけん さん 2005年 03月 28日 20時 15分 51秒
>でも私は、この場合のエラートラップするべき場所は「Lockする処理に対してのエラー処理」であって、「移動や削除のエラー処理」ではないと思っています。
>あるべき姿を考えた場合、これから扱おうとしているフォルダ、ファイル、サブフォルダに対してLockするメソッドが実装されていれば、エラー処理的にはすっきりだったのではないかと思います。
>まぁ、そうすると当然使いにくくなります(笑)
>オブジェクト指向ならではかも知れませんが、コピー、削除、移動といった処理が、複数の処理を一つにまとめて簡潔に扱えるようにしたために、こうなったんだと思いますね(^^;
>で。
>理想はともかく、結局一つの処理になってるので、コピー、削除、移動でトラップするしかないわけですが(笑)

メインフレームでは、そうでしたね。
ファイル操作の前に、必ずアロケ−ションが必要で、その中で、
データセット(=ファイルのこと)エンキュー(=待ち行列)をしてました。
でも、これは、バッチ処理の文化だからです。
バッチ処理では、実行途中に資源排他待ちやデッドロックが発生すると大変なので、
予め、使用資源をすべて排他しておくのです。

しかし、メインフレームのTSS(Time Sharing System)を過渡期として、
その後のUnixでは、多ユーザ/会話処理の文化になって、
時代遅れのアロケ−ションは消えちゃいました。

>■私の解決策
>で、やっぱり理屈うんぬんより、私自身、チェックしないと気持ち悪いので、自分なりに解決策を見つけました。

うーん、困りましたね。理屈云々と言われても、プログラムは、
「気持ち」で動くのではなく、「論理」で動くものなので。。。

>>それは、無駄なことです。仮令、それが分かったとしても仕方がありません
と申し上げたとおりなんですが、分かっていただけなかったようですね。
つまり、「■私の解決策」は多少発生頻度を少なくするだけで、
根本的に「解決策」になってないと。
結局、納品後にトラブル発生で呼び出されてやばいことに。。。

そうなったら大変でしょうから、もう一度「理屈」を云々しますから、
よく読んで、考えてみてくださいまし。

多重処理環境で、処理を逐次化するために、処理中フラグを作って、以下のように、
制御したとします。

待ち合わせしないケース
If FLAG=False Then
 FLAG=True
 処理
 FLAG=False
End If

待ち合わせするケース
Do While FLAG=True
 WScript.Sleep 100
Loop
FLAG=True
処理
FLAG=False

これらは、多重処理環境で、必ず破綻します。
==================
If FLAG=False Then
 FLAG=True
==================
この間をロックシリアライズしないと、
If FLAG=False Then
+++++++++ここに、他者が割り込んでFLAG=Trueにして平行して走ります。
 FLAG=True

If FLAG=False Then
 FLAG=True
の間なんて、微小な時間のように見えますが、
どんなに小さくても、0でない以上、現実的に割り込み可能です。

また、たとえ隣接する機械命令であっても、それらが別のメモリページに
跨っていれば、ページングが発生して、千客万来になることもあります。

なので、通常、重いロックメカニズムは、より軽いロックメカニズムを使って作ります。
「軽いロックを獲得」
If FLAG=False Then
 FLAG=True
「軽いロックを解放」
といったように。

例えば、セマフォアをミューテックスロックで作り、
ミューテックスロックは
TestAndSet(メモリ1バイトが00ならFFをセット)や
CompareSwap(メモリ1ワードがレジスタAと同じならレジスタBをセット)
などの機械命令で作り、
これらの機械命令は、メモリバスのロック機構で作ります。

で、結局、正しい解決方法は、削除のエラーを拾うか、リネームを使うか、です。
「削除」も「リネーム」も、「状態の判定」と「状態の遷移」を一度に行います。
そこのところがロックメカニズムのキーですね。

ファイルを一般ユーザから使われそうもない名前にリネームしてから移動すれば、
運用的に確実だと思います。

この多重処理(ロックシリアライズの仕組み)が分かっているかどうかが
プロの業務システム開発者の基本中の基本なので、そこんとこ、よろしく。


魔界の仮面弁士 さん 2005年 03月 29日 17時 34分 01秒

》きじさん 2005年03月29日 16時14分30秒
> Securityに関しては動作しません。。。

GetObject する際の文字列を、下記のように変更してみてください。

 "winmgmts:{impersonationLevel=impersonate,(Backup)}!\\.\root\cimv2"
   ↓
 "winmgmts:{impersonationLevel=impersonate,(Backup, Security)}!\\.\root\cimv2"

きじ さん 2005年 03月 29日 16時 14分 30秒

こんにちは。初めて質問させて頂きます。

<http://www.microsoft.com/japan/technet/scriptcenter/scripts/logs/eventlog/lgevvb01.mspx>
上記のスクリプトでapplicationをSecurityに置換して、Securityイベントログのバックアップ・クリアを実行したいのですが、Systemに置換すればSystemイベントログに対しては有効なのに、Securityに関しては動作しません。。。

これは、Securityだけ何かしらの制限事項が働いているのでしょうか?
若しくは、指定方法が別にあるのでしょうか?

ご教示頂きたく、よろしくお願いします<m(__)m>

きじ


ばんのしゃーによかばんた さん 2005年 03月 29日 14時 55分 50秒

.HTMを.VBSに合体。VBSには、複数行コメントがないので、HTML部分は1行に。

HTM.VBS
――――――――――――――――――――――――――――――――――――――
'<html><head><script>var ScriptEnabled=true;</script></head><body>aaaaaaaa</body></html><!--
Set fso=CreateObject("Scripting.FileSystemObject")
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
Set file=fso.GetFile(WScript.ScriptFullName)
file.Name=fso.GetBaseName(file.Name)&".HTM"
ie.Navigate(file.Path)
Do While ie.Busy Or ie.ReadyState<>4
 WScript.Sleep(100)
Loop
Do
 On Error Resume Next
 If ie.Document.parentWindow.ScriptEnabled=False Then
 Else
  Exit Do
 End If
 If Err<>438 Then Exit Do
 WScript.Sleep(100)
Loop
On Error GoTo 0
WScript.Echo ie.Document.parentWindow.ScriptEnabled
WScript.Echo "WSH started"
Do While TypeName(ie)<>"Object"
 WScript.Sleep(100)
Loop
file.Name=fso.GetBaseName(file.Name)&".VBS"
WScript.Echo "WSH ended"
WScript.Quit()
'-->
――――――――――――――――――――――――――――――――――――――
.VBSを.HTMに合体。

VBS.HTM
――――――――――――――――――――――――――――――――――――――
'<html><head><script for=window event=onload language=vbscript>CreateObject("WScript.Shell").Run("WScript.EXE //E:VBS """&unescape(Mid(location.pathname,2))&""""):</script></head><body>aaa</body></html><!--
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows()
If UnEscape(Replace(Mid(ie.LocationURL,9),"/","\"))=WScript.ScriptFullName Then Exit For
Next
If IsEmpty(ie) Then
 WScript.Echo "Failed"
 WScript.Quit
End If
WScript.Echo "WSH started"
Do While TypeName(ie)<>"Object"
WScript.Sleep 100
Loop
WScript.Echo "WSH ended"
WScript.Quit
'-->
――――――――――――――――――――――――――――――――――――――


ばんのしゃーによかばんた さん 2005年 03月 29日 14時 55分 26秒

>ばんのしゃーによかばんた さん 2005年 01月 25日 19時 27分 55秒
>WSHとIEの併せ技について紆余曲折。
>ie.Navigate "about:blank"はインターネットゾーンになるので、
>ie.Navigate "res://mshtml.dll/blank.htm"を使って、マイコンピュータゾーンにして、
>後からスクリプトやオブジェクトを組み込むことが出来ましたが、
>XP SP2から、これもインターネットゾーンになって、使えなくなりました。
>マイコンピュータゾーンにする方法は、ローカルにHTMファイルを作る?

のではなく、.HTMファイルと.JSファイルを1ファイル(.JS)に合体してみました。
JScriptなのは、複数行コメントがあるからです。

HTM.JS
――――――――――――――――――――――――――――――――――――――
/*
<html>
<head>
<script>
var ScriptEnabled=true;
</script>
</head>
<body>aaa
</body>
</html>
<!--
*/
var fso=new ActiveXObject('Scripting.FileSystemObject');
var ie=new ActiveXObject('InternetExplorer.Application');
ie.Visible=true;
var file=fso.GetFile(WScript.ScriptFullName);
file.Name=fso.GetBaseName(file.Name)+'.HTM';
ie.Navigate(file.Path);
while(ie.Busy||ie.ReadyState!=4) WScript.Sleep(100);
try{
while(typeof(ie.Document.parentWindow.ScriptEnabled)=='undefined')
WScript.Sleep(100);
WScript.Echo('ScriptEnabled');
while('Visible' in ie)WScript.Sleep(100);
}catch(e){}finally{
file.Name=fso.GetBaseName(file.Name)+'.JS';
WScript.Echo('WSH ended');
WScript.Quit();
}
//-->
――――――――――――――――――――――――――――――――――――――
逆に.JSを.HTMに一体化することも出来ます。
こっちのほうが、リネームや待合せの必要がなくてよいかも。

JS.HTM
――――――――――――――――――――――――――――――――――――――
/*
<html>
<head>
<script for=window event=onload>
new ActiveXObject('WScript.Shell').Run('WScript.EXE //E:JScript "'+unescape(location.pathname.substr(1))+'"');
</script>
</head>
<body>aaa
</body>
</html>
<!--
*/
var Shell=new ActiveXObject('Shell.Application');
for(var k=Shell.Windows().Count;k>0;k--){
var ie=Shell.Windows().Item(k-1);
if(unescape(ie.LocationURL.substr(8).replace('/','\\'))==WScript.ScriptFullName) break;
}
if(k=0){
WScript.Echo('Failed');
WScript.Quit();
}
WScript.Echo('WSH started');
try{
while('Visible' in ie)WScript.Sleep(100);
}catch(e){}finally{
WScript.Echo('WSH ended');
WScript.Quit();
}
//-->
――――――――――――――――――――――――――――――――――――――


ばんのしゃーによかばんた さん 2005年 03月 29日 14時 55分 00秒

>管理人むたぐち さん 2005年 03月 26日 21時 04分 26秒
>> 無地(無字)のフォルダアイコンにフォルダ名(英字先頭3文字程度)を重ね> たアイコンを
>> 自動的に作ってフォルダのアイコンに指定するってことが出来ますでしょ> うか。
>簡単です。
>ただし、doodle2では「本物の」icoファイルは作れないので、擬似icoファイルになります。擬似とは、要するにbmpをicoにリネームしただけという意味です。これでも一応はアイコンとして使えますが、16x16表示時に専用アイコンを表示したりすることはできません。

透過ができないみたいで黒くなります。
透過は、「本物の」.ICOファイルでないと無理でしょうか?

なので、大きいアイコンは、白地、黒外枠にすれば、よさそうなのが出来ます。
でも、小さいアイコンはやっぱ暈けます。
32x32で作って16x16に切り取ればよいかなと思いましたが、どうもよくないです。
16x16の場合はフォントが微妙で手作業でないと難しそうですね。

ところで、sysimage://ファイル/[large|small]が使えなくなりました。
res://ファイル/#番号とかでアイコンを参照できないものでしょうか。
それができれば「名前を付けて画像を保存」でアイコンが簡単に取り出せるんですが。


あさじゃけん さん 2005年 03月 29日 13時 23分 05秒

ちゃっぴさんありがとうございます(^^;

で・・・それでもやっぱり使えないですねぇ・・・

Active Directory環境は必要なくても、クライアントマシンにADSIはインストールされていないといけないような気がします。

私のところで、そのソースをVBSに書き換えて、実行しても、
「Active Directory: Active Directory プロパティがキャッシュに見つかりません。」とエラーになります。
GetObjectが正しく取得できていないっぽいです。

私は、昔、過去の書き込みでもありますが、「LDAP://」の定義の仕方でADSIは多少触っていたのですが、「WinNT」の形式で使ったことはないんですよね・・・汗
Windowsのプロバイダなので、いけそうな気はするのですが・・・何かが問題なようです。

ちゃっぴ さん 2005年 03月 28日 23時 36分 57秒

To あさじゃけん さん 2005年 03月 28日 20時 15分 51秒

ActiveDirectoryを構築していないワークグループ環境なんです;
なのでADSIが使えませんです(><;
#せめてWindowsドメイン環境にしてほすぃ〜

WorkGroup環境でもWinNT Providerなら使えますが…

' 参照 ActiveDS Type Library
Sub S_EnumResouce(strComputer As String)
  Dim objADsFSO    As ActiveDs.IADsFileServiceOperations
  Dim objADsResource As ActiveDs.IADsResource
  
  Set objADsFSO = GetObject( _
    "WinNT://" & strComputer & "/LanmanServer")

  If IsEmpty(objADsFSO) = False Then
    For Each objADsResource In objADsFSO.Resources
      With objADsResource
        Debug.Print "Path    : " & .Path
        Debug.Print "User    : " & .User
        'Debug.Print "UserPath  : " & .UserPath
        Debug.Print "LockCount : " & .LockCount
      End With
    Next objADsResource
  End If
  
  Set objADsFSO = Nothing
End Sub

WinNTの場合、"WinNT://" & strComputer & "/LanmanServer" でも
"WinNT://" & strWorkGroupName & "/" & strComputer & "/LanmanServer"

な感じでもいけたかと思います。

Return