魔界の仮面弁士 さん 2004年 02月 20日 15時 39分 47秒

| 4番目の引数は Variant だってMSは言っているのに〜。
まぁ、嘘では無いですよね。(^^;)

| postdat = Array("name=hoge")
あ、これだと駄目なんです。
VarType(postdat)が、8209(=vbArray Or vbByte)ではなく、
8204(=vbArray Or vbVariant)になってしまいます。

配列には違いありませんから、POST自体は一応行われるのですが、
Byte型とVariant型では、データサイズがまったく違いますので、
cgiに余計なデータまでもが送信されてしまうはずです。

| SAFEARRAY Data Type を指し示すArray 形データってどうやって作るんでしょう???
残念ながら、VBScriptやJScript自体の機能では作成できません。
ActiveX(COM)コンポーネントの手助けが必要です。

バイト配列を作成可能なコンポーネントとしては、
ADO(2.5以上)の『Streamオブジェクト』や
フリーソフトの『BASP21』などがあります。
(BASP21の方がコーディングは楽ですが、別途インストールが必要です)

例えば、Streamを使う場合はこんな感じです。
'====================
Set S = CreateObject("ADODB.Stream")
S.Open
S.Charset = "Shift_JIS"
S.WriteText "name=hoge"
S.Position = 0
S.Type = 1
postdat = S.Read(-1)
S.Close
Set S = Nothing
'====================

| document.getElementByid("hoge").value
| で参照できることを確認しました。
BODY要素の直下にあるコントロールは、hoge.value だけでアクセスできますが、
form要素の下にある場合は、formのコントロールとして document.forms.item(0).hoge.value で
アクセスしたり、allコレクション経由で document.all.hoge.value などと
書く事もできます。

| <form>
| <input type="text" id="hoge">
| </form>

正しくは、
<form action="〜.cgi" method="post">
<input type="text" id="hoge" name="hoge">
</form>
ですよね。(コントロールにname属性を付けないと送信されません)

いりや さん 2004年 02月 20日 14時 41分 08秒

> SAFEARRAY Data Type を指し示す Array 形データってどうやって作るんでしょう???

うっすみません、VBScript は苦手で・・・。(^^;

Akira さん 2004年 02月 20日 14時 30分 01秒

>いりや さん

>| いりや さん 、ありがとうございます。form を使うと、form内に入力された
>| データを、id属性をつけて VBScript から参照できなくなる(私が試した限り
>| ではそうでした)ので、今回は見送らせていただきます。
>
>こちら本当ですか?
>
>Dynamic HTML Object Model の説明書きを読むと document オブジェ
>クトの getElementById() メソッドを使えば参照できるとおもった
>のですが。。

いや、私が知らなかっただけで、getElementById を使えば大丈夫でした。

HTA内で、
<input type="text" id="hoge">
に入力されたデータを VBScript では
hoge.value
として参照していたのが、

<form>
<input type="text" id="hoge">
</form>
の場合は、
document.getElementByid("hoge").value

で参照できることを確認しました。アドバイスありがとうございました。

>| 情報ありがとうございます。4番目の引数は Variant だってMSは言っているのに〜。とりあえず vbArray
>| となるようにして試してみました。
>
>こちら、最後のほうに実はかいてあったりします :-)

Navigate2 のドキュメントは、冒頭だけ読んで、コリャ違う、と思ったので
最後まで読んでいませんでした。ヤラレタ〜。SAFEARRAY Data Type を指し示す
Array 形データってどうやって作るんでしょう???

いりや さん 2004年 02月 20日 13時 20分 22秒

Akira さん、

本題じゃないところにばかり目がいって申し訳ないです。。

| いりや さん 、ありがとうございます。form を使うと、form内に入力された
| データを、id属性をつけて VBScript から参照できなくなる(私が試した限り
| ではそうでした)ので、今回は見送らせていただきます。

こちら本当ですか?

Dynamic HTML Object Model の説明書きを読むと document オブジェ
クトの getElementById() メソッドを使えば参照できるとおもった
のですが。。

msdn, getElementById Method
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/methods/getelementbyid.asp

form オブジェクトには getElementByID() メソッドは備わってい
ませんから、form オブジェクトしか参照できないのであれば、form
オブジェクトの all コレクションから要素を一つずつ取り出して
id 属性が一致するものを見つける、そのような作りこみが必要に
なってきます。

ですが、今回は document オブジェクトも
InternetExplorer.Application の document 属性経由で参照でき
るはずですからこの作りこみは必要ないとおもわれます。

| 情報ありがとうございます。4番目の引数は Variant だってMSは言っているのに〜。とりあえず vbArray
| となるようにして試してみました。

こちら、最後のほうに実はかいてあったりします :-)
msdn も意地悪ですよね〜。

構文(シンタックス)の説明では

[PostData As Variant,]

パラメータの PostData の説明では、

| PostData
|
| Optional. Data to send to the server during the HTTP POST
| transaction. For example, the POST transaction is used to
| send data gathered by an HTML form to a program or script.
| If this parameter does not specify any post data, the
| Navigate method issues an HTTP GET transaction. This
| parameter is ignored if URL is not an HTTPURL.

とだけ書いてあるのですが、navigate2() メソッドの注釈に、

| The post data specified by PostData is passed as a SAFEARRAY
| Data Type structure. The variant should be of type Array and
| point to a SAFEARRAY Data Type. The SAFEARRAY Data Type
| should be of element type Integer, dimension one, and have
| an element count equal to the number of bytes of post data.

と但し書きが。``The variant shoud be of type Array and point
to a SAFEARRAY Data Type.'' うーん。

msdn, Navigate Method
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/methods/navigate.asp

msdn, Navigate2 Method
http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/webbrowser/reference/methods/navigate2.asp

Akira さん 2004年 02月 20日 09時 59分 33秒

》 魔界の仮面弁士 さん

情報ありがとうございます。4番目の引数は Variant だってMSは言っているのに〜。とりあえず vbArray
となるようにして試してみました。

