ばんのしゃーによかばんた さん 2005年 03月 12日 15時 56分 56秒

>ばんのしゃーによかばんた さん 2005年 03月 11日 16時 29分 32秒
>ie.StatusText="pipe"
>If Left(ie.StatusText,InStr(ie.StatusText,vbNullChar)-1)="pipe" Then Exit For

そうそう、言い忘れました。

これは、IEの「障害」だと思いますが、
ie.StatusText="pipe"
If ie.StatusText="pipe" Then
は決してTrueになりません。

ごみが付きます。長さの設定を間違えているのだと思います。



ばんのしゃーによかばんた さん 2005年 03月 12日 15時 56分 25秒

CMD.EXEのコマンドグルーピング()の「障害」の回避方法です。

>ばんのしゃーによかばんた さん 2005年 03月 09日 19時 20分 36秒
>CScript.EXE //E:VBS - の代替です。

標準入力からスクリプトを渡すとき、一行なら

ECHO スクリプト行 | (仮に) MORE

で済みますが、複数行のときは、グルーピング()を使います。
グルーピング()中の)は^)でエスケープします。

ところが、CMD.EXEには「障害」があって、
グルーピング()中の)が正しく処理されないのです。

(
ECHO Set wShell=CreateObject("WScript.Shell"^)
ECHO wShell.PopUp("HOGE"^)
) | MORE

最初の)が消えて末尾に付きます。

これでは折角の機能が使えません。:-< :-< :-<

)を%%29にエスケープして、UnEscape()して逃げるという手もありますが、
びゅーちふるじゃない。

そこで、前後にREM行を付け加えます。
(
ECHO Rem ^)
ECHO Set wShell=CreateObject("WScript.Shell"^)
ECHO wShell.PopUp("HOGE"^)
ECHO Rem
) | MORE

これでばっちぐーです。お試しあれ。


ばんのしゃーによかばんた さん 2005年 03月 12日 15時 56分 02秒

>管理人むたぐち さん 2005年 03月 10日 18時 08分 40秒
>今日、ばんのしゃーによかばんた さん 2005年 03月 06日 16時 01分 18秒 のスクリプトを動かしたら、DEPが作動せず普通にスクリプトが実行されました。

あれ、それはちょっと残念。

>>データ実行防止機能の動作確認用サンプルとしてご利用ください。:-p
として使えませんね。

>良くわからない機能です…<DEP

そんなご無体な。DEPは悪くありませんから。
単にバッファオーバランでなかっただけです。きっと。

元々、未初期化データを参照し、そのデータに依存してメモリを破壊する
障害があって、長〜い「ファイル名」を指定すると、未初期化データが変化し、
たまたまDEPの監視領域を壊したのでしょう。

なので、もしMS開発者と知り合いの方がお読みなら、お伝えくださいまし。
バッファオーバランに注目してソースを見ても空振りですよ。
MSHTAをPurifyに掛けて未初期化データ参照とメモリ破壊を検出しなさい。
と。


いりや さん 2005年 03月 11日 17時 42分 20秒

ひよこさん、

> workフォルダには、東部社員売上yymmdd.csvファイルともう一つcsvファイルがあり常に2つ存在します。

スクリプトを実行する日時から yymmdd の部分が計算できるのであ
れば、対象のファイルのパス情報を動的につくりだす方法はいかが
でしょうか。

例えば、対象のファイルは、一日前であることが分かる場合は、こ
のようなスクリプトになるでしょうか。n日前であれば DateAdd
() 関数の第二引数を -n に変更すれば OK です。

Dim fso
Dim directory
Dim yesterday
Dim yymmdd
Dim filename
Dim filepath

Set fso = CreateObject("Scripting.FileSystemObject")

directory = "c:\"
yesterday = DateAdd("d", -1, Now())

yymmdd = Mid(Replace(FormatDateTime(yesterday, vbShortDate), "/", ""), 3)
filename = Replace("東部社員売上%s.csv", "%s", yymmdd)
filepath = directory & filename

If fso.fileExists(filepath) Then
    ' 本体
End If


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

メモ帳でスクリプトを修正した後、名前を付けて保存するつもりが、
上書き保存してしまいました。
メモ帳さんには自動でバックアップを取って欲しいものです。

NotePad.VBS
――――――――――――――――――――――――――――――――――――――
Path=WScript.Arguments(0)
Set fso=CreateObject("Scripting.FileSystemObject")
Set wShell=CreateObject("WScript.Shell")
fso.CopyFile Path,Path&".BAK"
Call wShell.Run("NotePad.EXE "&Path,,True)
If fso.GetFile(Path).DateLastModified=fso.GetFile(Path&".BAK").DateLastModified Then
 Call fso.DeleteFile(Path&".BAK")
End If
――――――――――――――――――――――――――――――――――――――


ばんのしゃーによかばんた さん 2005年 03月 11日 16時 29分 32秒

>G-Luck さん 2005年 02月 28日 12時 06分 36秒
>現在、Excelを二つ起動していて、二番目に起動したExcelを取得したいのですが、その方法はあるでしょうか?
>現在は、GetObject(,"Excel.Application")で取得しているのですが、最初のものしか取得できません。
>環境 WinXP,Excel2003

GetObject(,"Excel.Application")で操作するには、
Excelを複数起動しないようにすればよいと思います。

具体的には以下のようにします。
関連付け起動だけを使う。
或いは、関連付け起動以外を以下のEXCEL.VBSに置き換える。

EXCEL.VBS
――――――――――――――――――――――――――――――――――――――
Set x2=CreateObject("Excel.Application")
Set xl=GetObject(,"Excel.Application")
If Not xl Is x2 Then x2.Quit
xl.Visible=True
xl.WorkBooks.Add
――――――――――――――――――――――――――――――――――――――

