Kei さん 2003年 07月 04日 14時 10分 09秒

はじめまして。
WSHをいじり始めたばかりの初心者ですがよろしくお願いします。
こちらのはサイトは、説明も分かり易くサンプルも多いので、
とても参考になります(^^)

〜 はなぶささんへ 〜

外してるかもしれませんが、ループ処理をするのであれば
Do...Whileステートメントが使えるのでは?

いりや さん 2003年 07月 04日 12時 27分 07秒

萌さん、

> 会社のパソコンなのであまりそういったソフトを
> 勝手に入れたりすると、後々、面倒なことにもなりかねませんの
> で、私にはそれは積極的には使えない方法でした(^^;

なるほど、仕事で使用する環境が前提の場合は、おっしゃる通り違った観点
での配慮 (フリーソフトウェアを公式に許していない PC 環境だってありま
すもんね!) が必要になる場合がありますから、積極的にはきびしいものが
ありますね。。

はなぶさ さん (hmiyake@tba.t-com.ne.jp) 2003年 07月 04日 12時 04分 42秒

萌 さん、ご返事ありがとうございます。
一般論でなく、具体的に書こうと思いますのでよろしくお願いします。
ただ、具体的にかけたかどうかは心配ですが。
Dim WSHShell
Dim strRet
Dim intMsg
Const ForReading = 1,ForWriting = 2,ForAppending = 8 '定数の指定Set
Set WSHShell = WScript.CreateObject("WScript.Shell")
'ここにラベルを書く label1 とでもします
WSHShell.Run "c:acb.exe", 1, true
WSHShell.Run "c:bcd.exe", 1, true
Set Fs = WScript.CreateObject("Scripting.FileSystemObject")
Set oTs1 = Fs.OpenTextFile("c:xyz.dat",ForReading)
sLine = oTs1.ReadLine '上記二つのexeを実行した結果のファィルを1行読み
'そのデータ− sLine が 0 なら、goto を実行 1 なら vbs を終了するわけですが
oTs1.Close 'oTs1を閉じる
if ( sLine == 0 ) { goto label1 }
else {
WScript.Echo(" VBS を終了します")
WScript.Quit }

としたいのです、つまり、c:xyz.datの中の数値が 1 になるまで
無限ループします。
以上よろしくお願いします。


さん 2003年 07月 04日 11時 29分 20秒

To はなぶさ さん

構造化プログラムではGoto文はスパゲッティコードに
なる元凶だと忌み嫌われ、使わないのが通説となっています。

ただ、二重ループを抜けるとかそういう特殊なケースで
使うのであればトリッキーじゃないと私は認識しています。

もっと趣旨を明確にしないと適切なレスは付かないと思いますよ。
私のように一般論には一般論でしか回答のしようが無いかと。




はなぶさ さん (hmiyake@tba.t-com.ne.jp) 2003年 07月 04日 09時 43分 00秒

どなたか助けてください。ばかばかしい質問と思わずよろしくお願いします。
そけは VBS で単純 goto 文はどう書くのでしょうか、つまり、あるところまで
実行したら、そこで goto abc(abc をラベル又は飛び先として)その abc に
戻りたいのです。;abc とか akc: とか書いてみましたがエラーです、
それとも vbs では条件分岐には if や switch や for しか使えないので
しょうか。よろしくご教授お願いします。


さざなみ さん 2003年 07月 03日 13時 46分 36秒

さざなみです。

あさじゃけん さん
> って、googleで検索したら、ここのサイトにあったっぽいです。ちょっとだけ(笑)

そうです。
自分もここで知りました。
で、他のメソッドを調べようとすると、日本語以外のサイトなので扱いかたがよく
わからなかったり。。。

さん 2003年 07月 03日 13時 09分 00秒

To いりやさん

こんにちは、萌です。

会社のパソコンなのであまりそういったソフトを
勝手に入れたりすると、後々、面倒なことにもなりかねませんの
で、私にはそれは積極的には使えない方法でした(^^;

でも、参考にさせて頂きました。

そこまでは考えていなかったんです、
VBでEXEを作ってWM_CLOSEを送信すればそれで終わりなのですが、
ランタイムを付けたりといろいろと面倒でしたので、
スクリプトで対応できないかと思っていたところでした。

ほんの数回程度しか使ったことが無かったので何もしりませんでした。
SendKeysまでWSHは使えたのですね、それに、GetObjectも使えたなんて(^^

Set objApp = GetObject("パス")
objApp.Quit

これで終了確認致しました。

あまり役に立つようなTipでもないのですが、
ログに残ればもしもの時の参考になるかと思い
挙げさせて頂きました。


いりや さん 2003年 07月 03日 12時 28分 53秒

萌さん、

はじめまして、いりやと申します。

| ただ、起動中のアプリを取得するのはCreateObjectではなく
| 通常はGetObjectだと思います、WSHでは使えないのでCreateObject
| でそうするしかないのでしょうね(^^
|
| このようなApplicationオブジェクトを取得する方法ではなく、
| FileSystmObjectとかのWSHに特化した機能で実現
| できたら良いなと思っていたのですが、ダメみたいですね(^^

Microsoft Component Object Model に沿ってアプリケーションの起動停止を
制御する、Windows プロセスの起動停止をシェルなどから制御する、といっ
た方法の他に、実はもう一つアプローチがあります。

それは、GUI の閉じる操作を人間の代りに誰かが代行するというものです。
ベクターさんにも一度特集が組まれましたが、操作の自動化ソフトと分類さ
れているソフトウェアです。
http://www.vector.co.jp/magazine/spotlight/030521/sl0305211.html

こういったソフトウェアを使用すれば、「ファイルメニューの(閉じる(&
Q))を選ぶ」とか「ALT+F+Cのキーを順番に押す」とか「アプリケー
ションに WM_QUIT メッセージを送る」といったような操作 (或は処理依頼)
をソフトウェアに代行させることが可能となります。

Windows Scripting Host にもそのような機能が一部備わっていたと記憶して
います。AYA さんの "Windows Scripting Host 2.0" レクチャをご参照くだ
さい。
http://member.nifty.ne.jp/aya/wsh/wsh205.htm

それから、ベクターさんの特集に掲載されている以外のソフトウェアの一つ
として UWSC というものがあります。
http://www002.upp.so-net.ne.jp/umiumi/

ソフトウェアに付属する "サンプル.uws" にはアプリケーションを閉じる操
作のデモンストレーションがあります。またサンプルの頁にも "// 開いてい
るウインドウを全て閉じる" という見出しで紹介がされています。
http://www002.upp.so-net.ne.jp/umiumi/sample.html

一度ご覧になってみることをおすすめします。

さん 2003年 07月 03日 10時 53分 19秒

To あさじゃけん さん

>えーと。質問の意味がよくわからないのですが・・・・
>ひょっとしてExcelで普通に開いているファイルを閉じるってことなんでしょうか・・・・

そうです、その通りです。

>私もやったことないので、はっきりとは言えませんが、
>Set objExcel=WScript.CreateObject("Excel.Application")
>とかでオブジェクトを作成し、現在開いているファイルをActiveWorkbookで>取得し、閉じるメソッドCloseとかQuit(でいいのかな?)を呼び出す感じになるでしょう。

例ではExcelになっていますが、これに特化したものではないのですが、
ExcelだとするとExcel.Applicationオブジェクトを使わなければならない
という事ですね、Shellでopenがあるので閉じるもcloseでできるかとやって
みましたがこれはダメでした(^^ゞ

ただ、起動中のアプリを取得するのはCreateObjectではなく
通常はGetObjectだと思います、WSHでは使えないのでCreateObject
でそうするしかないのでしょうね(^^

このようなApplicationオブジェクトを取得する方法ではなく、
FileSystmObjectとかのWSHに特化した機能で実現
できたら良いなと思っていたのですが、ダメみたいですね(^^

残念ですが、これは諦めます(^^

あさじゃけん さん 2003年 07月 03日 09時 45分 58秒

>さざなみさんへ

Shell.UIHelperの事、初めて知りました(汗)
勉強になります^^;;;
サイトは・・・私も教えて欲しいですねぇ(笑)
って、googleで検索したら、ここのサイトにあったっぽいです。ちょっとだけ(笑)
http://www.roy.hi-ho.ne.jp/mutaguchi/wsh/object/uihelper.htm


>萌さんへ
えーと。質問の意味がよくわからないのですが・・・・
ひょっとしてExcelで普通に開いているファイルを閉じるってことなんでしょうか・・・・
「開く」の間違いじゃないですよね?(汗)

私もやったことないので、はっきりとは言えませんが、
Set objExcel=WScript.CreateObject("Excel.Application")
とかでオブジェクトを作成し、現在開いているファイルをActiveWorkbookで取得し、閉じるメソッドCloseとかQuit(でいいのかな?)を呼び出す感じになるでしょう。
Excel.Applicationで過去ログ探せば、いっぱいサンプルありますよ。^^

さん 2003年 07月 02日 11時 38分 34秒

WSHからパスを指定したファイルを閉じることができますか?

何も分らず、イメージだけで書いてみたのですが(^^ゞ

Set FS = CreateObject("Scripting.FileSystemObject")
Set F = FS.GetFile("D:\sample.xls")
F.Close

ファイル名は固定でいいのですが、何か方法がございますか?

どうぞよろしくお願いします。

さざなみ さん 2003年 07月 02日 10時 14分 34秒

さざなみです。

お早いレスありがとうございます。

> むたぐちさん
> お気に入りフォルダの場所は、WshShell.SpecialFolders("Favorites")で
> 取れますが、AddFavoriteメソッドはダイアログを出してFavorites配下の
> 好きなフォルダに保存できるので、その場所をあらかじめ把握することは
> できないと思われます。

AddFavoriteメソッドを使用する前後に
ImportExportFavoritesメソッドでブックマークをインポートして
前と後ろのブックマークを比較する方法を考えていたのですが
どうも非現実的な感じがしたので。。。。

> ので、フルパスを知りたい場合は、UIHelperを使うのをやめて、WshShell.CreateShortcutを
> 使ってインターネットショートカットを作ってやる方が良いんじゃないでしょうか。

やはりこの方が簡単ですね。

> ShowBrowserUIメソッドってなんでしたっけ?

お気に入りの整理ダイアログを表示してくれますけど。。。?

Set ShellUIHelper = WScript.CreateObject("Shell.UIHelper")
ShellUIHelper.ShowBrowserUI "OrganizeFavorites",0
Set ShellUIHelper = nothing

あと、他のメソッドに関する日本語の解説ページをご紹介いただければ、幸いです。

あさじゃけん さん 2003年 07月 02日 09時 59分 19秒

>むたぐちさんへ

> WSHからXMLDOMを扱う方法
わかりやすかったでしょ?(笑)
むたぐちさんが言うように、ちょっとしたデータを簡単に処理できるので、結構便利かもです。
ただ、そのXMLデータを作るのがめんどくさかったりします(笑)
#探せばエディタぐらいあるのかな?^^;;;
#今のところメモ帳だしなぁ・・

しっかし、誰も反応しないから、みんなXML興味ないんだなぁと思った矢先、さすがむたぐちさん(笑)ありがとうございます。(紹介したかいがありますな。^^)

> Perl Socket
いえいえ、気にしないで下さい(笑)
会社のマシンで、遠隔するために24時間立ち上げっぱなしのクライアントがあるので、必要なときだけ起動できるようにしたくて・・・
でも、全従業員、賞与1/5支給というトンでもないカットくらったので、会社辞めるつもりです(泣)(まぁ理由はほかにもありますが)
で、結局、必要なくなりそう(爆)

> ノートン
私も使って嫌いになりました(笑)
初めて買ったんですけど、使いにくいったらありゃしない。しかも値段が高い。(><
まぁ、ウィルスバスターよりは機能豊富だけど・・・
買った後にAVGの存在知ったので、落胆してたとこです。
#サブマシン用に買わなくて良かった・・・

> Friend
あぁ、ありましたねぇ。そんなのが(笑)
って言うぐらい使わない(^^;;;
私はちなみに、「Property Let」の用法はちょっと無理があるような気がします。
無理にFriend使う必要はなく、クラス内で十分できる処理ですし。
オブジェクト指向的にはPublicとPrivateがあれば、十分だと思ってます。
#設計するときは、Friend使う設計する時点で間違っていると思ってます(笑)
#誰か反論希望(爆)

Friendだからこその利点ってあるんですかね?^^;;
#あとからやむを得なく追加、変更するのが利点だったり(^^;;

> Collectionオブジェクト
VBSで使えないの不便ですよねぇ・・・
実は、完全にclsCollectionじゃないですけど、ある処理に特化したCollectionクラスもどきを作ったことあります。(もちろんDictionary使って)
VBSのヘルプ見ても、「VBA の機能で VBScript に含まれていない機能」の項でしっかり書いてあるし。(><

> ワイルドカードを含む文字列を与えると、マッチしたFileオブジェクトあるいは
> Folderオブジェクトの格納された1次元配列を返すような関数にすれば
> 使い勝手が良さそうです。
ワイルドカードじゃないですが、簡単な条件式でDictionaryオブジェクトを返す関数作ったことあります。(指定フォルダからFileSystemObjectで再帰的に検索。フルパスファイル名格納)
しかし、処理をするとなると、一度、全フォルダを走査してから、またDictionaryオブジェクトを走査しなければならないので、処理時間がかかり、使えない関数になってしまいました(爆)

取得した一覧を、何度も何度も参照する必要があるプログラムなら有効かも知れません。
今なら、条件部分を正規表現にしてやれば、もちっと使い勝手よくなるかな?(汗)


管理人むたぐち さん 2003年 07月 01日 20時 39分 10秒

To: あさじゃけん さん

> WSHからXMLDOMを扱う方法

私自身は、MSXMLはこれまでほとんどxmlhttpしか使ってないだけに、参考になります。
WSHからXMLDOMを扱うケースはそれほどないと思ってましたが、
この例を見てると、ちょっとしたデータファイルにXMLを使うと便利かもという
気になってきました。

MSDNにも記事があったので一応。
初心者のための XML DOM ガイド
http://www.microsoft.com/japan/msdn/xml/general/beginner.asp

> Perl Socket

ぼちぼちやってますんで、あまり期待しないでください〜。
PerlScriptというかWSCの方に興味がいっちゃったもんで、PerlSocketは
後回しになってたりします。


To: つちや さん

ちなみに私はノートンが大っ嫌いです。
理由は言わずもがな(w

私もあさじゃけんさんと同じく、AVG 6.0 Free Editionを使ってます。

> WSC

ちょっと諸事情でまた開発環境がWin2000に戻ってますんで、確認できないです。
何か条件とかあるんですかね?

ちなみに、GetObjectの方法というのは、
Set hoge=GetObject("script:C:\nantoka.wsc")
で良いんですよね?
私、この方法すっかり忘れてましたが、レジストリに触らず(ProgID/ClassIDを登録せず)利用できるという
意味では有用ですねコレ。
(ただ、なんかよくわからないですが、そこらへんにあった適当なWSCをGetObject
してみたら上手くいかなかったです。それはちゃんと登録もしてるしCreateObjectできる奴なんですが。
WSCの書き方がまずいのかな?)


To: ヒデ さん

> Regeditを起動してキーのコピーをしたんですが
> それでは貼り付けてもなぜか二重にはならないんです。

というか、キーじゃなくて「名前」を読む必要があるからですね。
よーくレジストリを眺めてみてください。
ComputerNameキーの下にある、ComputerNameキーの下にある、ComputerNameという「名前」の
「値」を読む必要があるので、キーをコピーしただけじゃ駄目なわけです。

キー(最後が\で終わるもの)をRegReadすると、そのキーの「(標準)」の値が読み込まれる
仕様ですが、
HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ComputerName\ComputerNameキーの
「(標準)」の値は「(値の設定なし)」なので、読み込みは上手くいきません。
このキーの「ComputerName」の値を読んでやる必要があるわけですね。

「名前」の値を読むのも、キーの「(標準)」の値を読むのと書式が一緒なのがRegReadメソッド
の特徴でして(キーの場合は最後に\をつける)、「ComputerName」の値を読むには、
"HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\ComputerName\ComputerName\ComputerName"
と指定してやることになります。

ComputerNameは、キーと名前が一緒だったり、キーが二重になったりしてややこしいですが、
本質はそういうことです。


To: らいど さん&いりや さん

フレーム関係の話は、クロスドメインセキュリティ機構だの何だのがあって、
結構ややこしいですよね。
今回のケースは変数のスコープの問題だったようですが。
兎にも角にも、解決したようで(?)よかったです。


To: さざなみ さん

> Shell.UIHelperのAddFavoriteメソッドやShowBrowserUIメソッド
> で追加、変更された、フォルダーやインターネットショートカットの
> フルパスを取得したいのですが、一般的にどのようにすればいいでし

お気に入りフォルダの場所は、WshShell.SpecialFolders("Favorites")で
取れますが、AddFavoriteメソッドはダイアログを出してFavorites配下の
好きなフォルダに保存できるので、その場所をあらかじめ把握することは
できないと思われます。
ので、フルパスを知りたい場合は、UIHelperを使うのをやめて、WshShell.CreateShortcutを
使ってインターネットショートカットを作ってやる方が良いんじゃないでしょうか。

ShowBrowserUIメソッドってなんでしたっけ?


To: 神 さん

> ワイルドカードを含む任意のファイル名から、実在するファイル名を取得したいのですが

VBSやFileSystemObjectにはワイルドカードを展開する機能はありません。
(せいぜいDeleteFileメソッドなどの引数に使えるくらいですね)
ので、そういうコードを書いてやる必要があります。
(もちろんFileSystemObjectを併用しないと書けないわけですが)
テーマ的にも面白そうなので、ぜひチャレンジしてみてください。

ワイルドカードを含む文字列を与えると、マッチしたFileオブジェクトあるいは
Folderオブジェクトの格納された1次元配列を返すような関数にすれば
使い勝手が良さそうです。
というか、すでに誰かが作っていそうな気もします。探してみるのもいいかも。

管理人むたぐち さん 2003年 07月 01日 17時 59分 07秒

●VBSでクラスを作成する - Class ステートメント Part.2

※http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list84.shtmlの
 2003年 06月 16日 21時 07分 10秒の記事の続編です

前回、VB6のクラスモジュールにできて、VBSのClassステートメントにはできないこととして、
次の三点を挙げました。すなわち、

1.プロパティやメソッドの引数に型が指定できない
2.インターフェイス実装ができない
3.イベントが使えない

今回は、Classステートメントを色々弄ってみて、さらに気づいた不可能項目を2個追加します。


4.コレクションクラスが作成できない

まず、VBでコレクションクラスを作成する方法は、VBのヘルプに詳説がありますのでそちらを
参照してください。
コレクションの作成方法
http://www.microsoft.com/japan/developer/library/vbcon98/vbconcreatingyourowncollectionclasses.htm

一方VBSでは、
Private(/Public) hogehoges As New Collection
という記述ができないため、VBのように、Collectionオブジェクトを利用する
方法は使用できないわけです。

ただし、Collectionオブジェクトの代わりにDictionary(Scripting.Dictionary)オブジェクトを
併用して、コレクションクラスもどきを作成するというテクもあります。
こちらをご覧ください。
 aspZone.com - ASP File Upload using VBScript http://www.aspzone.com/articles/john/aspUpload/

ここで用いられているclsCollectionクラスは、Dictionaryオブジェクトを使うことで
擬似的なコレクションクラスを実現しています。
概念的には、先ほど示したVBヘルプにおける、「プライベート コレクションの例」に
近いものです。要するに、Class内で作成したDictionaryオブジェクトをPrivate変数に格納しておき、
外部からそこに値を格納したり、読み出したりする際はクラスのプロパティやメソッドを
通して行うわけです。

(Addメソッドに、値をvalidateするコードを加えるとさらにGoodですね。
というか、こういうコードを追加しないとわざわざClassにした意義が薄れるわけですが。
If IsObject(Value) And TypeName(Value)="clsNantoka" Then
 DictionaryにAddするコード
End If
のような感じで)

もちろん、clsCollectionクラスは本質的にはコレクションクラスではないので、
For Each...Nextで各値を取り出すことはできません。

ただ、Itemsメソッドを定義して、Dictionaryの各値が格納された1次元配列を返すように
しておけば、実用上はほぼ問題ないと思います。
clsCollectionに次のコードを追加してください。

Public Function Items()
Items=m_objDicItems.Items
End Function

これで、クライアント側からは
For Each obj In oCollection.Items
...
Next
のようにして各値が取り出せます。Itemsがカッコ悪いですが我慢しましょう。

(For Each...Nextができるようにするためには、コレクションオブジェクト(この例では
Dictionaryオブジェクトだが同じことだ)の列挙子のIUnknownインターフェイスを返す
NewEnumメソッドをクラスに実装した上で、NewEnumメソッドを非表示メンバにし、
プロシージャIDを-4に設定するとヘルプにはあるのだが、VBSのClassステートメントでは
不可能…だと思う。ただ、Dictionaryオブジェクトの_NewEnumメソッドは、
VBSでもobjDictionary.[_NewEnum]のようにすれば実行可能だし、TypeName関数で
調べたところちゃんとUnknownクラスのオブジェクトが返って来ているので、
後はクラスで実装するNewEnumメソッドのプロシージャIDを設定できれば、
完全なコレクションが作成可能なんではなかろうか?
もっとも、Classステートメントでは無理そうだが、もしかするとWSCなら可能なのかも
しれない。というのも、WSCでは<method name="methodName" dispid=dispID>のように、
dispIDを指定することができるからだ。もっとも、DictionaryオブジェクトでFor Each...Next
した際に返って来るのはKeyのセットなので、clsCollectionのようにValueの方に
オブジェクトを入れるのではなく、Keyにオブジェクトを入れなきゃならないが(できるのか?)。
うん、何か大きな勘違いをしてなければ、できそうだぞ。これ、後で試してみよう)

(さらに余談ですが、JScriptでは、単独ではコレクションどころか、SafeArrayすら作れなかったり
します。そのため、SafeArrayを作成するためだけのCOMコンポーネントがあったりする。
詳しくはhttp://www.imasy.or.jp/~hir/hir/tech/js_tips.html#safearray 参照。
このページはJScriptのtipsが色々と書いてあって参考になります。

VBSの配列やCOMのコレクションにアクセスするのにも、わざわざVBArrayオブジェクトや
Enumeratorオブジェクトを用いる必要があって、そこはFor Each...Nextが使える
VBScriptの方が有利ですよね。もっともJScript.NETではfor...inが拡張されて
コレクションも列挙できるようになったんですが。一方でSafeArrayは.NETでは型としては
消滅したらしい?です)


5.Friendキーワードが使えない

Friendとは、PrivateとPublicの中間的な意味合いを持つキーワードで、
「自分自身のクラスモジュールや、プロジェクト内のほかのモジュールからは
呼び出せるが、クラスを呼び出すクライアントからは呼び出せない」FunctionやPropertyを
定義することができます。
参考:オブジェクト間のプライベート通信
http://www.microsoft.com/japan/developer/library/VBCon98/vbconprivatecommunicationsbetweenyourobjects.htm

VB(S)のクラスでは、引数つきコンストラクタを記述することはできないので、
プロパティの値を初期化するときなど、異なったオブジェクト間で通信する際は、
呼び出し側でインスタンスを作成してからプロパティを設定するという手法が一般的です。
たとえば読み取り専用プロパティを設定したい場合などに、クラスのProperty Letに
Publicの代わりにFriendキーワードを使うことで、外部クライアントからはクラスのプロパティを
変更されないようにするわけです。

参考:@IT:連載:プロフェッショナルVB.NETプログラミング 第9回 オブジェクト関連(前編)
http://www.atmarkit.co.jp/fdotnet/vb6tonet/vb6tonet09/vb6tonet09_02.html
(ちなみにVB.NETでは引数つきコンストラクタも可能になってます)

ところが残念ながらVBSではFriendキーワードは使えません。よって、複数のClassステートメントを定義した場合、
その間で(安全な)データ通信をすることは不可能です。
まあ、たかがスクリプトなんだからプロパティが読み取り専用じゃなかろうがメソッドが隠蔽されて
なかろうが、要するに呼び出さなきゃいいんだからPublicで十分じゃん?
という意見もあるでしょうけどね。

ちなみに、これは多分VBSのヘルプには載ってないんですが、Classステートメント内で、
自分自身のクラスの実行中のインスタンスを表すMeキーワードは使用可能です。

(さらなる余談ですが、Friendキーワード的なことをWSCでやる方法ってあるんでしょうか?
WSCでも同一ファイル内に複数のクラス、というかComponentを定義できます。
あるComponentから別のComponentのインスタンスを作成するには、
createComponent関数を用います。このとき、呼び出される側のコンポーネントに、
<public>で公開したくないメソッドやプロパティを定義したくなりますが、
何か方法はあるんでしょうかね)


以上、Classステートメントでできないことをまとめますと

1.プロパティやメソッドの引数に型が指定できない
2.インターフェイス実装ができない
3.イベントが使えない
4.コレクションクラスが作成できない
5.Friendキーワードが使えない

以上5点となります。

私自身、クラスの概念をようやく理解しつつある段階ですんで、間違った認識も
含まれてるかもしれません。その際は指摘をよろしくお願いします。

さん 2003年 07月 01日 13時 33分 28秒

ワイルドカードを含む任意のファイル名から、実在するファイル名を取得したいのですが、何か良い方法ありますか。
FileSystemObjectでできるかな、と思って調べたのですが、わかりませんでした。
ご存知の方、よろしくお願い致します。

さざなみ さん 2003年 07月 01日 13時 04分 33秒

さざなみです。
Shell.UIHelperのAddFavoriteメソッドやShowBrowserUIメソッド
で追加、変更された、フォルダーやインターネットショートカットの
フルパスを取得したいのですが、一般的にどのようにすればいいでし
ょうか。

いりや さん 2003年 07月 01日 08時 44分 55秒

らいどさん、

> 結果から申し上げるとOKでした。

まずは結果がでて何よりです!
よかったですね!

> やはり[Set Object=...]でWindowを取得してと思ったのですがどうも捕まえ切れませんでした。
> 当初はスコープ(?)が適切でなかったようでしたが、試行錯誤のうえ
> 何とかHTMLDocumentとして確保出来るようになりました。
> しかしながら中にある要素を取得しようとすると「アクセスが拒否されました」とのErrMsg。
> そんなこんなで[Shell.Application]に辿り着いた次第です・・・。

そうでしたか。(A) の方式は確かにスコープをしっかり把握してい
ないとうまくデータを別な関数に渡してあげられないですからね。

ところで。ところで、らいどさんのスコープという言葉でフト思う
ことがあって VBScript.htm の該当箇所を書き換えてみましたとこ
ろうまく (A) の方式でいってしまいました (^^:

ポイントは、VS フレーム (VBScript.htm) で広域変数を用意して
やり、そこに保持しておいて後で使う、というものです。dummyWindow,
targetWindow 変数が広域変数です。

スクリプトは JavaScript で書いておりますが、たぶん VBScript
でも広域変数を利用可能だと推測します。こうすれば ActiveX
Object を利用するためにセキュリティーのレベルを下げなくとも
うまくいく・・・はずです。よろしければお試しください。

VBScript.htm の一部です。(例によって全角スペースは半角スペー
スに置き換えください)

<Form>
<input type=text name=txtVBS size=20 value="変更されましたか?"><P>
<input type=button name=button1 onClick="func1()" value="invoke func1()"><P>
<input type=button name=button2 onClick="func2()" value="invoke func2()"><P>
</Form>

<script type=text/javascript>
var dummyWindow;
var targetWindow;
function func1() {
    dummyWindow = window.open("", "DM");
    dummyWindow.navigate("Dummy/Dummy.htm");
    targetWindow = window.open("", "TG");
    targetWindow.navigate("Target/Target.htm");
}
function func2() {
    var tframe1Window = targetWindow.document.frames.Tframe1;
    tframe1Window.document.all.text1.value = window.document.all.txtVBS.value;
    tframe1Window.document.all.button1.click();
}
</script>

らいど さん 2003年 07月 01日 02時 19分 11秒

>いりやさん

 実は[Shell.Application]を試す前に[Window.open&Navigate]を使って
 色々試したんですが上手くいかなったという経緯がありました。
 
 やはり[Set Object=...]でWindowを取得してと思ったのですがどうも捕まえ切れませんでした。
 当初はスコープ(?)が適切でなかったようでしたが、試行錯誤のうえ
 何とかHTMLDocumentとして確保出来るようになりました。
 しかしながら中にある要素を取得しようとすると「アクセスが拒否されました」とのErrMsg。
 そんなこんなで[Shell.Application]に辿り着いた次第です・・・。

 ご提案いただいた[sample.js]は正常に動作してくれたようです。
 ただJacaScriptを最終的に使いこなせるか、次の問題が生じたときに自分で判断がつくか
 自信が無いのでちょっと別の方法にて回避を試みてしまいました。

 結果から申し上げるとOKでした。
 
 この間のVBScript.htmですがフレーム内からでは正常動作しなかったので
 まずはOya.htmに引き上げました。
 この位置からの実行では、前に記載したとおり問題がありません。
 
 そのうえでこのOya.htm=VBScript.htmにインラインフレームを作成して
 擬似的(?)にフレーム構造にしました。
 すると問題なくScriptを消化して期待通りの動作をしてくれました。
 今後インラインフレームゆえの制約なんてものがあるのかも知れませんが当面この方向で進めてみます。

 基礎が無くて応用ばかりなので、やけに時間が掛かります。
 正直Copy&Pasteで作っているようなものですが出来るとこまで頑張ってみます。

 今回は色々とご相談に乗っていただき本当に有難うございました。
 次回はもう少しマシな内容になっているようにしたいと思います。

あさじゃけん さん 2003年 06月 30日 14時 21分 43秒

>いりやさんへ
PHPユーザ会のメーリングリストBug報告スレの過去ログ見てたら、こんな記述がありました。
「rerorero at hogehoge dot co dot jp」
おおぉ。ドットも表記が!(笑)
最近の流行なのですかね^^;;;

でも、これもロボに検索されそうな予感(汗)
一時的な回避でしかないんでしょうねぇ・・・・

あさじゃけん さん 2003年 06月 30日 13時 48分 02秒

>Tomさんへ
あ。ホントだ、ウィルスデータベースにあるねぇ(笑)
しかも二種類あるや(^^;;;
いりやさん補足サンクス^^

■VBS_NEMITE.A
別 名: ネミット
 これはワームに分類されるVisual Basic で作成された不正プログラムです。Microsoft Outlookの機能を利用して自身のコピーをメールに添付し、アドレス帳にある全ての宛先に送信して自己増殖するワーム活動を行います。 ワームが送信するメールは下記の形式となります。 件名: HI 本文...
http://www.trendmicro.co.jp/vinfo/virusencyclo/default5.asp?VName=VBS_NEMITE.A

■VBS_PINOCC.A
別 名: ピノッカ, PINOCC.A
 これはVisualBasicScriptで記述された一般的にワームに分類される不正プログラムです。OutlookやmIRCを利用してネットワーク上で増殖する活動を行います。ワームの送信するメールは以下の通りです:  件名: "HI"  本文: KONO...
http://www.trendmicro.co.jp/vinfo/virusencyclo/default5.asp?VName=VBS_PINOCC.A

と、言うわけで。ウィルスの可能性大です。
そのマシンは、OSから再インストールすることをお勧めします。(もちろん全て削除することになります)
メーカーのパソコンなら、リカバリーCDとかがついていると思いますので、マニュアルの手順に沿ってやってくださいね。^^;;;
−−−!注意!−−−
この作業は出来るだけ早くやってください。ネットワークに繋げていると、他の方にも感染して迷惑をかけることになります!ワーム型ウィルスとはそういうものです。

入れなおしたら、ウィルスチェックソフト(ワクチンソフト)は必ず使いましょうね。^^;;;(初心者ならウィルスバスターが簡単でいいと思います。)
個人使用なら無料で使える英語のソフト等もありますので、必ず入れましょう。
■AVG 6.0 Free Edition
http://www.grisoft.com/
(私が家で使ってるやつです。サブマシンとかに。メインマシンはノートン入ってます。)

>いりやさんへ
「at=@」・・・私もこれからその手を使おう(笑)

いりや さん 2003年 06月 30日 13時 05分 47秒

tom さん,

あさじゃけんさんもご指摘の通りの可能性があります。

www.google.com で SYASHIN3.vbs を検索語にしてみるといろいろと
ひっかかります。(日本語オプションつきで) 例えば,

http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list69.shtml

とか。お試しください。

いりや さん 2003年 06月 30日 12時 18分 33秒

彩香さん,

> // すでに IE ウインドウが存在するとき run() 第三引数に 1 を受け付けられない。

こちら,正しくは,第三引数に true を受け付けられない,でした。お詫びして
訂正します。

あと,

> ただ、自分自身で自分自身への操作をしなければならないという
> 事もWSHではあまり必要ないかと思われますので、WSHを使い
> これで何ができるかといろいろ考えてみたのですが、
> なかなか有用な使い道が思いつきませんでした。

こちらですが,私は,Windows Shell の GUI を通して今までマウスで手動で行っ
てきたことをプログラム (VBScript/JScript等) でも書いて Shell とお話がで
きる,というところがポイントではないかと個人的に思っています。

最近わたしが発見したのは WScript.Shell>>run() メソッドをスクリプトの
Launcher として使うやり方です。

ご存知のとおり .vbs, .js という拡張子をつけてファイルを開くと Shell が実
行してくれます。これを利用してテキストデータをその拡張子をつけてファイル
保存し,

  (new ActiveXObject("WScript.Shell")).run("c:\\sample.js");

という風にすればプログラムがヒュルヒュルと動くのです。私は,この機能を応
用して選択範囲をプログラムと見なして実行するための枠組みをつくりました。

UWSC doIt tool という名前ですが,document の tips にも書いてある通り,
VBScript, JScript にでも簡単に対応させることが可能ですので,よろしければ
お試しください。
http://iriyak.adam.ne.jp/uwsc.html

いりや さん 2003年 06月 30日 11時 43分 05秒

> InvokeVerb・・・gooの辞書で調べたら、なんとなく意味わかりました^^
> が・・・音源ボードついてないPCなので、発音は聞けませんでした(笑)

www.alc.co.jp の英辞郎 on the web も役にたちますよ!お試しあれ。

> ひょっとして「at=@」の書き方は、アドレス収集ロボの対策です?

ですです。この書き方けっこう気に入っていて自サイトにも採用してま
す。。

あさじゃけん さん 2003年 06月 30日 11時 11分 35秒

>いりやさんへ
InvokeVerb・・・gooの辞書で調べたら、なんとなく意味わかりました^^
が・・・音源ボードついてないPCなので、発音は聞けませんでした(笑)
らいどさん、彩香さんの件は、お任せします(汗)
ひょっとして「at=@」の書き方は、アドレス収集ロボの対策です?
それいいですね(笑)


>つちやさんへ
一部復旧、ありがとうございます(汗)
早速、dmFMP見てます・・・けど、やっぱりJavaScriptっぽいんですね。^^;;
でも、md5ハッシュ、BlowFishの暗号化複合化あたりは、使いたいですねぇ。
でも、その前にDMonkey自体を調べないといけませんね。

ウィルスチェイサー・・・は、ある意味安心かも。(笑)
でも、反応しすぎてマヒしそうですね(笑)


>Tomさんへ
はじめまして(汗)
えぇーと。その話は、ここのサイトの趣旨と外れているので、他のサイトに質問を出されたほうが良いと思います。(間接的には絡んでそうですけど・・)
そのほうが、的確な解答を得られるでしょう。

さらに言うと、PCの機種、性能、OSの種類や、正確なエラーメッセージ、メッセージの出るタイミング、いつからエラーが出だしたか、エラーが出だした前後に操作したことは・・・等、必要な情報をきちんと明記しないと、誰も答えようがありません。

例えば、「車から変な音がするんだけど・・・」とだけいわれてもどこが悪いかわかりませんよね。
車の車種によっては、それは正常な音かもしれないし、ひょっとしたらブレーキパットがなくなってるのかもしれませんし、エンジントラブルかもしれません。
これでは、想定できる範囲が広すぎて、正しいアドバイスは出来ません。

つまり、Tomさんの書かれた内容から読み取れるのは、その程度の情報しかないということです^^;;;

今後は、他のサイトへ質問を出すときも、上記の項目を最低限記入するようにしましょう。
そうでないと、無視されるか、最悪の場合罵倒される事もあります・・・ここの掲示板で罵倒される事はないでしょうけど(笑)

とりあえず、文面から察するに、ウィルスの可能性もありますので、まずここでウィルスチェックして下さい。
http://www.trendmicro.co.jp/hcall/index.asp

それから質問の仕方について、
http://www.linux.or.jp/beginners/question.html
http://members.aol.com/seijiroun/nouri/nouri034.htm
http://www.amy.hi-ho.ne.jp/~lepton/program/prog/prog19.html
等を読んでください。
#解答する側の気持ちも理解してくださいね。

その後は、こちらに書き込みすると、解決するまで解答を得られると思います。
http://www.okweb.ne.jp
okwebの人たちは、PointをGetするために頑張って答えてくれるはずです(笑)

とりあえず、今後のTomさんのために、あえて言わせてもらいました。
(むたぐちさん親切だから、ある程度答えてくれそうだけど。笑)
でわでわ。^^

いりや さん 2003年 06月 30日 02時 04分 18秒

> あと差し支えなければ、動作確認していただいた際のソースを
> 教えていただければもう一度それで実行してみようかと思います。

あと忘れておりました。もともとのスクリプトは HTML 中の SCRIPT
エレメントではなく、ファイルに sample.js という名前で格納して
ダブルクリックして動作確認しました。(フレームがないもの、ある
ものなどウインドウをたくさん開いた状態にして...)

いりや さん 2003年 06月 30日 01時 51分 31秒

らいどさん、

お送りいただいた内容でだいたいイメージできました。問題のポイントをこのよ
うに理解しました。こんな感じでしょうか??

・問題

(1) oya.htm の VS フレームをロードするとき、Dummy/Dummy.htm, Target/Target.htm
  を window.open() にて新規ウインドウとして開きたい。
(2) VS フレーム (VBScript.htm) の txtVBS フィールドを利用者が変更する。
(3) 変更を完了して cmdVBS ボタンを押下すると、内部で以下の処理を行い
  たい。
  (a) Target/Target.htm の Tframe1 フレームの text1 フィールドの値
    を VS フレームの txtVBS フィールドの値とする。(入力の代行)
  (b) Target/Target.htm の Tframe1 フレームの button1 ボタンをクリッ
    クする。(クリックの代行)

それで課題は (3-a), (3-b) を実行するには、VS フレームを持つ window オ
ブジェクトへのリファレンスを呼び出し元が知っていないといけない。

(1) を実行するときに window>>open() メソッドが返す window オブジェク
トを後々のため保持しておいて、(3-a), (3-b) を実行するときに利用できれ
ばよいのだが、現状は window オブジェクトを落としている。そのため、ど
こか別の場所からリファレンスを取得する必要がある。そこで
Shell.Application>>windows() メソッドを使えば Internet Explorer オブ
ジェクトへのリファレンスが得られるのでそこから引き当てられる。

だけれでもそのスクリプトを VS フレームの HTML に格納して実行しようと
するとうまくいかないようだ。

・解決(案)

WSH/JScript で書きます。いまのところ私も Shell.Application>>windows() メ
ソッドが失敗する原因がよくわからないので、これを使わずとも何かよい方法は
ないか? という方向性でかんがえてみました。

(A) Window_OnLoad 関数の window>>open() で返ってきた window オブジェ
  クトを保持しておいて後から使う。

    dummyWindow = window.open("", "DM");
    dummyWindow.navigate("Dummy/Dummy.htm");
    targetWindow = window.open("", "TG");
    targetWindow.navigate("Target/Target.htm");

  という風にして一旦 targetWindow で保持しておくことができれば、次
  のような方法で (3-a), (3-b) を書くことができる。

    tframe1Window = targetWindow.document.frames.Tframe1;
    tframe1Window.document.all.text1.value = window.document.all.txtVBS.value;
    tframe1Window.document.all.button1.click();

    ※ window.document.all.txtVBS.value の window は VS フレーム
      をもつ window オブジェクトへのリファレンスが代入されてい
      る。(スクリプト全体を示していないので補足します)

(B) (1) 〜 (3) までを HTML の外で模倣する。(Windows Scripting Host を使っ
  て)

  (2) の箇所は私あんまり WSH のユーザ・インタフェースのバリエーショ
  ンをよく知りませんので、ここは決めうちで (1), (3) だけを模倣する
  WSH/JScript のスクリプトをご紹介します。ディレクトリの修正と全角スペー
  スの修正後、sample.js というファイル名で保存して実行ください。(ダブ
  ルクリックしてください)

var ie1 = new ActiveXObject("InternetExplorer.Application");
ie1.visible = true;
ie1.navigate("D:\\Documents and Settings\\iriyak\\My Documents\\forride\\ScriptTest\\ScriptTest\\Dummy\\Dummy.htm");
waitUntilLoadingHasCompleted(ie1);

var ie2 = new ActiveXObject("InternetExplorer.Application");
ie2.visible = true;
ie2.navigate("D:\\Documents and Settings\\iriyak\\My Documents\\forride\\ScriptTest\\ScriptTest\\Target\\Target.htm");
waitUntilLoadingHasCompleted(ie2);

var tframe1Window = ie2.document.frames.item(0); // ie2.document.frames.Tframe1 は WSH/JScript 上では失敗するよう...
if (tframe1Window != null) {
    tframe1Window.document.all.text1.value = "こんにちは";
    tframe1Window.document.all.button1.focus();
    tframe1Window.document.all.button1.click();
}

function waitUntilLoadingHasCompleted(anInternetExplorer) {
    do {
        WScript.sleep(0.1 * 1000);
        var b1 = anInternetExplorer.busy == false;
        var b2 = anInternetExplorer.readyState == 4; // 4 = READYSTATE_COMPLETE
        var breakCondition = b1 && b2;
    } while (!breakCondition)
}


らいど さん 2003年 06月 29日 22時 07分 02秒

いりやさん
 申し訳ありませんがメールさせて頂きましたのでお読み頂けますでしょうか
 宜しくお願いします。

いりや さん 2003年 06月 29日 01時 37分 38秒

らいどさん、

ちょっとスクリプトを実行する場所が違うようだ、というのがお話を
うかがってわかりました。

  ...\ScriptTest\Oya.htm
  ...\ScriptTest\VBScript.htm
  ...\ScriptTest\JavaScript.htm

こちら一式全部拝見させていただいてもよろしいですか??
あと実際に "TargetTitle" をもつ HTML ウインドウで具体的に何を
制御したいのか (text1.value = "XXX", button1.click() など) を
教えていただけませんか?? もしかしたら、Shell.Application>>windows()
を使わなくともうまくいく方策があるかもしれません。

サイズが大きいようであれば iriyak at mcn.ne.jp (at は @ によみかえて
ください) までメールでお送りください。そうでもなければこちら
に。


らいど さん 2003年 06月 29日 00時 46分 05秒

いりやさん、ご返事有難うございます。
早速試してみましたが、結果から申し上げるとエラーでした。
何点か確認したい事があるので、確認した経過を書き添えます。

■ご指摘をされた点について■
 objWindow.document.Frames(j).document.all.text1.value="XXX"
 objWindow.document.Frames(j).document.all.Button1.click
 この点については問題無いと思われます。
 先の書き込みに記載したとおり、単独ではすべてのスクリプトを消化して
 期待したとおりの結果が出てきます。(任意のページのテキスト欄に
 文字を入力してから実行ボタンをクリックしてくれてます。)

■ご提案されたJavaScript実行について■
 下記の「実行内容」の状態にて実行。
 結果、単独では問題無く動作、フレーム内からではエラーとなりました。
 (ついでですが正直Javaは殆ど分かりません。)

■実行内容■

 <使用したファイル>
  ...\ScriptTest\Oya.htm
  ...\ScriptTest\VBScript.htm
  ...\ScriptTest\JavaScript.htm

 <ページ構成>
  \Oya.htm
+---(Frame1)--- \VBScript.htm
+---(Frame2)--- \JavaScript.htm

 <ソース>

 --\Oya.htm--------------------------------------------------------------
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  <HTML>
  <HEAD>
  <meta http-equiv="content-type" content="text/html; charset=shift_jis">
  <meta http-equiv="cache-control" content="no-cache">
  <meta name="generator" content=" ver">
  <Title>Oya</Title>
  </HEAD>
  <FRAMESET ROWS="120,*">
<FRAME NAME="VS" SRC="VBScript.htm">
<FRAME NAME="JS" SRC="JavaScript.htm">
  </FRAMESET>
  </HTML>

 --VBScript.htm(前回と何も変わりませんが)--------------------------------
  Sub SerialNo_OnBlur
   Set Shell = CreateObject("Shell.Application")
   intWindowCount = Shell.Windows.Count
   If intWindowCount = 0 Then WScript.Quit
   For i = 0 To intWindowCount - 1
    Set objWindow = Shell.Windows.item(i)
    If TypeName(objWindow.document)="HTMLDocument" Then
     If objWindow.document.Frames.Length > 1 Then
      For j = 0 To objWindow.document.Frames.Length - 1
       If objWindow.document.Frames(j).name="TargetTitle" then
        objWindow.document.Frames(j).document.all.text1.value="XXX"
        objWindow.document.Frames(j).document.all.Button1.click
       End if
      Next
     End If
    End If
   Next
  End Sub

 --\JavaScript.htm-------------------------------------------------------
  <html>
  <head>
  <script language="JavaScript">
  <!--

    「 この部分にご提案いただいたScriptを記述
             読み込み/更新時に実行されます。
      \\iriyak   → \\ride    に変更済み。
      全角スペース → 半角スペース に変更済み。 」

  //-->
  </script>
  </head>
  <body>
   JavaScriptTestPage
  </body>
  </html>

■実行結果■
 今回は「Microsoft Script Editer」を使用してエラー箇所を確認してみました。
 VBScript.htm実行時
  ・Msg 「Microsoft VBScript 実行時エラー:書き込みできません。」
  ・Line「intWindowCount = Shell.Windows.Count」
 JavaScript.htm実行時
  ・Msg 「Microsoft JScript 実行時エラー:書き込みできません。」
  ・Line「var shellWindows = shellApplication.windows();」

■考察■
 まずJavaScript.htmのスクリプト以外のタグの部分に問題が無いか?
 (ホント理解がないので・・・)
 OKなら、何故いりやさん環境では動作したものがエラーになるのか?

 実行環境かとも思いましたが、自宅と職場(こっちで使いたい)でも同じでした。
 参考までに、共にWinXPPro+SP1,IE(ver6),Wscript.exe(ver5.6)、です。

 もし環境なら[インターネットオプション]からの有効or無効の設定など???

 それ以外にErrMsgの「書き込みができません。」が理解できませんでした。

 あと気になったのは、大した差異は生じないかもしれませんが、
 フレームを宣言(?)している \Oya.htm の記述でしょうか
 良かったら \Oya.htm のソースを見ていただけませんでしょうか?

 あと差し支えなければ、動作確認していただいた際のソースを
 教えていただければもう一度それで実行してみようかと思います。

 ■■長くなってしまって申し訳ありません■■

Tom さん 2003年 06月 28日 16時 16分 12秒

初めまして!
お聞きしたいのですが…
Windowsを起動すると、最初に毎回必ず・・・スクリプトファイル"C:\WINDOWS\SYASHIN3.vbs"が見つかりません・・・と出てくるんですが、どうやったら解決しますか?
初心者ですので、詳しく教えて頂けるとありがたいです…
宜しくお願い致します。


いりや さん 2003年 06月 28日 13時 58分 57秒

らいどさん、

いりやと申します。

>  フレーム内から実行してみると[intWindowCount = Shell.Windows.Count]の
>  ところでエラーが出ているらしく、Windowの数が取得できないようです。

という所がこちらでも発生するか試してみました。具体的にはフレーム構造
をもつウインドウを開いておいて、以下の WSH/JScript スクリプトを動かし
てみましたが特にエラーは発生しませんでした。

勝手な推測ですが、ポイントは、

>       objWindow.document.Frames(j).document.all.text1.value="XXX"
>       objWindow.document.Frames(j).document.all.Button1.click

ここが、本当に対象の HTML 要素を指して、プロパティーを設定している、
もしくはメソッドを起動しているか?にあるのではないでしょうか。そこは
確認されましたか??

わたしも IE の操作に取り組んでいますが、対象の HTML 要素をさがすのが
一番骨の折れる作業でしたので、そこに目がいきました。
http://iriyak.adam.ne.jp/uwsc.html

[ スクリプトについて ]

・WinXP SP1, IE6.0 で動作確認しています。
・各 ShellWindow オブジェクトの属性を列挙して、それを "ShellWindowsの状態.txt"
 というテキストファイルでマイドキュメントに格納します。
・最後にそのファイルの起動をシェルに依頼します。(その結果ウインドウが
 開きます。)
・インデントを有効にするため全角スペースを入れました。実行する前に半
 角スペースを追加してください。またマイドキュメントはハードコーディ
 ングしています。皆さんの環境に即して修正ください。(たぶん iriyak と
 いうところをユーザ名に置き換えてやれば OK)


[ WSH/JScript サンプルスクリプト ]

var logFilePath = "C:\\Documents and Settings\\iriyak\\My Documents\\ShellWindowsの状態.txt";
var s = fileOutPropertiesOfShellWindowsTo(logFilePath);

openFile(doublequote(logFilePath)); // ファイル起動をシェルにお願いする
//popUpMessage(s); // PopUp ウインドウに表示可能な範囲だけ表示する

function fileOutPropertiesOfShellWindowsTo(logFilePath) {
    var shellApplication = new ActiveXObject("Shell.Application");
    var shellWindows = shellApplication.windows();
    var s = "";
    for (var i = 0; i < shellWindows.count - 1; i++) {
        shellWindow = shellWindows.item(i);
        s += getProperties(shellWindow, i);
    }
    if ((logFile = filePath2file(logFilePath)) != null) {
        var writeStream = logFile.openAsTextStream(2); // ForWriting = 2;
        writeStream.write(s);
        writeStream.close();
    }
    return s;
}

function openFile(filePath) {
    var shell = new ActiveXObject("WScript.Shell");
    shell.run(filePath);
}

function filePath2file(filePath) {
    aFileSystemObject = new ActiveXObject("Scripting.FileSystemObject");
    if (!aFileSystemObject.fileExists(filePath))
        aFileSystemObject.createTextFile(filePath, true);
    return aFileSystemObject.getFile(filePath);
}

function getProperties(shellWindow, anIndex) {
    var s = "";
    s += "shellWindows.item(" + anIndex + ")\r";
    s += " name = " + bracket(shellWindow.name) + "\r"
    s += " path = " + bracket(shellWindow.path) + "\r"
    s += " fullName = " + bracket(shellWindow.fullName) + "\r"
    s += " locationName = " + bracket(shellWindow.locationName) + "\r";
    s += " locationURL = " + bracket(shellWindow.locationURL) + "\r";
    s += " isIE(self) = " + bracket(isIE(shellWindow).toString()) + "\r";
    s += "\r";
    return s;
}

function popUpMessage(s) {
    var shell = new ActiveXObject("WScript.Shell");
    shell.popUp(s);
}

function bracket(s) {
    return "[" + s + "]";
}

function doublequote(s) {
    return "\"" + s + "\"";
}

function isIE(shellWindow) {
    return shellWindow.fullName == "C:\\Program Files\\Internet Explorer\\iexplore.exe";
}

らいど さん 2003年 06月 27日 21時 27分 05秒

始めましてです。
 過去ログなどを見ながらスクリプトを組んでみているのですが、
 どうにもうまく動作しなくて困ってしまい、質問させていただきます。

目的:
 現在起動中のIEの操作をしようとしてします。
 Document.Titleより操作対象を選別して、InnerTextの取得・Text.Valueの
 入力・Buttonのクリック・等々です。

問題点:
 下記のスクリプトを実行すると、自分が単一のHTMLファイルでは問題無く
 動作してくれるのですが、フレーム内に入ってしまうとエラーになります。
   ○ \MyScript.htm
   × \Oya.htm
      +--(Frame1)---\MyScript.htm
      +--(Frame2)---\etc.htm

 フレーム内から実行してみると[intWindowCount = Shell.Windows.Count]の
 ところでエラーが出ているらしく、Windowの数が取得できないようです。

 ・元々のスクリプト自体に問題があるのか?
 ・フレーム内からのときは、なにか違う構文を使用するのか?
 ・もしくは、フレーム内からでは無理な事なのか?

 ■なんでも結構なので参考になりそうな事を宜しくお願い致します。
 ■勉強不足ですから「リンク参照の事!!」でも結構です。

スクリプト:
Sub SerialNo_OnBlur
 Set Shell = CreateObject("Shell.Application")
 intWindowCount = Shell.Windows.Count
 If intWindowCount = 0 Then WScript.Quit
 For i = 0 To intWindowCount - 1
  Set objWindow = Shell.Windows.item(i)
  If TypeName(objWindow.document)="HTMLDocument" Then
   If objWindow.document.Frames.Length > 1 Then
    For j = 0 To objWindow.document.Frames.Length - 1
     If objWindow.document.Frames(j).name="TargetTitle" then
      objWindow.document.Frames(j).document.all.text1.value="XXX"
      objWindow.document.Frames(j).document.all.Button1.click
     End if
    Next
   End If
  End If
 Next
End Sub

いりや さん 2003年 06月 27日 20時 11分 20秒

むたぐちさん,

> そういえば、私もInvokeVerbを使って「プロパティ」ダイアログを開くとき、
> スクリプトの終了が先になってしまいうまく実行できずに悩んだことがありました。
> そのときもWScript.Sleepを最後に入れることで回避しました。

FolderItem.invokeVerb() メソッドの処理完了のタイミングを知ることができれ
ばいいのですけど,提供されているメソッド群からは見当たらないようです。

Dynamic HTML Object Model の場合は readyState 属性を呼び出し元から問い合
わせることでそのようなタイミングを探る手立てが残されています。このような
口が用意されていない場合は,実行時間を実測ベースで見積もって,WScript>>sleep()
を最後にいれてヨシとするのがよさそうです。。

イベントとそのハンドラなど,非同期処理を WSH で取り扱うのは簡単ではあり
ませんね・・・。

いりや さん 2003年 06月 27日 18時 58分 04秒

彩香さん,

> プロセス管理ができるのですか!?

> "open"したのは良いが、プロセス管理ができないので
> それを閉じる術がないものと思っていましたら、
> ここまでできるとは思っていませんでした(^^

一部の場合にうまくいく,というレベルではありますが二つご紹介します。

使用したのは WSH/JScript ですが,WSH/VBScript へのポーティングは難
しくないと思います。command を置き換えて二つの方式をいろいろお試し
ください。

インデントを有効にするため全角スペースを入れています。実行する前に
必ず半角スペースに置き換えておいてください。

それから WScript.Shell>>run() で c:\sample.html が失敗するケースが
なぜおこるのか,それは ShellExecuteEx() の SHELLEXECUTEINFO 型にヒ
ントが隠されています。

hProcess メンバ変数,fMask メンバ変数をチェックしてみてください。
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/structures/shellexecuteinfo.asp


// 例1 (WScript.Shell>>run() メソッドの第三引数を利用して待つ)
//
// [ Related links ]
//
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/wslrfscriptexecobject.asp
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/wsmthrun.asp

command = "calc";
// command = "clock";
// command = "notepad c:\\sample.html";

// command = "c:\\sample.html";
// すでに IE ウインドウが存在するとき run() 第三引数に 1 を受け付けられない。

executeAndWaitUntilFinished1(command);
aShell = new ActiveXObject("WScript.Shell");
aShell.popUp("プロセス終了を確認。");

function executeAndWaitUntilFinished1(command) {
    var aShell = new ActiveXObject("WScript.Shell");
    aShell.run(command, 1, true);
}

// 例2 (WshScriptExec オブジェクトのステータスを監視して待つ)
//
// [ Related links ]
//
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/wslrfscriptexecobject.asp
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/wslrfstatusproperty.asp

command = "calc";
// command = "clock";
// command = "notepad c:\\sample.html";

// command = "c:\\sample.html";
// 有効な Win32 アプリケーションではないため受け付けられない。

result = executeAndWaitUntilFinished2(command);
aShell = new ActiveXObject("WScript.Shell");
aShell.popUp("プロセス終了を確認。Status = [" + result + "]");

function executeAndWaitUntilFinished2(command) {
    var aShell = new ActiveXObject("WScript.Shell");
    var wshScriptExec = aShell.exec(command);
    while (wshScriptExec.status == 0) {
        WScript.sleep(0.1 * 1000);
    }
    return wshScriptExec.status;
}

彩香 さん 2003年 06月 27日 13時 27分 02秒

To:いりやさん

いろいろな検証、とても参考になります。

>その外部仕様をみると、起動して生成したプロセスの終了まで呼び出し元が待つ
>ようなオプションを導入しているものもある。(WScript.Shell>>run()) ただし、
>open コマンドを処理するのみに特化され、今回のように print コマンドなどそ
>の他のコマンドにまで適用できるよう配慮されていないように思われる。

プロセス管理ができるのですか!?

"open"したのは良いが、プロセス管理ができないので
それを閉じる術がないものと思っていましたら、
ここまでできるとは思っていませんでした(^^

ただ、自分自身で自分自身への操作をしなければならないという
事もWSHではあまり必要ないかと思われますので、WSHを使い
これで何ができるかといろいろ考えてみたのですが、
なかなか有用な使い道が思いつきませんでした。

皆様方は、かなり深いところまでやられているのでビックリしています。
私はバッチファイルのようなものを実現するぐらいですか
WSHを使ってはいませんでしたから(^^



ヒデ さん 2003年 06月 27日 12時 56分 36秒

さとまる さん
管理人むたぐち さん

ヒデです。
すぐにレスを頂いていたのにお礼を申しあげるのが
遅くなり申し訳ありませんでした。
2日ほど外出しておりまして・・・

さて、質問の件ですが・・・

有難うございます。
おっしゃるとおりにやったらできました。

キーは二重化されているんですね。
Regeditを起動してキーのコピーをしたんですが
それでは貼り付けてもなぜか二重にはならないんです。


助かりました。
有難うございます。

また、ご指導お願いします。

つちや さん 2003年 06月 27日 11時 11分 39秒

WSCですが、98・ME・2000で使っていたものを、
XPで、右クリックで登録しようと思ったらできないではあーりませんか。
何かコツがあるのでしょうか。
同じWSCを、登録せずにGetObjectで直接WSCファイルを指定する方法だと実行できます。
MS社から昔ダウンロードしたウィザードでWSCを作ってそのまま登録しようとしても、
登録できませんでした。

WSCの代わりにSCT(スクリプトレット)の方で同じことをすると、問題なく通ります。
で、私の環境だと、98〜XPですべて登録できたのは、WSCではなくSCTなのでした。
うーむ、私の知らない世界がまたここにも。。。

つちや さん 2003年 06月 27日 10時 54分 14秒

ども。
一部コンテンツはそのままなので、
http://www2.jan.ne.jp/~kajika/index2.html
でどぞ。

実は、リンク先のホームページの一つが私が振込みを忘れていた関係でなくなってしまい、
掲示板はしばらく前からコンテンツがなくなっていたのですが、復活方法がわからず、
さらに、ウィルスチェイサーでスキャンかけてみたら、
WScript.ScriptFullNameをつかったスクリプトのいくつかが、
感染の疑いありなんてでてくるものだから、
コンテンツ整理までちょっと隠しておこうかな、なんて思ったのでした。
Set objFile = objFS.GetFolder(objFS.GetParentFolderName(WScript.ScriptFullName))
といった行が感染の疑いをかけられたのではたまったものではありませんが、
濡れ衣とは言え、気持ちのいいものではないので、
書き換えとこれを機会にこんどこそはと思っているコンテンツ整理のため、
ちょっと雲隠れしてみたのでした。
説明なしですみませんです。
むたぐちさんとこでダウンロードしたスクリプトもいくつかチェック受けましたし、なんだかそこまでしなくても、と思ってしまいますよ。
他のソフトで、毎日ウィルスチェックおこなっていたのに。。。

ちなみに,ウィルスチェイサーは、HSPで作ったプログラムをウィルス感染と判断してしまいます。
これもすごいですね。
でも、このウィルスチェイサーをクリアしてしまえば、一安心できるのかも。

いりや さん 2003年 06月 27日 10時 42分 34秒

あさじゃけんさん、

> ところで、InvokeVerbってなんて読むのでしょう・・・
> インボークバービー?(笑)
> 私も少しUWSC触って見よ^^;;

invoke, verb という英単語をつないだもののようですので、それぞれ
辞書をひかれてみれば読み方が出てくると思います。verb は動詞を意
味します。

オブジェクトを名詞、メソッド名を動詞のように使う流儀がオブジェ
クト指向プログラム言語の世界には存在します。それにならって verb
という単語を使っているのでしょう、きっと。

あさじゃけん さん 2003年 06月 27日 09時 41分 55秒

ぬお。
http://www2.jan.ne.jp/~kajika
http://csx.jp/~tsuchiya
つちやさんとこ閉鎖してるやん・・・
いまから見ようと思ったのにぃ・・・

SIGNAL9 さん 2003年 06月 27日 09時 41分 53秒

>アルジャーノン さん

さすがにASPだと掲示板違いだと思うので、簡単に道筋だけ。

http://www.microsoft.com/japan/msdn/columns/server/server033099.asp
↑ちょっと古いですが、大筋考え方は使えます。

ちなみに、こういう場合ASPですと、必ず権限の問題に行き当たります。
http://www.microsoft.com/japan/support/kb/articles/184/2/91.asp
などをご参照ください。

仮に共有プリンタをブラウザで管理したいのでしたら、インターネット
印刷サービスを構成するのが早道でしょう。
http://www.microsoft.com/japan/support/kb/articles/313/0/58.asp

あさじゃけん さん 2003年 06月 27日 09時 36分 56秒

あ。先にこれを紹介します。
WSHからXMLDOMを扱う方法を簡単に説明してあります。
分かりやすかったのでご紹介。
http://ash.jp/xml/wsh/index.htm
この会社・・・うちの近所じゃ(笑)


>むたぐちさんへ

> 変数名の衝突ですか。
いや、私は紛らわしい変数名をつけるのは嫌いなので(笑)
ちゃんとプリフィックスもつけます(笑)
となると・・・「Hito」オブジェクトになるなぁ・・・
Set objHito = new Hito()
objHito.CreateHito("じゃけん")
objHito.CreateHito("あさ")
Set objHito = Nothing 'おいおい(汗)

Socketまじで作ってるんですね(><
むたぐちさんありがとう・・・頑張って!(ものすごく他力本願)汗
でも、Perl分かってないので、助けれない罠(><
#そんなに時間を割いてもらっていいんだろうか・・・

> 大昔は使えたテク
あぁ、やっぱりそういう問題なんですね(><
残念。これできたらいいのになぁ・・・(意味はあまりないかな?^^;;)
#OS以外に「WSH2.0ではできる」・・とかいう事も考えられますね・・


>真琴さん、いりやさんへ
InvokeVerb、IShellDispatch2まで話がいくと、私はお手上げです(><
ところで、InvokeVerbってなんて読むのでしょう・・・
インボークバービー?(笑)
私も少しUWSC触って見よ^^;;


>アルジャーノンさんへ
Users GroupのML・・・いくつか私も参加していたり(笑)
でも、ASPは参加してないなぁ・・・
しかも私もお手上げ(><
#あぁ、最近お手上げ増えてきた(><


>真琴さんへ
こんなページも見つけました。ぜひ^^
http://nacelle.cug.net/wsh/index.html

管理人むたぐち さん 2003年 06月 27日 08時 45分 46秒

Gray-World.net / NACS bypassing http://gray-world.net/

Wsh, "Web Shell" - remote UNIX/WIN shell,
that works via HTTP/HTTPS. The package contains two perl scripts
for server and client hosts: the first one is for console usage
and the second one runs as CGI script on the target host.

だそうです。決してWindows Script Hostではありません。


To: じゃけん さん

> ・・・残念ながら別人です^^;;;;
> あぁ、ハンドルネーム変えないといけないなぁ・・・

変数名の衝突ですか。
でも、WSHLab掲示板NameSpaceに属しているあささんは一人だし問題ないんじゃないですか(w

あと、PerlSock.Socket(うーん、イマイチなProgIDかもしれん)ですが、
BASP21のsocketコンポーネント並のことはできるようになりました。
つまり、TCPなクライアントを作るのには使えるということです。
これから、UDPも使えるようにしたり、listenメソッドと各種イベントを設定して、
サーバー用にも使えるようにしていきたいと思います。

PerlScriptでWSCを書いていて思ったことを少し。

まず、登録時に、スクリプトのコンパイルエラーを出してくれないのに参りました。
たとえシンタックスエラーがあっても登録は通ってしまいます。
んで、そのコンポーネントをCreateObjectすると、「コンポーネントが作成できません」
というエラーが出るだけで、どこにエラーがあるか分からない罠。
Perl初心者にはきつすぎます。とりあえず、<script>内を抜き出して、perl.exeで
実行させるという原始的な方法でエラーチェックしてますが何とかならないもんでしょうか。

次に、Shift_JISが使えないという制限が…。
EUCならいけるのでしょうか?どうもus-asciiしか無理なような…。
まあ、日本語を使うのはコメント文くらいでしょうから、とくに問題はない気もします。今のところ。

それとdieはWSC内では使えない予感?どうするんだろう…。

とまあそんなレベルをさまよってます。

> --------------------------------------------------
> Set WshShell = WScript.CreateObject("WScript.Shell")
> '59は、ボタンのないダイアログを表示させる引数です。
> WshShell.popup "5秒後に閉じます。",5,"ボタンなしダイアログ", 59
> --------------------------------------------------
> 喜び勇んで実行しても何も表示されません・・・・

大昔は使えたテクなんですが、今は私のところでも使えないですね。
ということはWin9x系でのみ有効ということか。おそらく。


To: 真琴 さん

> この「VBSランゲージリファレンス」とはどれのことを言ってらっしゃるのですか?
> 何か、本のことなのか、それとも、scd56jp.exe のことなんでしょうか?
> 教えてください。

たぶん、当時の私は、当時の最新版ヘルプのことを指していたのだと思います。
今の気持ち的には、scd56jp.exeになりますね。

> もし、scd56jp.exe のことだとしたら、これをDLしてインストールした場合、
> バージョンが5.6に上がってしまうんでしょうか?

ドキュメントだけですのでおそらくその心配はないかと。

WSHのバージョンについては、私も返信してるのでもう一度読んでくださいまし。
WScript.Versionですよ。

> 逆に、2.0を使っているのに、5.6のヘルプを見てもしょうがないのかなぁ(笑) って気もするので、いろいろ教えてください。

scd56jp.exeのヘルプだと、ちゃんと各機能が使用可能なバージョン表記があるので、WSH2.0用の
ヘルプとしても使えます。

個人的には、scd56jp.exeがかなりお勧めです。昔のヘルプは酷かった分、現在のヘルプは
輝いて見えます。
書籍は過去にまとめたことがあるので、掲示板のログを探してみてください。
…Googleで(w

そういやこれは紹介してなかったかも?

Windows Script Hostハンドブック―Windows簡単プログラミング講座 Windows Start Books
掌田 津耶乃 (著)
http://www.amazon.co.jp/exec/obidos/ASIN/4839908516/250-0482094-1100257
http://www.h5.dion.ne.jp/~tuyano/RensaiHome.html

Windows Start誌で連載されてた「Windows Scripter 2002」が単行本化したもので、
2002/9/28に発売されました。二つ目のURLにはサンプルコードが転載されてます。
(この続編?の「Windows Script GTR」が先月まで連載されてたみたいです。
これもいずれ単行本になるんでしょうか。詳しくは二つ目のURLを)


To: 彩香 さん & いりや さん

> >むたぐちさんの頁に紹介されていた IShellDispatch2 オブジェクトを
> >WinXP 上で試しておりますが、ShellExecute() メソッドがうまく機能し
> >ないようです。うむむ。
>
> そんなメソッドがあったのですね(^^

おおう、私も忘れてましたよ。
InvokeVerbよりスマートですね。

そして様々な検証、参考になります。 > いりやさん
そういえば、私もInvokeVerbを使って「プロパティ」ダイアログを開くとき、
スクリプトの終了が先になってしまいうまく実行できずに悩んだことがありました。
そのときもWScript.Sleepを最後に入れることで回避しました。


To: アルジャーノン さん

すいません、私にはお手上げです。
餅は餅屋ということで、ASP/IISのことは専門家に任せた方がいい気がしてきました。
たとえばUsers GroupのASP MLは日夜活発な議論がされてますし、
他にも掲示板があるに違いありません。そちらをあたってみては?

いりや さん 2003年 06月 27日 02時 50分 07秒

じゃけんさん、

> UWSCすごいですね・・・そこまでできるとは・・・
> 操作記録ソフトの中では、最高峰だと思って、昔から「しなっと」使っていたの
> ですが、そこまでできるとは思っていませんでした(汗)

UWSC は、開発の途中で Component Object Model や Win32 API も利用できるよ
うになりました。私はですので開発当初の操作記録/再生ソフトウェアとしての
利用法よりも COM ドライバ+αの方が多い。実際スクリプトを眺めていると八
割ぐらいは WSH/JScript にポーティング可能だったりします。

ですので、

> いりやさんの使い方は、すでに操作記録ソフトじゃないですもん(爆)

このご指摘は大当たりです :-)

いりや さん 2003年 06月 27日 02時 37分 49秒

彩香さん、

| 私も同Win XPの環境で早速試してみましたが、
| これでWord、Excel、Txtの全てが印刷できるようです。

うまくいったようで何よりです。

さて、前回投稿したときにうまくいかないとお伝えしましたが原因が判明しまし
た。IShellDispatch2 (Shell.Application) オブジェクトは白でした。

UWSC をつかって説明しますが、Component Object Model のところを追って頂け
ればほとんど問題なくポイントをつかめると思います。

また何度も印刷させるわけにはいかないので print を open にしています。印
刷させる場合は、open は print に、"開く(&O)" は "印刷(&P)" に読み替えて
ください。


[ 事象 ]

Shell.Application の機能を利用してマイクロソフト・ワード
のファイルを開こうとしたところうまくいかないケースに遭遇
した。

動作確認: WinXP SP1, MS Word 2000 (9.0.6929 SP-3), UWSC 2.8

[ OK, NG 例 ]

// #1 OK (Shell.Application>>shellExecute() を利用)

aShellApplication = CREATEOLEOBJ("Shell.Application");
aShellApplication.shellExecute("c:\sample.doc", 0, 0, "open", 1);
MSGBOX("");

// #1 NG

aShellApplication = CREATEOLEOBJ("Shell.Application");
aShellApplication.shellExecute("c:\sample.doc", 0, 0, "open", 1);

// #2 OK (FolderItem>>invokeVerb() を利用)

aShellApplication = CREATEOLEOBJ("Shell.Application");
aFolder = aShellApplication.nameSpace("c:\");
aFolderItem = aFolder.parseName("sample.doc");
aFolderitem.invokeVerb("開く(&O)");
MSGBOX("");

// #2 NG

aShellApplication = CREATEOLEOBJ("Shell.Application");
aFolder = aShellApplication.nameSpace("c:\");
aFolderItem = aFolder.parseName("sample.doc");
aFolderitem.invokeVerb("開く(&O)");

// #3 OK (#2 でメソッドの呼び出しをカスケード)

aShellApplication = CREATEOLEOBJ("Shell.Application");
aShellApplication.nameSpace("c:\").parseName("sample.doc").invokeVerb("開く(&O)");
MSGBOX("");

// #3 NG

aShellApplication = CREATEOLEOBJ("Shell.Application");
aShellApplication.nameSpace("c:\").parseName("sample.doc").invokeVerb("開く(&O)");

// #4 OK (ShellExecuteA() Win32 API)

def_dll ShellExecuteA(hwnd, string, string, string, string, long) :long :shell32.dll
ShellExecuteA(0, "open", "c:\sample.doc", "", "", 1); // nShowCmd = 1

[ 原因 ]

・#1 〜 #3 のメソッド起動は非同期である。そのため、処理が完了しないうち
 に呼び出し元に実行の制御が戻ってくる。
・Microsoft Word の起動は結構時間がかかる。
・スクリプト終了時に、生成した COM Object の開放を行う。

この振る舞いから、#1 〜 #3 で NG の時は、Shell.Application が sample.doc
に対する依頼をなげないうちに、Shell.Application が開放されてしまったため
に、Microsoft Word が残ってしまった。

#1 〜 #3 で OK の時は、MSGBOX("") で、ダイアログが表示されてスクリプトの
実行がブロックされている。その間の時間にたまたま依頼が完了したためにうま
くいっている。

#4 で OK なのは、ShellExecteA() の実行が完了して呼び出し元に実行の制御が
戻ってきたときには依頼が完了している。だからうまくいっている。

なお、この事象は WSH/JScript でも起こりうる。再現も確認された。

[ 対策 ]

・ShellExecuteA() を使う。

・メソッド起動の方式を採用するのならば、起動が非同期であることに留意して
 呼び出し元が何らかの手を打たねばならない。例えば、

  非同期とは言えそんなに時間がかからないので、数秒の待ち (SLEEP) を入
  れればよいと割り切る。

  外部から起動の終了を知るてがかりを得て、以降のプログラムを実行するよ
  うな待ちの手続きを組み込む。

依頼そのものにかかる時間は数秒のオーダなので、全体のスクリプトの仕事の割
合からあまり気にならないようであれば、数秒の待ちを入れれば問題ないと思わ
れる。

[ ちょっと脱線 ]

Microsoft が提供している COM Object には、いくつかの ShellExecuteA() を
ラッピングしたメソッドが存在する。
  FolderItem.invokeVerb()
  Shell.Application>>shellExecute()
  WScript.Shell>>run() など

その外部仕様をみると、起動して生成したプロセスの終了まで呼び出し元が待つ
ようなオプションを導入しているものもある。(WScript.Shell>>run()) ただし、
open コマンドを処理するのみに特化され、今回のように print コマンドなどそ
の他のコマンドにまで適用できるよう配慮されていないように思われる。

そのあたりまじめに考えるには、ShellExecuteEx() の SHELLEXECUTEINFO 型の
ことをもっと勉強しないといけないように msdn を読んで感じた。


アルジャーノン さん 2003年 06月 26日 23時 49分 45秒

>あささんへ
すみません。ソースのサンプルはあささんが書いてくれたとうりでした。
この掲示板に書く時にSETを書き忘れていました。
そんな訳で、
未だに現象はかわりません。VBSファイルのダブルクリックだと通常使うプリンターはころころ変わるのに、ASPからだと駄目です。
このASPファイルは、WEB上でいつも起動させますが、
ASPファイルを置く場所は特に制約はないんですよね。
もう3週間ぐらい悩んでます。IISの設定時の常識的な事ができてないのかも
しれません。
どうか助けて下さい。

彩香 さん 2003年 06月 26日 16時 27分 34秒

To:いりやさん

>こちら、DDE を使用して印刷を指示するようになっているために、その部分
>もシミュレートする必要があるようです。(.txt ファイルは DDE を使用し
>ていないためにうまくいく)

あれらが取得できていたので、ついできるのかと思ってしまいました、
でも、このスクリプトではできませんと、きちんとありましたね(^^;

>なんとか ShellExecuteA() Win32 API まで橋渡しをする機能があって、
>それが WSH から利用できれば御の字なんですけどね。そうすると DDE の
>シミュレートは Windows Shell に頼めますし。

そうですね、これで"Print"で解決だったのですけどね。

>むたぐちさんの頁に紹介されていた IShellDispatch2 オブジェクトを
>WinXP 上で試しておりますが、ShellExecute() メソッドがうまく機能し
>ないようです。うむむ。

そんなメソッドがあったのですね(^^

私も同Win XPの環境で早速試してみましたが、
これでWord、Excel、Txtの全てが印刷できるようです。

PrintFiles FF 'フォルダオブジェクト

Sub PrintFiles(F)

For Each subf In F.SubFolders

PrintFiles subf

Next

For Each ObjF In F.Files

strFilePath = F.Path & "\" & ObjF.Name
Shell.ShellExecute strFilePath, NULL, NULL, "print", SW_SHOWNORMAL

Next

End Sub

試してみるものですねぇ、ビックリでした(^^

こんな素敵なメソッドをありがとうございますm(__)m

真琴 さん 2003年 06月 26日 14時 58分 03秒

以前質問させてもらった真琴です。
すごく馬鹿みたいな質問でごめんなさい。

このHPのあちらこちらで
「VBSランゲージリファレンス」という言葉がでてきてますよね。

例えば、Lesson13 ファイルシステムにアクセスする  の項目4の下の行
 『このLessonは、VBSランゲージリファレンスの「スクリプティングランタイム
  リファレンス」とともにご覧ください。 』

この「VBSランゲージリファレンス」とはどれのことを言ってらっしゃるのですか?
何か、本のことなのか、それとも、scd56jp.exe のことなんでしょうか?
教えてください。

もし、scd56jp.exe のことだとしたら、これをDLしてインストールした場合、
バージョンが5.6に上がってしまうんでしょうか?
ちなみに、自分のバージョンが今、なんなのかを知りたいんですという、質問を
以前こちらでさせていただいて、ヒカリブシさんより以下の返事をもらいました。

2003年 06月 19日 15時 52分 53秒
'===========================================================

version=ScriptEngineMajorVersion &"."&ScriptEngineMinorVersion
if version >= 5.1 then
MsgBox "WSH 2.0を使用してるで。"
else
MsgBox "エンジンが古すぎるで。"
end if

'===========================================================

これを実行すると「WSH 2.0を使用してるで。」というメッセージがでてくるので
うちの使っているのは、2.0なんだろうなぁ と思っているんですが・・・。
上記の scd56jp.exe を入れた場合、5.6に上がってしまうのかどうか心配です。
逆に、2.0を使っているのに、5.6のヘルプを見てもしょうがないのかなぁ(笑) って気もするので、いろいろ教えてください。

そういうリファレンスとか、WSHのことが体系的に書かれたものを読みたいので、
WSHので書籍とか、ページとがあれば(初心者用)、よろしくお願いします。

じゃけん さん 2003年 06月 26日 13時 55分 30秒

>いりやさんへ
そこまでいくと、私もわからんです(汗)
お願いします^^;;;


で、まったく別の質問です。
ここの過去ログで以下のようなものを見つけたのですが、
--------------------------------------------------
Set WshShell = WScript.CreateObject("WScript.Shell")
'59は、ボタンのないダイアログを表示させる引数です。
WshShell.popup "5秒後に閉じます。",5,"ボタンなしダイアログ", 59
--------------------------------------------------
喜び勇んで実行しても何も表示されません・・・・
59を0にすると、普通に動きます。
なんででしょ?(汗)

Return