postdat = Array("name=hoge")
objIe.Navigate "http://somewhere/hoge.cgi, , , postdat

サーバのログを見ると確かに POSTされているようです。しかし、どんな
データをPOSTしても、CGIが受け取るデータは、

keyword=よく分からないバイナリデータ

となっています。なんらかの形式にエンコードされているのでしょうか...

いりや さん 、ありがとうございます。form を使うと、form内に入力された
データを、id属性をつけて VBScript から参照できなくなる(私が試した限り
ではそうでした)ので、今回は見送らせていただきます。

なお、もちょっとやりたかったことを詳しく書くと、LANに接続するために認証
するシステムにおいて、認証サーバがPOSTデータを受け付ける(暗号化なし^^;)
ようになっており、そのユーザ名とパスワードを入力して送るラッパーをHTAで
作っていました。
実は URLにデータをくっつけてGETで送っても認証サーバは受け付けてくれるのですが、
ブラウザが表にでるとパスワード丸見えになるので、POSTでできないか、と
試していました。

一方、objIe.Visible = False
として、データ送受信が完了するまで Waitする方法を

http://member.nifty.ne.jp/aya/wsh/wsh07.htm

で見つけたので、とりあえず今回はそれで用が足りることになりました。

アドバイスありがとうございました。



いりや さん 2004年 02月 19日 16時 06分 00秒

>                 elapsedSecs = elapsedSecs + waitSecs;

                elapsedSecs = elapsedSecs + 0.1 * 1000;
が正しかったです。うむむ。

魔界の仮面弁士 さん 2004年 02月 19日 14時 12分 40秒

》 Akira さん

Navigate/Navigate2メソッドの第4引数には、配列を渡してください。
それ以外(例えば文字列)を渡した場合は、GET扱いになります。
相手がcgiの場合は、VarTypeの戻り値が8209(=vbArray Or vbByte)に
なるような配列を指定すると良いでしょう。

文字列で指定したいのであれば、InternetExplorer.Navigate2の替わりに、
XMLHTTP.send を利用する事を検討してみてください。
もしくは、いりやさんの回答にあるように、form.submitするか…ですね。

いりや さん 2004年 02月 19日 12時 22分 20秒

と書いていましたが、

> HTAのフォームから、直接CGIにPOSTするというテもあるのですが、

というケースに該当するのかな、という気がしてきました。Akira さん
の求めているものとちと違うようですね。わたしのサンプルは。

いりや さん 2004年 02月 19日 12時 20分 21秒

> "alc の辞書ページを使用して [スクリプト] を国語辞典で調べます。"

これ誤りですね。。"by intent" という単語を調べます、が正しい。

いりや さん 2004年 02月 19日 12時 19分 13秒

AKIRA さん、

> HTAのinputタグに入力されたデータを、VBScriptを呼び出してCGI
> にデータをPOSTすることを試しています。しかし、たとえば

Dynamic HTML Object Model の form オブジェクトの submit() メ
ソッドの使用も検討いただけます。

msdn, form element | form object
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/objects/form.asp

[ サンプル (WSH/JScript) ]

var queryString = 'by intent';
example(queryString);

function example(queryString) {
    var aShell = new ActiveXObject("WScript.Shell");
    aShell.popUp("alc の辞書ページを使用して [スクリプト] を国語辞典で調べます。", 3);

    var e = new InternetExplorer();
    e.visible(true);
    e.navigate('http://www.alc.co.jp/');

    var aForm = e.source.document.ejr;
    aForm.word_in.value = queryString;
    aForm.submit();
    e.waitForever();

    aShell.popUp("処理を完了しました。", 3);
}

function InternetExplorer () {
    this.source = WScript.createObject('InternetExplorer.Application', 'InternetExplorer_');
    this.visible = function () {
        if (arguments.length == 0)
            return this.source.visible;
        if (arguments.length == 1 && typeof(arguments[0]) == 'boolean') {
            this.source.visible = arguments[0];
            return this.source.visible;
        }
    }
    this.navigate = function () {
        if (arguments.length == 0) {
            this.source.navigate('about:blank');
            this.waitForever();
        }
        if (arguments.length == 1 && typeof(arguments[0]) == 'string') {
            this.source.navigate(arguments[0]);
            this.waitForever();
        }
    }
    this.waitForever = function () {
        while (this.source.busy || this.source.readyState != 4)
            WScript.sleep(0.1 * 1000);
    }
    this.waitWithTimeout = function (timeout) {
        var elapsedSecs = 0;
        do {
            if (elapsedSecs > timeout)
                return false;
            else {
                WScript.sleep(0.1 * 1000);
                elapsedSecs = elapsedSecs + waitSecs;
            }
        } while (this.source.busy || this.source.readyState != 4)
        return true;
    }
}

Akira さん 2004年 02月 19日 11時 53分 12秒

HTAのinputタグに入力されたデータを、VBScriptを呼び出してCGIにデータをPOSTすることを試しています。しかし、たとえば

set objIe = CreateObject("InternetExplorer.Application")
objIe.Navigate "http://somewhere/hoge.cgi", , , "name=taro"

とやっても、CGIのあるサーバのログを見るとGETされたことになっていて、POST
が実現できません。MSのサイトを見ると、Navigateメソッドの第4引数を使うと、
POSTトランザクションが使えるように書いていますが...。

HTAのフォームから、直接CGIにPOSTするというテもあるのですが、
inputタグに入力されたデータを、他のVBScriptからも使用したいので、
途中に VBScript をかませたいと考えています。

よろしくお願い致します。

SOU さん 2004年 02月 19日 10時 53分 54秒

すみません、WSH勉強中のSOUと申します。
お恥ずかしながら質問させて頂きます。

WSHにて記述したプログラムを実行すると、MsgBOXやInputBOX関数などで
ダイアログが表示される時、ダイアログがアクティブの場合と非アクティブ
になる場合があります。
これは、仕様なのでしょうか、それともOS毎に何か条件があるのでしょうか。
もしくは、表示されるダイアログは常にアクティブ、の様なコードがあれば
ご教授願います。