さて、私的に流行のie.PutPropertyを使うと、複数のExcelが操作出来ます。
x1.VBS 初めに    
――――――――――――――――――――――――――――――――――――――
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.StatusText="pipe"
Set dic=CreateObject("Scripting.Dictionary")
ie.PutProperty "Excel",dic
Do While TypeName(ie)="IWebBrowser2"
WScript.Sleep 1000
Loop
WScript.Echo "manager end."
――――――――――――――――――――――――――――――――――――――
x2.VBS ×n回
――――――――――――――――――――――――――――――――――――――
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows
 If Left(ie.StatusText,InStr(ie.StatusText,vbNullChar)-1)="pipe" Then Exit For
Next
If IsEmpty(ie) Then
 WScript.Echo "pipe not found."
 WScript.Quit
End If
Set dic=ie.GetProperty("Excel")
Set xl=CreateObject("Excel.Application")
xl.Visible=True
dic.Add xl,xl
Set xl=Nothing
WScript.Echo "I am number",dic.Count
――――――――――――――――――――――――――――――――――――――
x3.vbs 最後に
――――――――――――――――――――――――――――――――――――――
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows
 If Left(ie.StatusText,InStr(ie.StatusText,vbNullChar)-1)="pipe" Then Exit For
Next
Set dic=ie.GetProperty("Excel")
WScript.Echo dic.Count
For Each key In dic
 Set xl=dic.Item(key)
 dic.Remove key
 xl.Quit
Next
ie.Quit
――――――――――――――――――――――――――――――――――――――
IE=Interprocess object Exchangerですね。


ひよこ さん 2005年 03月 11日 14時 08分 30秒

いりやさん、お返事ありがとうございます。

ファイルは処理後、バックアップフォルダへ移動させますので、
workフォルダには蓄積させません。
workフォルダには、東部社員売上yymmdd.csvファイルともう一つcsvファイルがあり常に2つ存在します。
拡張子での識別も無理なんです。。。


超初心者 さん 2005年 03月 11日 13時 30分 22秒

他のマシンの共有フォルダからスクリプトを使用して、自分のPCのフォルダにファイルをコピーしたいのですが、ホストマシンであるため、共有フォルダにアクセスしようとすると、ユーザ名とパスワードを求められます。前もって手動でログインしておけば問題ないのですが、これをスクリプトを使用して、ユーザ名とパスワードを設定するような事は可能でしょうか?

いりや さん 2005年 03月 11日 13時 00分 43秒

ひよこさん、

固定ではないがそのディレクトリにその形式で格納されるファイルは一つなのでしたっけ。それとも日がかわるとどんどん増えてくるのでしょうか。

東部社員売上050311.csv
東部社員売上050312.csv
東部社員売上050313.csv
  :
  :

ひよこ さん 2005年 03月 11日 11時 06分 16秒

ファイルを取得したいのですが、ファイル名が固定でない場合のファイル名の取得方法について教えていただけますでしょうか。
ファイル名のすぐ後ろに6桁の数字(yymmdd)がつきますが、可変なのです。
ファイルを開くときに、ファイル名が固定だと処理が可能ですけど、ここでワイルドカードは使えないんですよね。
このような場合はどのようにしたらよいのか、アドバイスをお願いします。

Set fso = CreateObject("Scripting.FileSystemObject")
Set tmpFile = fso.OpenTextFile("C:\My Documents\Temporary\work\東部社員売上*.csv",1,True)

・ファイルが存在する場所は決まっている
・ファイル名は、「東部社員売上yymmdd.csv」

管理人むたぐち さん 2005年 03月 10日 18時 08分 40秒

今日、ばんのしゃーによかばんた さん 2005年 03月 06日 16時 01分 18秒 のスクリプトを動かしたら、DEPが作動せず普通にスクリプトが実行されました。
何の設定も弄ってないのに!

良くわからない機能です…<DEP

ばんのしゃーによかばんた さん 2005年 03月 10日 17時 55分 38秒

unixのwhichのようにベース名/ファイル名からPATH配下のフルパス名を得る方法は?

普通に考えると、環境変数のPATHとPATHEXTをばらして、組み合わせて、存否確認して、
と結構、面倒です。もっと簡単にできないかものかと。

バッチなら、
which.BAT
@ECHO OFF
FOR %%0 IN (%~$PATH:1) DO ECHO.%%0
FOR %%2 IN (%PATHEXT%) DO FOR %%3 IN (%1%%2) DO FOR %%4 IN (%%~$PATH:3) DO ECHO.%%4

VBSなら、
which.VBS
――――――――――――――――――――――――――――――――――――――
Option Explicit
Dim wShell
Dim Link
Dim Path

Set wShell=CreateObject("WScript.Shell")
Set Link=wShell.CreateShortCut(".LNK")
Do
 Path=InputBox("Enter File Name or Base Name.",WScript.ScriptName,Path)
 If Path="" Then Exit Do
 On Error Resume Next
 Call GetFullPath(Path)
 On Error GoTo 0
Loop
Sub GetFullPath(Path)
 Link.TargetPath=Path
 Path=Link.TargetPath
End Sub
――――――――――――――――――――――――――――――――――――――


ばんのしゃーによかばんた さん 2005年 03月 10日 17時 55分 11秒

HTAのソースを丸ごとパイプでMSHTAに渡す、方法もあります。

これなら、MSHTAのコマンドラインを、F2.VBSより、もっと短くできます。

また、HTAソースをinsertなんとかで組み上げるよりもずっと簡単です。

H.VBS
――――――――――――――――――――――――――――――――――――――
Set fso=CreateObject("Scripting.FileSystemObject")
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.PutProperty "VBScriptTypeInfo",Me
Set wShell=CreateObject("WScript.Shell")