ウォン さん 2004年 02月 16日 21時 49分 35秒

wsh 、もちろん、しっていますよ...。

ウォン さん 2004年 02月 16日 21時 47分 43秒

vb、勉強中です。

デザイン、何とか理解可能。

問題は、コード(スクリプト)なんですよ。

ブルーバックスから、出ている「vb」本、

よんでいるのですが、なかなか...。

いりや さん 2004年 02月 14日 15時 12分 47秒

緑の風さん、

| そのため、表示位置をかえるには、サイトの winopen() 関数の実体に、新しい
| window オブジェクトを捕捉してその window オブジェクトの moveTop() メソッ
| ドをキックするよう「手をいれなければならない」とわかりましたが、もちろん
| それはできない相談です。

ここ、補足します。「別にサイトでなくたっていいのではないか?」という選択
肢があったことをすっかり忘れていました。

要は winopen('http://www.hanajikan.jp/cgi-bin/today/exec.cgi') が実行さ
れればよい、と達観できれば、呼び出し元 (遠隔操作している側) にスクリプト
をもってくれば実現は可能です。

具体的には元々の window オブジェクトは、仮に ie 変数に
InternetExplorer.Application オブジェクトが束縛されているとして、
ie.document.parentWindow で捕捉できます。これを使って、

winopen() のかわりに、