Set oExec=wShell.Exec("MSHTA ""javascript:new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll();""")

oExec.StdIn.Write fso.OpenTextFile(Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"."))&"HTA").ReadAll
oExec.StdIn.Close

Do While IsEmpty(ie.GetProperty("window"))
 WScript.Sleep 1000
Loop
Set window=ie.GetProperty("window")
ie.Quit
MsgBox window.document.documentElement.outerHTML
window.alert window.document.Title
Set window.document.body.onunload=GetRef("proc")
window.alert "hoge"
window.close
Do While htaStop=False
 WScript.Sleep 1000
Loop
WScript.Quit

Sub proc()
MsgBox "hta onunload"
htaStop=True
End Sub
――――――――――――――――――――――――――――――――――――――
H.HTA 本来はH.VBSに文字列で組み込む。今回はコンセプト検証なのでファイル。
――――――――――――――――――――――――――――――――――――――
<html><head><title>HTA TITLE</title>
<script language="VBScript">
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows
 If Not IsEmpty(ie.GetProperty("VBScriptTypeInfo")) Then Exit For
Next
If IsEmpty(ie) Then
 alert "ie not found."
 close
End If
Set VBScriptTypeInfo=ie.GetProperty("VBScriptTypeInfo")
VBScriptTypeInfo.WScript.Echo "from hta 1"
VBScriptTypeInfo.WScript.Sleep 2000
VBScriptTypeInfo.WScript.Echo "from hta 2"
ie.PutProperty "window",window
</script>
</head><body></body></html>
――――――――――――――――――――――――――――――――――――――


ばんのしゃーによかばんた さん 2005年 03月 10日 17時 54分 26秒

>管理人むたぐち さん 2005年 03月 08日 23時 20分 14秒
>やっぱりデータ実行防止のエラーが出ます。

「データ実行防止」を設定しましたが、エラーは出ませんでした。

>Execに変えてもダメですね。cmd.exeでMSHTA以下の部分を実行してやっても、
やっぱりデータ実行防止のエラーが出ます。
>MSHTAにあまり長いオプションをつけるとダメってことなのかもしれません。

普通は「ファイル名」なので、こういう長い「ファイル名」のテストはしてない
のでしょうね。きっと。

出来るだけ短くしてみました。これならどうでしょう?

F2.VBS
――――――――――――――――――――――――――――――――――――――
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
'ie.StatusText="pipe"
ie.PutProperty "VBS",Me
Set wShell=CreateObject("WScript.Shell")
wShell.Run "MSHTA ""javascript:var ies=new ActiveXObject('Shell.Application').Windows();for(var k=ies.Count;k>0;k--){var ie=ies.Item(k-1);var VBS=ie.GetProperty('VBS');if(VBS){ie.PutProperty('window',window);break;}}if(!k){alert('ie not found.');close();}"""

Do While IsEmpty(ie.GetProperty("window"))
 WScript.Sleep 1000
Loop
Set window=ie.GetProperty("window")
ie.Quit
MsgBox window.document.documentElement.outerHTML
window.VBS.WScript.Echo "hta"
Set window.document.body.onunload=GetRef("proc")
window.alert "hoge"
window.close
Do While htaStop=False
 WScript.Sleep 1000
Loop
WScript.Quit

Sub proc()
MsgBox "hta onunload"
htaStop=True
End Sub
――――――――――――――――――――――――――――――――――――――
もっと複雑なHTAは、WSHから、
window.document.body.insertAdjacentHTML "<xxx>..."
などを使って、組み込んでいけばよいのかな。


魔界の仮面弁士 さん 2005年 03月 10日 09時 48分 36秒

おぉ。XP SP2のDEPが働くんですか。
MSHTA を DEP から除外設定すれば動くのかな?

私の環境は、Windows CE環境のデバッグが必要な関係で、
データ実行防止機能をOffにしているため、確認できませんでした。
http://support.microsoft.com/kb/891667

ばんのしゃーによかばんた さん 2005年 03月 09日 19時 20分 36秒

CScript.EXE //E:VBS - の代替です。

MORE | MSHTA.EXE vbscript:close(execute(CreateObject("Scripting.FileSystemObject").GetStandardStream(0).ReadAll())) | MORE

CScript.EXE //E:JS - の代替です。

MORE | MSHTA.EXE "javascript:eval(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll());close();" | MORE

ただし、WScript.*は使えません。


sei さん 2005年 03月 08日 23時 55分 01秒

ばんのしゃーによかばんた様ありがとうございました。HTAのスクラッチ
起動できました。これを公開なさったときに丁度 HTA の windowオブジェクト
取得方法を考えていたので「渡りに船」でした。そーかー VARIANT なら
なにを書いても OK で、マーシャリングも IE が勝手にしてくれるんですね。
色々勉強になりました。
管理人様が動かないと書かれてましたが私も最初は D.VBS & D.HTA , F.VBS
は動きませんでした。Win98 という古めかしい環境のせいかもしれませんが
私の場合は ie.PutProperty('window',window) が出来ませんでした(エラーは
表示せず止まったまま)。F.VBSのほうだけいろいろいじった結果 MSHTA 実行
前に'window'プロパティを null で定義してプロパティの書き込み待ちを
IsNull() でチェックすると行けました。ちなみに C.VBS でなさっていたイベントを使う方法は MSHTA 実行で Me オブジェクトを取得できませんでした。IE の
プロパティの存在意味も?だし なんだかよくわからん世界だ…
今後は私のスクリプトツールの定番方法になるでしょう、しかし確かに
セキュリティには良くない方法ですね。

管理人むたぐち さん 2005年 03月 08日 23時 27分 57秒

To: うつ猫 さん

Shell.Applicationを使えば可能です。

Set Fs = WScript.CreateObject("Scripting.FileSystemObject")
Set Shell = WScript.CreateObject("Shell.Application")

For Each sArg In WScript.Arguments
  If Fs.FileExists(sArg)Then
    dDate=Fs.GetFile(sArg).DateLastModified
    
    'ここにファイルの修正のコード入れる
    
    Call ModifyDate(sArg,dDate)
  End If
Next

MsgBox "終了"

Sub ModifyDate(path,date)
     Shell.NameSpace(Fs.GetParentFolderName(path)).ParseName(Fs.GetFileName(path)).ModifyDate=date
End Sub

管理人むたぐち さん 2005年 03月 08日 23時 20分 14秒

To: ばんのしゃーによかばんた さん 2005年 03月 08日 16時 18分 20秒

> コマンドラインが長すぎて、バッファオーバランしたのでしょうか。
> Runか、MSHTAか、その先か。Execに変えても駄目でしょうか?

Execに変えてもダメですね。cmd.exeでMSHTA以下の部分を実行してやっても、
やっぱりデータ実行防止のエラーが出ます。
MSHTAにあまり長いオプションをつけるとダメってことなのかもしれません。

データ実行防止機能は、「システムのプロパティ」→「詳細設定」→「パフォーマンス」
→「データ実行防止」で設定できます。
デフォルトでは「重要なWindowsのプログラムおよびサービスについてのみ有効にする」
にチェックが入っています。

oo さん 2005年 03月 08日 19時 56分 36秒

>うつ猫 さん 2005年 03月 08日 17時 56分 27秒
>ファイルを修正した後、ファイルの更新日時は元のファイルのまましたいです。
>出来ますでしょうか?

FileSystemObjectの、DateLastModified プロパティを保存しておいて、
ファイル修正後に、設定しなおせば良いと思います。

oo さん 2005年 03月 08日 19時 53分 45秒

>Ω さん 2005年 03月 05日 14時 02分 54秒
>WSHでwinの環境変数に追加したいと考えています。

WSHのEnvironmentプロパティを使えば、
1) SYSTEM環境変数の登録追加(マイコンピュータプロパティの詳細で設定するのと同じ)
2) USER環境変数の登録追加(同上)
3) いまWSHが動いているプロセスの環境変数の書き換え(子プロセスへも継承)
4) 同上(子プロセスへ継承しない)
ができます。

サンプル:上記3)のケース
Set WshShell = WScript.CreateObject("WScript.Shell")
Set WshEnv = WshShell.Environment("process")
WshEnv("ZZZZZ")="12345"
WshShell.run "CMD"

run "CMD" で開くコマンドプロンプトで echo %ZZZZZ% とすれば 12345 となります。

うつ猫 さん 2005年 03月 08日 17時 56分 27秒

ファイルを修正した後、ファイルの更新日時は元のファイルのまましたいです。
出来ますでしょうか?
教えてください!お願いします。

ばんのしゃーによかばんた さん 2005年 03月 08日 16時 19分 11秒

もう少し実用性のある1行スクリプトをば。

クリップボードの中身を取り出す。

MSHTA.EXE "javascript:new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(clipboardData.getData('text'));close();" | MORE

クリップボードにテキストを書き込む。

ECHO aaaaa | MSHTA.EXE "javascript:clipboardData.setData('text',new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(0).ReadAll());close();"

1行の中にテクが凝縮されていて、俳句や短歌みたいですね。:-)


ばんのしゃーによかばんた さん 2005年 03月 08日 16時 18分 49秒

>むちゃ さん 2005年 03月 07日 13時 58分 48秒
>> >後は、HTA(*.hta)でも window.status は生きているようなので >StatusTextChange イベントに接続して、
>> >HTA(*.hta)の自作(擬似)ステータスバーに文字列を表示できるかなぁ・・・>と思っちゃったりもして。
>以前はそれで(正確には setTimeout メソッド)やっていたのですが、
>他の動作があまりにも遅くなったためにやめました。
>(100ms 〜 500ms 間隔で window.stats の値を取得していました)

そんなに遅くなりますか?
ひょっとして、毎回、同じ処理=重い処理をしてませんか?

イベントでもタイマループでも同じですが、
高頻度側の処理を軽くする/短絡する工夫が必須ですよね。
こんな感じ。↓

甲案
status=window.status
If status<>previous Then
 previous=status
 hogehoge.status=status
End If

乙案
If window.status=previous Then Exit Sub
previous=window.status
hogehoge.status=window.status


ばんのしゃーによかばんた さん 2005年 03月 08日 16時 18分 20秒