childWindow = ie.document.parentWindow.open('http://www.hanajikan.jp/cgi-bin/today/exec.cgi, "newwin1","toolbar=no,...")
childWindow.moveTo(...);

を呼び出し元に展開します。そうするとこれ以降 childWindow 変数を通じて
document プロパティーにもアクセスできるようになります。

当時、この方式を選択しなかった理由は、なるべく通常のユーザの操作に近い操
作を遠隔で行おう、という方針からです。動くには動くけど、ちょっとこれは違
うよな、とおもって選択はしませんでした。

いりや さん 2004年 02月 14日 13時 27分 16秒

緑の風さん、

submit した後のウインドウをどうやって捕捉するか、Internet Explorer を
COM ベースで扱うときの大きな課題ですよね。

そのページの HTML (及び SCRIPT タグ内のスクリプト) を見ていませんのでハ
ズしているかもしれません。

ですが、予想されるシナリオとして、submit した後に新しいウインドウを開く
タイミングで Dynamic HTML Object Model の window オブジェクト [1] が生成
されているが、その window オブジェクトを、遠隔操作をしているスクリプトか
ら得る手立てがない。そのため、それ以降、window オブジェクトを経由してそ
のページのコンテンツ (window.document プロパティー) にアクセスすることも
できない。

[1] msdn, window Object,
http://msdn.microsoft.com/library/default.asp?url=/workshop/author/dhtml/reference/objects/obj_window.asp

たとえば、角川書店さんの花時間 (http://www.hanajikan.jp/) というサイトの
「一日一花」というボタンをクリックすると、新しいウインドウが開くのですが、
そのウインドウの表示位置をスクリーン左上にもっていきたい、という課題にい
ぜん私は取り組みました。そのときのことを簡単にお話します。

当該ボタンのアンカーの href フィールドの値は、

<a href="javascript:winopen('http://www.hanajikan.jp/cgi-bin/today/exec.cgi'>

で、winopen() 関数の実体が、

function winopen(file){
    window.open(file,"newwin1","toolbar=no,...")
}

のような感じで、window オブジェクトの open メソッドを呼んでいました。
open メソッドを呼ぶと新しい window オブジェクトが生成されるのですが、こ
の window 変数 (に束縛されている window オブジェクト) から生成される
window オブジェクトをひきあてる手がありません。(逆に生成された window オ
ブジェクトには opener and/or parent プロパティーを通じて呼び出し元の
window オブジェクトを知ることができる!)

そのため、表示位置をかえるには、サイトの winopen() 関数の実体に、新しい
window オブジェクトを捕捉してその window オブジェクトの moveTop() メソッ
ドをキックするよう「手をいれなければならない」とわかりましたが、もちろん
それはできない相談です。

それで、このようなケースは COM ベースでの遠隔操作 *だけ* で考えた方式の
一つの限界ではないかと知った次第です。


では、それでおしまいか、といえば、IE とは関係ないところで、
Shell.Application オブジェクトというのがいて、このオブジェクトの windows
プロパティーには現在開かれているエクスプローラ (と Internet Explorer) の
window オブジェクトのコレクションが保持されています。

[2] むたぐちさん, Shell オブジェクト
http://www.roy.hi-ho.ne.jp/mutaguchi/wsh/index.html

この windows コレクションから件 (くだん) の window オブジェクトをひきあ
てる、という手があります。

引き当て方については、こちらの掲示板の過去ログにも何度か掲載されています
ので、AKiOS さんのプログラムでキーワード検索してみるとよいでしょう。また
WSH ではありませんがこういう過去ログ [3] も参考になるでしょう。

[3] うみうみ屋さんの掲示板
http://hidebbs.net/bbs/umiumi?s=7&n=16815696 (Shell.Application)
http://hidebbs.net/bbs/umiumi?s=7&n=16899636 (Shell.Application)
http://hidebbs.net/bbs/umiumi?s=7&n=19683658 (IE 一般)


ご参考になれば幸いです。

               ★☆

さいごに、さきの表示位置の変更について結末を申し上げると、window オブジ
ェクトを使わず、うみうみ屋さんの UWSC [4] の組込み関数 GETID() および
Win32 API MoveWindow() を使用してウインドウの捕捉と位置変更を実現しまし
た。スクリプトはこちら [5] から確認できます。

[4] うみうみ屋さん, UWSC
http://www002.upp.so-net.ne.jp/umiumi/

[5] todays-flower.uws (下記の URL の "アンカーのクリック#2" に保存)
http://iriyak.adam.ne.jp/uwsc.html

魔界の仮面弁士 さん 2004年 02月 14日 13時 25分 11秒

> RUNAT=Serverは間違っていると思います。
一応、ポストバック処理を行えば、クリック時にサーバ側スクリプトが実行されるように
コーディングする事はできますが、今回は「クライアント側で表示」させたいのですから、
クライアント側スクリプトで処理を行わないと、意味が無いという事です。


> やってみたら、ASPなしの純粋なVBSCRIPTなら、
えぇと、『純粋なVBScript』というのは、どういう意味でしょうか?


> Onclickイベントは問題なし関数を呼べるのですが
そもそも、イベントは「呼ぶ物」ではなく「呼ばれる物」ですよね。(^^;

onclickイベントは、JScriptやVBScript自体の機能ではなく、HTML側の機能ですので、
HTML中にスクリプトとの関連付けを記す必要があります。

例えば、
 <button id="Button1" onclick="Test1()">ボタン</button>
などと書いておけば、ボタン押下時に Test1 が実行されます。

onclick属性中に埋め込む方法以外にも、

 <button id="Button2">ボタン</button>
<script type="text/VBScript">
Function Button2_onclick()
MsgBox "テスト"
End Function
</script>

のような関数命名方法による「自動的な関連付け」を施す事や、
 <button id="Button3">ボタン</button>
<script type="text/VBScript">
Set Button3.onclick = GetRef("Test3")
Function Test3()
MsgBox "テスト"
End Function
</script>
のように、GetRef関数を使って後から割り当てる方法などもあります。

この点に関しては、下記の資料を参照してみてください。
http://www.microsoft.com/japan/msdn/columns/scripting/scripting04092001.asp


> ASPの環境で呼べないです
サーバー側スクリプトと、クライアント側スクリプト、どちらで処理しようとしていますか?
ASPにおいて、RunAt=Server 指定のscript要素で処理したいのであれば、「ボタンが押された」という事を
サーバ側に伝えるための[ポストバック]と呼ばれる処理を実装する必要があります。
(ASP.NETの場合は、ポストバックのための機能が標準で用意されています)

クライアント側スクリプトであれば、先に書いたように、HTMLの要素とスクリプトとの間で
イベントの関連付けを正しく記す必要があります。

Yoko さん (toyama@simplenet.co.jp) 2004年 02月 14日 12時 46分 30秒

いりやさん

やってみたら、ASPなしの純粋なVBSCRIPTなら、Onclickイベントは問題なし
関数を呼べるのですが、ASPの環境で呼べないです、それはASPはすべてのイベントを一度にサーバに送ってからの原因か、それともほかの原因かよくわからないです。

いりや さん 2004年 02月 14日 12時 24分 59秒

yoko さん、

> もしかして、OnclickイベントはVBSCIPTの関数を呼べないでしょうかと思っています。

これって本当でしょうか。msdn の VBScript 解説ページによれば、

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/vbsfirst.asp
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/script56/html/vtoriVBScriptInInternetExplorer.asp

OnClock ハンドラも VBScript で書けるようによめました。

ちょっと脱線しました。

いりや さん 2004年 02月 14日 12時 17分 15秒

ともさん、

> このように機能からメソッドを調べる方法について教えて戴けないでしょうか?

以下のお二方の解説ページは、ともさんの期待にかなり副う(そう)ものと思い
ます。VBScript 言語だけで書かれていないので読み替えが必要ですが大層な話
ではないでしょう。

むたぐちさん, Windows Script Host(WSH)の解説ページ
http://www.roy.hi-ho.ne.jp/mutaguchi/wsh/index.html

AYA さん, 趣味のJavaScriptなページ
http://member.nifty.ne.jp/aya/index.htm

おまけ: jw さん, wsh Utilities and Scripts (GUI をあの手この手でこさえる
トリックがつまっている。ボリュームがあります。消化不良にならないようご注
意!)
http://home.att.net/~wshvbs/index.htm

ただ、ことマイクロソフトが提供している Component Object Model
(shell32.dll や scrrun.dll が提供しているオブジェクト) についてはの数が
あまり多くないこともあって仕様を説明した資料を一度目を通して、だいたいで
きることを把握される方が多いようです。


ところで、Windows Script Host と GUI の関係については、後継と思われる
.Net フレームワークを視野に入れてはいかがでしょうか。

AYA さんが、JScript.Net 講座をはじめられました。そちらには .Net 製品と一
緒に提供される GUI 関連のライブラリについても言及されています。
http://member.nifty.ne.jp/aya/JScript.NET/index.htm

Windows Script Host は GUI について包括的な枠組みを提供しているわけでは
なく外にその機能を求めている格好ですので、プログラム言語環境全体として統
一感がないようにおもいます。一方、.Net 製品は最初から GUI を見据えてライ
ブラリも提供しています。枠組みがあったほうがよいとお考えならば .Net 製品
の検討をおすすめします。

yoko さん (toyama@simplenet.co.jp) 2004年 02月 14日 11時 37分 14秒

魔界の仮面弁士さん
ご説明ありがとうございます、
質問についての答えはいかです:
1)開く場所はクライアントで、サーバではないです。RUNAT=Serverは間違っていると思います。
2)開く[フォルダ」もクライアントです。
3)処理言語については、どちでもいいですけど、今の問題はOnclikイベントでVBSCIPTで作ったgetFolderPath()関数を呼べないみたいです。この関数だけじゃなくて、何でもそうです。でもJavascriptで作ったほかの関数でやってみったら、成功でした。もしかして、OnclickイベントはVBSCIPTの関数を呼べないでしょうかと思っています。
ASPの経験はとても浅いで、ご指導をお願いいたします。

とも さん 2004年 02月 13日 15時 22分 03秒

魔界の仮面弁士 さん、はじめまして&ありがとうございます。
なにぶん始めてなので、何を調べていいやら悩んでました。

BrowseForFolderとvbsをキーワードに検索すると、いくつかのサンプルにたどり着くことが出来ました。
このように機能からメソッドを調べる方法について教えて戴けないでしょうか?

魔界の仮面弁士 さん 2004年 02月 13日 15時 03分 46秒

》とも さん
> WSHでGUIを利用する事はできませんか?
GUIではありませんが、CScript.exe経由での起動であれば、
CUIからの入力ができます。

> メッセージボックスやテキストの入力は出来るようですが
メッセージボックスやテキストの入力というのは、
VBScriptのMsgBox/InputBoxなどの事でしょうか。

WSHに拘らないのであれば、拡張子HTAのファイル(HTML Application)を
使うという方法があります。

もしくは、WSHからInternetExplorerオブジェクトを起動して、
それを入力画面代わりに使うという選択肢もあります。


> フォルダやファイル選択のダイアログボックスは利用できないでしょうか?
COMコンポーネントを利用してみてください。

例えば、Shellオブジェクトの BrowseForFolderメソッドや、
ExcelのDialogオブジェクト、OfficeのFileDialogオブジェクトなどを
利用する事ができます。

魔界の仮面弁士 さん 2004年 02月 13日 14時 54分 43秒

# 投稿がなんだか凄い事に(汗)

》 Yoko さん
うぅむ。RUNAT=Server…ですか?


状況が良く分からなかったので、以下の項目について教えて下さい。

1) [開く場所]について
→BrowseForFolderメソッドは、フォルダの選択画面を表示するための物ですが、
 それを「サーバ上の画面」に表示させたいのでしょうか。
 それとも「クライアント側の画面」に表示させたいのでしょうか?

2) [フォルダ]の所在について。
→サーバ上のフォルダを開きたいのでしょうか。
 それともクライアント上のフォルダを開きたいのでしょうか?


3) 処理言語について
→最後に「javascriptのFOLDER開く関数」との記述がありましたが、
 サーバ側スクリプト(今回はVBScriptですよね)ではなく、
 クライアント側スクリプト(JScriptかな?)で行いたいのでしょうか?

上記が(1)〜(3)それぞれが明らかになれば、もう少し具体的な回答ができるかと思います。


--------------------
前提条件が曖昧だったので、以下、わかる範囲で一般論的な話を書いてみます。

まず、上記の(1)と(2)ですが、
 <a> サーバのフォルダをクライアント画面上に開くのか
 <b> サーバのフォルダをサーバ画面上に開くのか
 <c> クライアントのフォルダをクライアント画面上に開くのか
 <d> クライアントのフォルダをサーバ画面上に開くのか
によって、それぞれ話が変わってきます。

<a>サーバ上のフォルダをクライアント上で開くなら、BrowseForFolderではなく、
 IEのhttpFolderデフォルトビヘイビアを使った方が良いと思います。(要IE5.0以上)
 この場合、httpフォルダとしてアクセスできるようにしておく必要があります。

<b>サーバ上のフォルダをサーバ上で開くのは、少々困難です。
 これは、IISはサービスとして起動される物であるため、Windows Serverの
 デスクトップには、ログインされていない状態で運用される事が一般的で
 あるという点と、IISから他の画面を開くのは、通常のIISアカウントよりも
 上位の権限を与える/偽装する必要があるという理由によります。

<c>クライアント上のフォルダをクライアント上で開くには、BrowseForFolderでいけます。
 ただし、ブラウザ(IE)からCOMコンポーネントを起動できるだけの権限設定が
 許可されている必要があるという点と、クライアントPC上の Shell32.dll が
 Version 4.7以上で無ければいけないという制限があります。

<d>クライアント上のフォルダをサーバ上の画面に表示させたいのであれば、
 クライアントのフォルダ情報を、何らかの形でサーバ側に通知させねばなりません。
 少々無理のある仕様なので、あまりやるべきでは無いでしょうね。


で。(3)ですが、これは(1)で「サーバ上で開く」事を選択した場合は、
基本的にサーバサイドスクリプト、すなわち<%〜〜%>ブロックか、もしくは
<script RunAt="Server">〜〜</script>ブロックを使う事になります。
そして、クライアント側で開く場合は、runat指定の無いscript要素、または
それに相当する機能(エレメントビヘイビア等)を使う事になるでしょう。

# サーバ側でJScriptを使ったり、クライアント側でVBScriptを使うこともできますが、
# そうした言語選択は、あまり一般的では無いようです。

とも さん 2004年 02月 13日 14時 49分 49秒

WSHでGUIを利用する事はできませんか?
メッセージボックスやテキストの入力は出来るようですが
フォルダやファイル選択のダイアログボックスは利用できないでしょうか?

宜しくお願いします。

Yoko さん (toyama@simpleねt.co.jp) 2004年 02月 13日 11時 46分 46秒

ASPでFOLDERを開く関数を探しています。
いまVBScriptのスースがあるですが、onclick イベントでこの関数を呼ぶですが、ぜんぜん反応してない、

script language="VBScript" RUNAT=Server>
<!--
function getFolderPath(s)
msgbox "FOLDER aaaa"
dim x, osh, ofl
set osh = CreateObject("Shell.Application")
set ofl = osh.BrowseForFolder(0, s, 1)
if (ofl is Nothing) then
getFolderPath = ""
else
on error resume next
getFolderPath = ofl.ParentFolder.ParseName(ofl.Title).Path
If Err.Number > 0 Then
getFolderPath = ""
Err.Clear
msgbox ofl.title & " よりも下位の階層を指定してください", vbOkOnly+vbExclamation, "制限事項"
End If
on error goto 0
end if
set osh = Nothing
set ofl = Nothing
end function

// -->
</script>

原因をわかる人ぜひ教えてください、
もしjavascriptのFOLDER開く関数があれば、ぜひ教えてください、
とても悩んでいます。

Yoko さん (toyama@simple.co.jp) 2004年 02月 13日 11時 46分 32秒

ASPでFOLDERを開く関数を探しています。
いまVBScriptのスースがあるですが、onclick イベントでこの関数を呼ぶですが、ぜんぜん反応してない、