>管理人むたぐち さん 2005年 03月 06日 23時 37分 34秒
>このスクリプトを実行すると、htaを実行する段階で
>XP SP2のデータ実行防止機能が働いて途中で止まりました(汗

あれまぁ。未修正のセキュリティホールが見つかったってことでしょうか。
コマンドラインが長すぎて、バッファオーバランしたのでしょうか。
Runか、MSHTAか、その先か。Execに変えても駄目でしょうか?

>初めて見たなぁ、データ実行防止のダイアログ。

データ実行防止機能の動作確認用サンプルとしてご利用ください。:-p

これって、ハードとソフトの二つあるんですよね?
有効にするかどうかの設定もあるんですよね?
デフォルトは無効でしょうか?
私のところでは異常を検出することなく動いています。
これって、悪い意味のフォルトトレラントで動いているってことですよね。
動くと言っても、セキュリティホールを開けたままでは嬉しくないですね。


タイガージェットシーン さん 2005年 03月 08日 13時 12分 09秒

TO ちゃっぴ さん 2005年 03月 07日 21時 28分 11秒

ちゃっぴ さま
ご返答有難うございます。

> Remote Machineで任意のCodeを実行したいというのであれば、
> Win32_Process Class に Create Methodなるものが存在します。

Win32_Processクラスを利用して、以下のスクリプトを完成する
ことが出来ました。

strCMD = InputBox("リモートで実行するコマンドを入力して下さい。")

Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objSWbemServices = objSWbemLocator.ConnectServer (strComputer, _
            strNameSpace, strUser, strPass)
Set RemoteCom = objSWbemServices.get("Win32_Process")
rc = RemoteCom.create("cmd.exe /c " & strCMD)

今のところ、リモートマシン上でコマンドが実行されているようです。
有難うございました。またよろしくお願い致します。

ちゃっぴ さん 2005年 03月 07日 21時 28分 11秒

To タイガージェットシーン さん 2005年 03月 07日 14時 15分 17秒

> VBS上で前回はVBS上でDOSコマンドを実行する方法を
> 質問させていただきましたが、リモートマシンにDOSコマンド
> を実行する方法はありますでしょうか。

惜しいところまではいってますので・・・
Remote Machineで任意のCodeを実行したいというのであれば、
Win32_Process Class に Create Methodなるものが存在します。

また、Pingを打つのであれば、Win32_PingStatusなるものも
存在します。



タイガージェットシーン さん 2005年 03月 07日 14時 15分 17秒

以前質問させていただきました者です
(魔界の仮面弁士さま。。その際は有難うございました。)

VBS上で前回はVBS上でDOSコマンドを実行する方法を
質問させていただきましたが、リモートマシンにDOSコマンド
を実行する方法はありますでしょうか。
リモートマシンのホスト名、adminユーザ、Passwdを指定して
行えれば幸いです。

イメージとしては。

Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objSWbemLocator.ConnectServer (strComputer, strNameSpace, strUser, strPass)

Set wShell = CreateObject("WScript.Shell")
Set oExec = objWMIService.wShell.Exec("cmd.exe /c ping 192.168.0.1")

上記スクリプトでは、「そんなメソッドはない」とエラーが出ます。

宜しくお願いします。

むちゃ さん 2005年 03月 07日 13時 58分 48秒

To: ばんのしゃーによかばんた さん

> >むちゃ さん 2005年 03月 04日 01時 17分 14秒
> >実は、HTA(*.hta)で ExecWB メソッドを使用したいと思いまして・・・
>
> document.execCommand()で代替出来ませんか?

execCommand メソッドではだめなようです。
印刷関連(特に印刷プレビュー)の識別子がないので;;

> >後は、HTA(*.hta)でも window.status は生きているようなので >StatusTextChange イベントに接続して、
> >HTA(*.hta)の自作(擬似)ステータスバーに文字列を表示できるかなぁ・・・>と思っちゃったりもして。
>
> window.setInterval()
> で代替でしょうか。

以前はそれで(正確には setTimeout メソッド)やっていたのですが、
他の動作があまりにも遅くなったためにやめました。
(100ms 〜 500ms 間隔で window.stats の値を取得していました)

管理人により削除 さん 2005年 03月 07日 11時 16分 36秒
URL:管理人により削除

管理人により削除

管理人むたぐち さん 2005年 03月 06日 23時 37分 34秒

To: ばんのしゃーによかばんた さん

このスクリプトを実行すると、htaを実行する段階で
XP SP2のデータ実行防止機能が働いて途中で止まりました(汗

初めて見たなぁ、データ実行防止のダイアログ。

ばんのしゃーによかばんた さん 2005年 03月 06日 16時 01分 18秒

WSH/IE(HTM)連携では、HTMファイルなしで、VBSファイルだけで
IEの中にスクラッチ(about:blank)からHTMLDocumentが作れました。
しかし、WSH/HTA連携ではそういうことは出来ませんでしたよね。

ところが、驚くなかれ、HTAファイルなし、テンポラリファイルもなしに、
VBSファイルだけでWSH/HTA連携が出来ます。

F.VBS
――――――――――――――――――――――――――――――――――――――
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.StatusText="pipe"
ie.PutProperty "VBScriptTypeInfo",Me
Set wShell=CreateObject("WScript.Shell")
wShell.Run "MSHTA ""javascript:var Shell=new ActiveXObject('Shell.Application');var ies=new Enumerator(Shell.Windows());for (;!ies.atEnd();ies.moveNext()){var ie = ies.item();if(ie.GetProperty('VBScriptTypeInfo')) break;}if(!ie){alert('ie not found.');close();}var VBScriptTypeInfo=ie.GetProperty('VBScriptTypeInfo');VBScriptTypeInfo.WScript.Echo('from hta 1');VBScriptTypeInfo.WScript.Sleep(2000);VBScriptTypeInfo.WScript.Echo('from hta 2');ie.PutProperty('window',window);"""

Do While IsEmpty(ie.GetProperty("window"))
 WScript.Sleep 1000
Loop
Set window=ie.GetProperty("window")
ie.Quit
MsgBox window.document.documentElement.outerHTML
window.alert window.document.Title
Set window.document.body.onunload=GetRef("proc")
window.alert "hoge"
window.close
Do While htaStop=False
 WScript.Sleep 1000
Loop
WScript.Quit

Sub proc()
MsgBox "hta onunload"
htaStop=True
End Sub
――――――――――――――――――――――――――――――――――――――
これで、HTAはWSHの完全なフロントエンドですね。:-)

WSH/HTM連携なんかよりWSH/HTA連携のほうが遥かにパワフルで、
本命、最強の組合せ、ではありますまいか。

これは、もう魔道かもしれない。:-p


ばんのしゃーによかばんた さん 2005年 03月 06日 16時 00分 52秒

従前のCScript -e:VBS -は使えなくなりましたが、それに代わる、
1行スクリプトのアイデアが閃きました。

コマンドプロンプトで、

MSHTA javascript:alert('hoge');close();

MSHTA javascript:confirm(prompt('hoge','fox'));close();

MSHTA vbscript:close(msgbox("hoge"))

MSHTA vbscript:close(msgbox(inputbox("hoge")))

MSHTA vbscript:execute("msgbox(""hoge""):close")

MSHTA "about:<script>alert('hoge');close();</script>"

MSHTA "about:<input type=file onchange=alert(this.value)>"

IExplore "about:<input type=file onchange=alert(this.value)>"

IExploreはセキュリティレベルの制約があるので、MSHTAがいいですね。


ばんのしゃーによかばんた さん 2005年 03月 06日 16時 00分 23秒

WSHとHTAの間でオブジェクトをIEの何処に入れて受け渡すか?

これまでは、HTMLDocumentのeventプロパティを使ってましたが、
今回は、IEのPutProperty/GetPropertyを使ってみました。

D.VBS
――――――――――――――――――――――――――――――――――――――
Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.PutProperty "VBScriptTypeInfo",Me
Set wShell=CreateObject("WScript.Shell")
wShell.Run Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"."))&"HTA"
Do While IsEmpty(ie.GetProperty("window"))
 WScript.Sleep 1000