script language="VBScript" RUNAT=Server>
<!--
function getFolderPath(s)
msgbox "FOLDER aaaa"
dim x, osh, ofl
set osh = CreateObject("Shell.Application")
set ofl = osh.BrowseForFolder(0, s, 1)
if (ofl is Nothing) then
getFolderPath = ""
else
on error resume next
getFolderPath = ofl.ParentFolder.ParseName(ofl.Title).Path
If Err.Number > 0 Then
getFolderPath = ""
Err.Clear
msgbox ofl.title & " よりも下位の階層を指定してください", vbOkOnly+vbExclamation, "制限事項"
End If
on error goto 0
end if
set osh = Nothing
set ofl = Nothing
end function

// -->
</script>

原因をわかる人ぜひ教えてください、
もしjavascriptのFOLDER開く関数があれば、ぜひ教えてください、
とても悩んでいます。

Yoko さん (toyama@simple.co.jp) 2004年 02月 13日 11時 45分 44秒

ASPでFOLDERを開く関数を探しています。
いまVBScriptのスースがあるですが、onclick イベントでこの関数を呼ぶですが、ぜんぜん反応してない、

script language="VBScript" RUNAT=Server>
<!--
function getFolderPath(s)
msgbox "FOLDER aaaa"
dim x, osh, ofl
set osh = CreateObject("Shell.Application")
set ofl = osh.BrowseForFolder(0, s, 1)
if (ofl is Nothing) then
getFolderPath = ""
else
on error resume next
getFolderPath = ofl.ParentFolder.ParseName(ofl.Title).Path
If Err.Number > 0 Then
getFolderPath = ""
Err.Clear
msgbox ofl.title & " よりも下位の階層を指定してください", vbOkOnly+vbExclamation, "制限事項"
End If
on error goto 0
end if
set osh = Nothing
set ofl = Nothing
end function

// -->
</script>

原因をわかる人ぜひ教えてください、
もしjavascriptのFOLDER開く関数があれば、ぜひ教えてください、
とても悩んでいます。

いりや さん 2004年 02月 12日 23時 30分 12秒

むたぐちさんのコードを WSH/JScript にポーティングしてみました。最初
example2() のような正規表現で試していたので最左最長一致 (leftmost
longest match) でダメなのかなあと思っていたら ? を一個入れたらうまく
いきました。なるほどね・・・。

var anArray;
var message;

anArray = example1();
message = anArray.length + (anArray.length > 1 ? ' matches: ' : ' match: ') + anArray;
WScript.echo(message);

anArray = example2();
message = anArray.length + (anArray.length > 1 ? ' matches: ' : ' match: ') + anArray;
WScript.echo(message);

function example1(){
    var s = 'aaa/*bbb/*ccc*/dddd/*eeee*/';
    var regexp = /\/\*.+?\*\//g;
    return s.match(regexp);
}

function example2(){
    var s = 'aaa/*bbb/*ccc*/dddd/*eeee*/';
    var regexp = /\/\*.+\*\//g;
    return s.match(regexp);
}

たかはし さん 2004年 02月 12日 22時 41分 38秒

To:管理人様

早速のご返信ありがとうございます。
無事動作を確認でき解決いたしました。
ありがとうございました。

管理人むたぐち さん 2004年 02月 12日 22時 26分 54秒

To: たかはし さん

Set objRgex = New RegExp

objRgex.Pattern = "\/\*.+?\*\/"
objRgex.Global=True

For Each oMatch In objRgex.Execute("aaa/*bbb/*ccc*/dddd/*eeee*/")
msgBox oMatch
Next

でどうでしょうか。


To: 漣 さん

folder.htt内でスタイルを定義している部分を弄れば変えられます。
といっても今手元にWinXPしかないので、ちょっと確認できません。

たかはし さん 2004年 02月 12日 21時 58分 42秒

管理人様、皆様はじめまして。たかはしといいます。
いつも参考にさせていただいております。
ありがとうございます。

今回VBSの正規表現について悩んでおります。
どなたかご教授お願いいたします。

"aaa/*bbb/*ccc*/dddd/*eeee*/"
上記の文字列から"/*.....*/"で囲まれた文字列を抽出しようとしています。

期待する結果として、

/*bbb/*ccc*/
/*eeee*/

の様に取得したいのですが、
objRgex.Pattern = "(\/\*)[^\/\*]*(\*\/)"
で試してみたところ、

/*ccc*/
/*eeee*/

このような結果となってしまいます。

/*....*/の中の/*を無視したいのですが思うように行きません。
どなたか解決策をご存知でしたらご教授お願いいたします。
よろしくお願いいたします。

魔界の仮面弁士 さん 2004年 02月 12日 21時 03分 21秒

》SARU さん
書き方は幾つかありますが、例えば、

'2004-02-10 09:00:00:00000'
'20040210090000.000000+***'
'20040210090000.000000+540'

などの形式が有効です。
http://msdn.microsoft.com/library/en-us/wmisdk/wmi/date_and_time_format.asp

SARU さん 2004年 02月 12日 13時 43分 22秒

訂正
Set EveSet = Service.ExecQuery _
("Select * From Win32_NTLogEvent Where TimeGenerated > '200402100900'")
です

SARU さん 2004年 02月 12日 13時 41分 44秒

WMI・WQLを教えてください。
Set EveSet = Service.ExecQuery _
("Select * From Win32_NTLogEvent Where TimeGenerated '200402100900'")
上記のようにイベントログより日時の条件に該当するものだけを
取得したいのですが、エラーとなってしまいます。
時間を指定せずに '20040210' だけを指定すると正常に処理が動くのですが、
どのようにしたら、時間も指定できるのでしょうか?

トラオ さん 2004年 02月 12日 09時 21分 59秒

知っている方お願いします。
BASP21を使用しているのですが、サーバーのセキュリティーをUPさせたことにより動作しなくなることってありますか?
またBASP21を使用する際のセキュリティー条件があるのでしょうか?

いりや さん 2004年 02月 12日 02時 29分 04秒

ひろみさん、

うまくいってなによりです。

ところで、マニュアルをみるとRuntime オブジェクトには、他にも
目的別に exec メソッドが用意されているようです。

    Process exec(String command)
    Process exec(String[] cmdarray)
    Process exec(String[] cmdarray, String[] envp)
    Process exec(String[] cmdarray, String[] envp, File dir)
    Process exec(String cmd, String[] envp)
    Process exec(String command, String[] envp, File dir)

これらの実装については C:\Program
Files\j2sdk_nb\j2sdk1.4.2\src.zip にある

    C:\Program Files\j2sdk_nb\j2sdk1.4.2\src\java\lang\Runtime.java

に公開されていますので一度読んでみると理解が進むとおもいます。
もっとも、最終的に Runtime オブジェクト Native メソッドの

    private native Process execInternal(String cmdarray[], String envp[], String path)
    throws IOException;

を呼んでいて、ここについては Sun がソースコードを持っている
のでしょうから、オブジェクトファイルをディスアセンブルする以
外に探索する手立てはないのですけどね。Google を散策している
と CreateProcess Win32 API を呼んでいるのでは??、といった発
言がポロポロと確認できます。

試しに、と Kaffe 1.0.6 WinCE 版のソースコードツリー (http://www.wince-devel.org/src/kaffee-wince-src.tar.gz)
を眺めてみましたが、execInternal() メソッドのいきついた先は最終的に
abort() でおわっていました :-(

残念です。

ひろみ さん 2004年 02月 12日 00時 54分 42秒

いりやさんへ
早速試してみました。動作確認できました。ありがとうございました。

いりや さん 2004年 02月 11日 23時 11分 44秒

ひろみさん、

JScript のファイルを同ディレクトリに置いた上で Process
exec(String[] cmdarray) メソッドを使ってみてはいかがでしょう
か。

[ MyTest.java ]

(インデントの為の全角スペースは半角スペース二つに置き換えて
ください)

import java.io.*;

public class MyTest {
  public static void main(String args[]){
    example1();
  }
  public static void example1() {
    String[] argumentsArray = {
      "wscript.exe",
      ".\\test.js",
      "This is argument 1.",
      "This is argument 2.",
      "This is argument 3.",
      "This is argument 4.",
      "This is argument 5.",
      "This is argument 6."
    };
    try {
      Runtime.getRuntime().exec(argumentsArray);
    } catch(IOException e){
      System.err.println("Error:" + e);
    }
  }
}

[ 実行例 ]

C:\Documents and Settings\iriyak\My Documents\java>dir
ドライブ C のボリューム ラベルは xxx です
ボリューム シリアル番号は xxx です

C:\Documents and Settings\iriyak\My Documents\java のディレクトリ

2004/02/11 23:02  <DIR>     .
2004/02/11 23:02  <DIR>     ..
2004/02/11 23:03       1,316 MyTest.class
2004/02/11 23:03        646 MyTest.java
2004/02/11 23:02       1,310 test.class
2004/02/11 23:02        644 test.java
2004/02/11 23:04        95 test.js
        5 個のファイル        4,011 バイト
        2 個のディレクトリ 24,286,851,072 バイトの空き領域

C:\Documents and Settings\iriyak\My Documents\java>type test.js
C:\Documents and Settings\iriyak\My Documents\java>type test.js
for (var i = 0; i < WScript.arguments.length; i++)
    WScript.echo(WScript.arguments.item(i));

C:\Documents and Settings\iriyak\My Documents\java>"C:\Program Files\j2sdk_nb\j2
sdk1.4.2\bin\java" MyTest

C:\Documents and Settings\iriyak\My Documents\java>


[ 参考 ]

Java2 SDK 1.4.0, Process exec(String[] cmdarray)

http://java.sun.com/j2se/1.4/ja/docs/ja/api/java/lang/Runtime.html#exec(java.lang.String[])

ひろみ さん 2004年 02月 11日 21時 54分 44秒

いりやさん
こんばんは。
私は
Process pro ;
pro = Runtime.getRuntime().exec();
こんな感じで使用しています。

hiro さん 2004年 02月 11日 21時 39分 54秒

exce()メソッドを使ってます。

いりや さん 2004年 02月 11日 21時 29分 40秒

ひろみさん、

どのメソッドをいまおつかいですか??

ひろみ さん 2004年 02月 11日 21時 21分 58秒

javaから引数を6つわたしてvbscriptファイルを起動させるにはどうしたらいいのでしょうか?引数なしではvbscriptファイルを起動できるのですが。

いりや さん 2004年 02月 11日 19時 18分 18秒

HELP ME さん、

WSH/JScript をつかった一例です。ご参考になさってください。

[ スクリプトについて ]

D:\xxx\z1.txt
D:\xxx\z2.txt

という風に削除したいファイルパスを記したファイルを用意する。(例では
D:\xxx\list.txt)

スクリプトを remove.js というファイル名で保存しダブルクリックして実行
する。

[ 動作確認環境 ]

WinXP Pro SP1 + IE 6.0 SP1 (Windows Script Host 5.6)


[ WSH/JScript ソースコード ]

var FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var listfilepath = 'D:\\xxx\\list.txt'; // 各行にファイルパスが書かれたファイル

main(listfilepath);

function main(listfilepath) {
    var filepathArray = generateFilepathArray(listfilepath);
    var removeBlock = function (each) {
        if (FileSystemObject.fileExists(each))
            FileSystemObject.deleteFile(each);
    }
    filepathArray.do_(removeBlock);
    filepathArray.waitUntilRemoved(); // See [1].
}

function generateFilepathArray(listfilepath) {
    var readStream = file→readStream(filepath→file(listfilepath));
    var filepathArray = new Array();
    try {
        while (!readStream.atEndOfStream)
            filepathArray.push(readStream.readLine());
    } finally {
        readStream.close();
    }
    return filepathArray;
}

function filepath→file(filepath) {
    return FileSystemObject.fileExists(filepath) ? FileSystemObject.getFile(filepath) : null;
}

function file→readStream(file) {
    var ForReading = 1;
    var TristateUseDefault = -2;
    return file.openAsTextStream(ForReading, TristateUseDefault);
}

function Array.prototype.select(discriminator) {
    var anArray = new Array();
    for (var i = 0; i < this.length; i++) {
        var each = this[i];
        if (discriminator(each))
            anArray.push(each);
    }
    return anArray;
}

function Array.prototype.do_(aFunction) {
    for (var i = 0; i < this.length; i++)
        aFunction(this[i]);
}

function Array.prototype.waitUntilRemoved() {
    var discriminator = function (each) { return FileSystemObject.fileExists(each) };
    var testArray = this;
    while (true) {
        var testArray = testArray.select(discriminator);
        if (testArray.length == 0)
            break;
        WScript.sleep(270); // See [2].
    }
}

// [1] ファイル削除が完了するまで待つ処理
//
// FileSystemObject>>deleteFile() メソッドは非同期に実行されることがわ
// かっている。つまりメソッドから返った時点ではファイルの削除が保証され
// ない。さらにこのスクリプトはそのまま終了してしまう。このような時に具
// 合の悪いタイミング・イシューが発生する。それはスクリプト終了時に、
// ActiveX オブジェクトの解放処理をスクリプトホスト (wscript.exe) がおこ
// なうのだが、その時にまだ FileSystemObject>>deleteFile() メソッドの処
// 理が完了していない場合のエラーである。
//
// 以上を踏まえ、非同期処理の待ち合わせ処理を呼び出し元でつくりこんでや
// る必要がある。具体的には FileSystemObject.fileExists() メソッドで存在
// 有無を検査する。FileSystemObject.fileExists() メソッドの内部実装は未
// 確認だが、FileSystemObject>>deleteFile() メソッドの実行が完了した後は
// false を返す、という前提をおいている。

// [2] 検査時間と同時間だけ待つ。その時間を決める。
//
// 基本性能 : Pentium 2 Processor (400 MHz), 256 MBytes
//
// 算術平均 : 0.27085 (milliseconds/fileExists() メソッド)
//
//   0.26919 (milliseconds/file)
//   0.27179 (milliseconds/file)
//   0.27039 (milliseconds/file)
//   0.26929 (milliseconds/file)
//   0.27359 (milliseconds/file)
//
// 100 個のファイル検査をするのであれば 27 (milliseconds)
// 1000 個のファイル検査をするのであれば 270 (milliseconds) 必要となる。
// そのため次のファイル検査を行うまで検査時間と同時間だけ待ちたいならば
// 100 個 → WScript.echo(27)
// 1000 個 → WScript.echo(270)
// を実行すればよい。
//
// プログラムは検査をする毎に残存しているファイルだけを残すようにしてい
// るけれどもここではワーストケースとして 1000 個を常に実行する前提でか
// んがえると、270 (milliseconds) 待てば検査時間と同時間だけ待つことがで
// きる。

HELP me さん (SONOMI_MURAKAMI@PROMISE.CO.JP) 2004年 02月 10日 18時 47分 31秒

最近、WSHというものを知り、勉強中です。
ファイル名(複数あり、1行毎に書かれている)を抽出したテキストファイルがあるのですが、それを読み込んで、削除していく方法を教えてください。

緑の風 さん 2004年 02月 10日 09時 29分 11秒

WSHからIEを起動して制御しています。
あるページからsubmitして別ウィンドウにページが表示されたとき、このページを制御する方法がわかりません。
(元のページはそのまま制御できます)

Set IE = WScript.CreateObject("InternetExplorer.Application")
IE.Visible = true
IE.Navigate("http://xxx/")
Do While IE.busy
Loop
Do While IE.Document.readyState <> "complete"
Loop
IE.Document.form1.input1.value = "abc"
IE.Document.form1.input2.value = "xyz"
IE.Document.form1.submit
ここで、別ウィンドウにページが表示される。そのページを制御したい。

さん 2004年 02月 08日 15時 44分 15秒

管理人様。

えーと、いきなり質問してしまって申し訳ないのですが、エクスプローラ等で表示される左側のwebページ、そこのフォントの色って変えれるのでしょうか?
イロイロ調べてまわったんですけど、なんかイマイチ具体的な方法が載ってなくて、こちらのサイトに迷い込んでしまいました。
そこで、失礼かとは思いましたが、こうして質問させてもらってる次第です。もしかして方法を知っておられるのでは?と思いまして…。
情けないことに私、スタイルシートとかちんぷんかんぷんなんで、もしよろしければご教授お願いいたします。

たいへい さん (tai_shido@r4.dion.ne.jp) 2004年 02月 07日 15時 45分 03秒

>InternetExplorerの「インターネット一時ファイルの削除」

for each a in folder.Files
a.Name = "d.txt"
delfile.DeleteFile "C:/...../Temporary Internet Files/d.txt"

ってな感じでフォルダにあるファイルを d.txt に変えてそれを削除する。
この繰り返しでファイルを消したいのですが、
Temporary Internet Files にアクセスできません。
これをやると違うフォルダのファイルを消してしまいます。
このフォルダを指定するにはどうすればよいのでしょうか?

祥子 さん 2004年 02月 06日 15時 27分 23秒

ひょん さんへ
>拙作ですが、キャッシュを削除できるコンポーネントがあります。
>一括削除はできないので、1つ1つ削除することになりますが、WSHから使えます

すばらしいコンポーネントを紹介してくださって、
ありがとうございました。

以上です。

ひょん さん 2004年 02月 05日 23時 37分 23秒

祥子 さんへ
>>InternetExplorerの「インターネット一時ファイルの削除」
>>と同じことを、CUIで実現したいです。

拙作ですが、キャッシュを削除できるコンポーネントがあります。
一括削除はできないので、1つ1つ削除することになりますが、WSHから使えます
http://hyons.hp.infoseek.co.jp/

Return