Loop
Set window=ie.GetProperty("window")
ie.Quit
MsgBox window.document.documentElement.outerHTML
window.alert window.document.Title
Set window.document.body.onunload=GetRef("proc")
window.alert "hoge"
window.close
Do While htaStop=False
 WScript.Sleep 1000
Loop
WScript.Quit

Sub proc()
MsgBox "hta onunload"
htaStop=True
End Sub
――――――――――――――――――――――――――――――――――――――
D.HTA
――――――――――――――――――――――――――――――――――――――
<html><head><title>HTA TITLE</title>
<script language="VBscript">
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows
 If Not IsEmpty(ie.GetProperty("VBScriptTypeInfo")) Then Exit For
Next
If IsEmpty(ie) Then
 alert "ie not found."
 close
End If
Set VBScriptTypeInfo=ie.GetProperty("VBScriptTypeInfo")
VBScriptTypeInfo.WScript.Echo "from hta 1"
VBScriptTypeInfo.WScript.Sleep 2000
VBScriptTypeInfo.WScript.Echo "from hta 2"
ie.PutProperty "window",window
</script>
</head></html>
――――――――――――――――――――――――――――――――――――――
このIEのPutProperty/GetPropertyは、汎用のshared memory用途に
使えそうです。


ばんのしゃーによかばんた さん 2005年 03月 06日 15時 59分 55秒

>門外漢 さん 2005年 02月 26日 21時 35分 52秒
>工夫すればさらに信頼済みサイトゾーンも可能です。

これは、どうも駄目みたいです。XP SP2

>・イントラネットゾーン

これは、可能ですね。

しかし、セキュリティゾーンの偽装を許す危険な仕様ではないでしょうか?

<!-- saved from url=(0017)http://localhost/ -->
を埋め込んだページをインターネットに置いておくと、
ローカルにそのまま取り込んだときに、イントラネットゾーンで動きます。
マイコンピュータゾーンのロックダウンも効きません。

ところで、WEBページをローカルに保存すると、NTFSの場合にはファイルに
ZoneIDが付けられると聞いたのですが、どこにあるのでしょう?
ZoneIDの表示や判別方法はあるのでしょうか?


ばんのしゃーによかばんた さん 2005年 03月 05日 17時 26分 33秒

>むちゃ さん 2005年 03月 04日 01時 17分 14秒
>実は、HTA(*.hta)で ExecWB メソッドを使用したいと思いまして・・・

document.execCommand()で代替出来ませんか?

>後は、HTA(*.hta)でも window.status は生きているようなので >StatusTextChange イベントに接続して、
>HTA(*.hta)の自作(擬似)ステータスバーに文字列を表示できるかなぁ・・・>と思っちゃったりもして。

window.setInterval()
で代替でしょうか。

――――――――――――――――――――――――――――――――――――――
>ちゃっぴ さん 2005年 03月 03日 23時 53分 03秒
>遊んでしたら、こんなのが見つかりました。

あるんですね。こういうものが。


ばんのしゃーによかばんた さん 2005年 03月 05日 17時 25分 48秒

>ばんのしゃーによかばんた さん 2005年 03月 02日 16時 16分 51秒
>以前、WSH/WSF/VBS/JSなどのIconHandlerにSCFのものを使う話をしました。
>>ただ、指定のない大多数のファイルがアイコンなしアイコンになってしまうので、
>という問題がありました。これは、URLのものを使うと、よいようです。

駄目ですね。:-<

レジストリにDefaultIconキーがあるので、効くのか、と思ったら、
固定のアイコンしか表示されません。:-<

そもそも、
良く言えば、リンクを作れば、アイコンが変えられる。
悪く言えば、アイコンを変えるには、リンクを作らなければならない。
というのがおかしいと思いません?

任意のファイルで、プロパティでアイコンが変更できればよいのに。
設定情報は、.WSHのような別ファイルではなく、
\05SummaryInformationのようにStreamに入れる。
こういうIconHandlerとPropertySheetHandlerがあればよいに。


Ω さん 2005年 03月 05日 14時 02分 54秒

はじめまして。最近WSHを勉強しているものです。
いきなり質問です。
WSHでwinの環境変数に追加したいと考えています。

Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Exec("set ZZZ=yyy")

を実行しても環境変数に追加されていません。
どうしてでしょうか?

どうしたらうまくいくのでしょうか?

ATH さん 2005年 03月 05日 13時 36分 13秒

To: むちゃさん ばんのしゃーによかばんた さん
はじめまして 興味がわきましたので。

pipeのieを生かしておけば、HTAのフロントエンドが常に浮かんだ状態でも
任意起動のスクリプトからドライブできるっていう事でいいんですよね。

sei さん 2005年 03月 04日 23時 51分 02秒

すんません ぼけてました
>定数と変数では扱いが異なることからVBSでの実装は
> 文字列定数:VARIANT
> 文字列変数:VARIANTへのポインタ(LPVARIANT)  ← VT_BYREFです
>になっているように思います。


1つの書きこみで2つ言うのわルール違反ですが

KOU さん へ

{SPACE}表記はもともとないのでわ?手もとの資料でも記述がないし
スペースは特殊な文字でもないので対応する必要がないような。
ちなみに私もエラーが出ました。(Win98)

KOU さん 2005年 03月 04日 15時 48分 55秒

ooさん、ありがとうございます。

WshShell.Sendkeys(" ")

↑で出来ました。chr(13) や chr(8)でも試してみようと思います!!

oo さん 2005年 03月 04日 15時 34分 40秒

>WshShell.Sendkeys("{SPACE}")

WshShell.Sendkeys(" ") でできますよ。
他の制御文字に付いても、"{ENTER}" や "{BS}" でなく chr(13) や chr(8) のように書いてもいけるようです。

KOU さん (f04a207@tmail.shinshu-u.ac.jp) 2005年 03月 04日 13時 02分 49秒

はじめまして。Sendkeysについて、お聞きしたい事がありましたので投稿させて頂きました。
Sendkeysを使って、Spacebarをストロークさせたいのですが,
    
WshShell.Sendkeys("{SPACE}")

↑のように書いても、エラーが出てしまいます。
ENTERは{ENTER}や~など,キーに対応したコードがあるようですが,Spacebarに対応したコードが見つかりません。Sendkeysでは、Spacebarをストロークさせることはできないのですか?

sei さん 2005年 03月 04日 02時 26分 28秒

ちょいと口挟み。以前&hffff問題を解決していただいたものです。
Dynacallのパラメータ挙動でVARIANT型の変換に悩んだものとして
ちょっと前に話題になさっていた InvokeVerb を定数の扱いから
類推してみました。
環境はWIN98ですがこの辺は多分変わらないとふんでます。

これを追試験するのはかなり面倒なので結果だけを書きますと
DynaCallでDLLに文字列引数をLPWSTRとして渡すと
 文字列定数:文字列へのポインタそのもの(BSTRのアドレス)
 文字列変数:VT_BSTRへのポインタ(=VARIANTへのポインタ)
がDLLに渡されます。
これにかかわる部分をDYNWRAP.CPPで見るとVBSからの引数の
VARIANTに格納してある実体を単純に渡しているだけです。

定数と変数では扱いが異なることからVBSでの実装は
 文字列定数:VARIANT
 文字列変数:VARIANTへのポインタ(LPVARIANT)
になっているように思います。

またこの予想があっていれば VBSはDispatch I/Fに 現在自分が取り出せる
VARIANTを参照など関係なく渡していると考えられます。

InvokeVerb の引数がおかしいのは VARIANTを引数にすることは本来VBSでは
出来ないことからVBSのための実装になっていないせいだと考えています。

私の当て推量があっていればこの問題はVBSとオートメーションオブジェクトの
どっちに非があるとは言えないような。


ちなみにDynWrapの引数の扱いがわかったのでほとんどのWin32API使えるように
なりました。HTAを使って窓操作が(見かけ上は)簡単に出来るようになって
うれしー。VBSの解析にも結構使えます。苦労した甲斐がありました。

ちゃっぴ さん 2005年 03月 04日 01時 39分 42秒

ちょっと興味がありまして・・・

皆さんは、Script を書くときにどういう Editor を使っていますか?

私は、VBA もしくは、VB の Editor で単体Test(出来れば)を行って、
そこからWSHとかに落としてやる("As"を"'As"で置換)な感じで
作成することが多いですが・・・

なんか、効率的な WSHの作成方法、および Debug方法がありましたら
ご教授願います。(*- -)(*_ _)ペコリ

むちゃ さん 2005年 03月 04日 01時 17分 14秒

To: ばんのしゃーによかばんた さん

> >むちゃ さん 2005年 03月 02日 15時 38分 40秒
> >起動している HTA(*.hta) の InternetExplorer Object(WebBrowser Object)を取得することはできないでしょうか?
>
> なので、苦労します。:-< 例えば、データの遣り取りは、
>
> 中略・・・
>
> WSHからIE/HTMを自由自在に操作できたように、
> WSHからHTAをフロントエンドとして自由自在に操作できます。
> ブラボー!

ほうほう、IE を中継して操作ですか・・・
これはすごいですね(^-^)

> うーん、だんだんよく分からない世界になって来ましたね。
> ここまで来ると邪道というより極道かも。:-p

そうですね。
読み始めは、「???」とよくわかりませんでしたので、
じっくりと拝見させていただきました。(笑)


> なので、苦労します。:-< 例えば、データの遣り取りは、

やはり、HTA の場合、
Shell.Application の Window コレクションから取得できないことから、
InternetExplorer Object(WebBrowser Object)は取得できないみたいですね。

実は、HTA(*.hta)で ExecWB メソッドを使用したいと思いまして・・・
IE(*.html)では自分の InternetExplorer Object を取得して実行が可能なのですが。

後は、HTA(*.hta)でも window.status は生きているようなので StatusTextChange イベントに接続して、
HTA(*.hta)の自作(擬似)ステータスバーに文字列を表示できるかなぁ・・・と思っちゃったりもして。

ですが、根本的に取得が出来なかったので手をこまねいていたのです。

ちゃっぴ さん (masa-eno@deluxe.ocn.ne.jp) 2005年 03月 03日 23時 53分 03秒

To ばんのしゃーによかばんた さん 2005年 02月 15日 17時 29分 32秒

WMIを扱う上で便利なTool ScriptOmatic が VersionUp したので

http://www.microsoft.com/downloads/details.aspx?FamilyID=09dfc342-648b-4119-b7eb-783b0f7d1178&DisplayLang=en

遊んでしたら、こんなのが見つかりました。

Dim objWMIService  ' As WbemScripting.SWbemServices
Dim colItems    ' As WbemScripting.SWbemObjectSet
Dim objItem     ' As WbemScripting.SWbemObject
Dim strBuf()    ' As String
Dim i        ' As Long

Set objWMIService = GetObject( _
  "winmgmts:\\.\root\CIMV2\Applications\MicrosoftIE")

Set colItems = objWMIService.ExecQuery( _
  "SELECT Zone, Level FROM MicrosoftIE_Security")

ReDim strBuf(colItems.Count)
i = 0

For Each objItem In colItems
  With objItem
    strBuf(i) = .Zone & vbTab & .Level
  End With
  i = i + 1
Next

WScript.Echo Join(strBuf, vbLF)

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

>むちゃ さん 2005年 03月 02日 15時 38分 40秒
>起動している HTA(*.hta) の InternetExplorer Object(WebBrowser Object)を取得することはできないでしょうか?

なので、苦労します。:-< 例えば、データの遣り取りは、

>ばんのしゃーによかばんた さん 2005年 02月 12日 19時 39分 08秒
>一方、WSHとHTAの連携は、と言えば、標準入出力のパイプ以外は難しく、
>それも自由度がないので、あまり使えません。
>そこで、IEをパイプ代わりにして、WSH-(IE)-HTAの連携を試してみました。

今回、更に、WSHとHTA間で、相互に相手の関数を呼び出してみました。:-)

B.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.Title="pipe"
Set wShell=CreateObject("WScript.Shell")
wShell.Run Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"."))&"HTA"
ie.Document.body.innerText="MsgBox ie.Document.Title"
Do While ie.Document.body.innerText<>""
 WScript.Sleep 1000
Loop
Set ie.Document.body.ondblclick=GetRef("proc")
ie.Document.body.onclick
ie.Document.body.innerText="close"
Do While ie.Document.body.innerText<>""
 WScript.Sleep 1000
Loop
ie.Quit
WScript.Quit

Sub proc()
MsgBox "proc from hta"
End Sub
――――――――――――――――――――――――――――――――――――――
B.HTA
――――――――――――――――――――――――――――――――――――――
<script language="VBscript">
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows
 If TypeName(ie.Document)="HTMLDocument" Then
  If ie.Document.title="pipe" Then Exit For
 End If
Next
If IsEmpty(ie) Then
 alert "ie not found."
 close
End If
Set ie.Document.body.onclick=GetRef("htaproc")
setInterval "proc",1000
Sub proc()
If ie.Document.body.innerText<>"" Then
Execute ie.Document.body.innerText
ie.Document.body.innerText=""
End If
End Sub
Sub htaproc()
MsgBox "call from wsh"
ie.Document.body.ondblclick
End Sub
</script>
――――――――――――――――――――――――――――――――――――――
※pipeのIEをクリックしてはいけません。:-p
なので、非表示にしておいたほうがいいですね。

更に、更に、WSHとHTA間で、
相互に相手内のオブジェクトを参照/操作できます!

HTAからWSHのWScript.Sleep/Echoを呼び出したり、
WSHの関数をGetRefしてHTAのbody.unload Eventに接続したり。

C.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.Title="pipe"
Set ie.Document.body.ondblclick=Me
Set wShell=CreateObject("WScript.Shell")
wShell.Run Left(WScript.ScriptFullName,InStrRev(WScript.ScriptFullName,"."))&"HTA"
Do While IsNull(ie.Document.body.onclick)
 WScript.Sleep 1000
Loop
Set window=ie.Document.body.onclick
ie.Quit
MsgBox window.document.documentElement.outerHTML
window.alert window.document.Title
Set window.document.body.onunload=GetRef("proc")
window.alert "hoge"
window.close
Do While htaStop=False
 WScript.Sleep 1000
Loop
WScript.Quit

Sub proc()
MsgBox "hta onunload"
htaStop=True
End Sub
――――――――――――――――――――――――――――――――――――――
C.HTA
――――――――――――――――――――――――――――――――――――――
<html><head><title>HTA TITLE</title>
<script language="VBscript">
Set Shell=CreateObject("Shell.Application")
For Each ie In Shell.Windows
 If TypeName(ie.Document)="HTMLDocument" Then
  If ie.Document.title="pipe" Then Exit For
 End If
Next
If IsEmpty(ie) Then
 alert "ie not found."
 close
End If
Set vbglobal=ie.Document.body.ondblclick
vbglobal.WScript.Echo "from hta 1"
vbglobal.WScript.Sleep 2000
vbglobal.WScript.Echo "from hta 2"
Set ie.Document.body.onclick=window
</script>
</head></html>
――――――――――――――――――――――――――――――――――――――
WSHからIE/HTMを自由自在に操作できたように、
WSHからHTAをフロントエンドとして自由自在に操作できます。
ブラボー!

うーん、だんだんよく分からない世界になって来ましたね。
ここまで来ると邪道というより極道かも。:-p


管理人により削除 さん 2005年 03月 03日 13時 22分 07秒
URL:管理人により削除

管理人により削除

管理人により削除 さん 2005年 03月 02日 22時 03分 24秒
URL:管理人により削除

管理人により削除

Return