はた坊 さん 2003年 11月 06日 18時 04分 20秒

>魔界の仮面弁士 さま

おっしゃってる内容、理解できました。
ですが、私の知識不足のため
スクリプトでわからないところがあるのですが・・・・

>ToYYYYMMDD = Right(CStr(1E8 + lngYMD), 8)

「 1E8 +  」のところがよくわからないんです。

たとえば、2003/11/06の場合
lngYMDに入るのは20031106ですよね?
これに 1E8 を足し算してるのでしょうか??

よろしければご教示願えますでしょうか<(_ _)>

P.S.
質問者の方は解決されたようですね。
よかったです。

ちー さん 2003年 11月 06日 17時 04分 25秒

みなさんどうもありがとうございます。
おかげで無事解決できました。
今後も勉強を続けて答える立場になれるようになりたいと思います。

魔界の仮面弁士 さん 2003年 11月 06日 16時 53分 22秒

》 はた坊 さん 2003年 11月 06日 16時 26分 46秒

日付型の値を、Mid関数に直接かけるのは、あまりお勧めできません。

文字列型への内部変換される際の書式は、コントロールパネルの
設定に依存するため、単純に文字位置での切り分けを行うのは危険です。

面倒ですが、自前で書式化してください。

例えば、日付であればこんな感じにしてみるとか…。

===================
Option Explicit

MsgBox ToYYYYMMDD( Date() ), vbInformation

Function ToYYYYMMDD(dt)
Dim lngYMD
lngYMD = Year(dt) * 10000 + Month(dt) * 100 + Day(dt)
ToYYYYMMDD = Right(CStr(1E8 + lngYMD), 8)
End Function

いりや さん 2003年 11月 06日 16時 47分 33秒

kana さん,

| ファイルを開く以下のスクリプトを作ったのですが、今ファイル名
| が001.gifとなっていますが、ここをクリップボードを使って任意
| の名前にしたいのです。

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



50-22 土屋 さん 2001/10/28 17:40

さんの投稿に VBScript の例題が述べられています。引用させてい
ただくと・・・

Set IE = WScript.CreateObject("InternetExplorer.Application")
IE.Navigate "about:blank"
IE.Visible = True
While(IE.busy):Wscript.Sleep 100:Wend
IE.Document.parentWindow.clipboardData.setData "text","あいうえお"
MsgBox IE.Document.parentWindow.clipboardData.getData("text")
IE.Document.parentWindow.clipboardData.clearData "text"
IE.Quit

です。

IE.Document.parentWindow.clipboardData.getData("text")

でクリップボードの値を取得できますね。

また,ここ1ヶ月の間にタイムリーにクリップボードの話題がでま
したので,ポインタ情報をお知らせします。行頭の 92 とか 93 が
過去の記事リスト番号です。

93-34 いりや さん     2003/11/03 12:34
93-28 いりや さん     2003/10/31 13:06
93-18 いりや さん     2003/10/30 02:34
92-50 Gen さん       2003/10/25 23:46
92-46 いりや さん     2003/10/24 13:18
92-45 いりや さん     2003/10/24 11:28
92-44 魔界の仮面弁士 さん 2003/10/24 09:57
92-43 bon さん       2003/10/24 07:58

kana さん 2003年 11月 06日 16時 29分 02秒

ファイルを開く以下のスクリプトを作ったのですが、今ファイル名が001.gifとなっていますが、ここをクリップボードを使って任意の名前にしたいのです。
ヘルプを見ていろいろ調べたのですが、VBSでは、クリップボードの値を取得することは出来るのでしょうか?よろしくお願いします。

Set WshShell = WScript.CreateObject("WScript.Shell")
Return = WshShell.Run("001.gif " )

はた坊 さん 2003年 11月 06日 16時 26分 46秒

私も初心者の域を脱していないのですが
こんなかんじでしょうか↓

mmdd = Date
hhmm = Time
msgbox Mid(mmdd,6,2) & Mid(mmdd,9,2) & Mid(hhmm,1,2) & Mid(hhmm,4,2)

「msgbox」のところは「FileName = 」に置き換えて下さい。
もっとスマートな方法があれば私も教えていただきたいです。

魔界の仮面弁士 さん 2003年 11月 06日 16時 07分 40秒

> FileName = Format(Now, "mmddhhnn")
それは、VBAやVB6の場合ですよね?
(VBScriptには、Format関数はありません)

> 「型が一致しません'Format'」とエラーがでてしまいます。
上記の場合、『Formatという名前の変数』だと思われているのでしょう。

バグの混入を防ぐためにも、明示的に、
「Option Explicit」を宣言しておく事をお奨めします。

> 日付の形式を「mmddhhnn」にするにはどうしたらよいのでしょうか?
Hour関数などを組み合わせて、自分でそのような文字列を作り上げてください。
VB.NETやVB6などをお持ちであれば、Format機能を持つActiveX DLLを
作成し、それを呼び出すという手もありますね。

ちー さん 2003年 11月 06日 15時 36分 14秒

はじめまして
WSH初心者ですが勉強させて頂いております。

日付をファイル名にしようと思いFormat関数を用いて
FileName = Format(Now, "mmddhhnn")
としたのですが
「型が一致しません'Format'」とエラーがでてしまいます。
どうしても時間帯まで入れたファイル名が必要ですので
FileName = FormatDateTime(Now, vbLongTime)
では問題があるのです。

日付の形式を「mmddhhnn」にするにはどうしたらよいのでしょうか?

マサノ さん 2003年 11月 05日 08時 56分 56秒

いりやさん>ありがとうございます。
無事、確認できました。
参考にして、頑張ってみます。
ただ、何がなんだか解らないところがいっぱいですが、、、

オックン さん 2003年 11月 04日 15時 08分 13秒

現在のコードが間違っていましたので、
再度投稿させていただきました。

現在コード:
Set WSHNetwork = WScript.CreateObject("WScript.Network")
Const strShare="共有ポイント名"

WScript.Sleep(4000)
WSHNetwork.RemoveNetworkDrive strShare,True,False

オックン さん 2003年 11月 04日 15時 05分 56秒

いつも勉強・参考にさせていただいています。

早速ですが、質問させていただきます。

エクセルの終了時にネットワークドライブを切断するために、
WHSファイルを起動させて、4秒後にRemoveNetworkDriveを実行させています。

しかし、エラーなどが頻発しているので、、
「4秒後」ではなく、「エクセルの終了後」に
実行するというコードに変更したいのですが期待通りの動作になりません。

何卒、良いアイデアがありましたらお願いします。

現在のコード:

Set WSHNetwork = WScript.CreateObject("WScript.Network")
Const strShare="共有ポイント"
WSHNetwork.RemoveNetworkDrive strShare,True,False

いりや さん 2003年 11月 03日 22時 40分 23秒

文面では半角スペース二つのつもりでしたが表示上は一つとなるようです
ので,二つで置き換えてください。インデントが保持されます。(タブストップを半角スペース八つにしています)

いりや さん 2003年 11月 03日 22時 38分 29秒

マサノさん,

こんばんわ。

(1) <job id=screen> から </job> までをコピーする
(2) エディタにはりつける
(3) " " を " " に置き換える (ダブルクオーテーションはいりません)
  全部で 228 個の " " が置き換わります。
(4) screen.wsf ファイル名で保存する (.txt ではダメ)
(5) screen.wsf ファイルのアイコンが水色の巻物であることを確認する
(6) screen.wsf ファイルをダブルクリックします。


マサノさんは 1600x1200 の解像度に変更可能でしょうか?? もし
1024x768 ならば OK でしたら,

for (var i = 0; i < 7; i++)



for (var i = 0; i < 4; i++)

に置き換えて実行してみてください。WinXP + IE 6.0, 1024x768
(ThinkPad) の環境で確認しました。今度はうまくいくはず・・・。

いりや

マサノ さん 2003年 11月 03日 22時 21分 02秒

いりやさん、ありがとうございます。
初心者なので、回答で少しわかりませんので、教えてください。
>全角スペースを半角スペースに置き換えて実行してください。とありますが、
どこのとこなのですか?
又、回答をコピー&ペーストして実行すると、行4、文字2 文字が正しくありませんという、エラーとなってしまいます。
申し訳ありませんが、もう少し教えてください。
よろしくお願いします。

いりや さん 2003年 11月 03日 13時 42分 32秒

あっと訂正します。(^^;
解像度による微調整を行っていますね。解像度を 1280x1024 にして
実験したらいきなり 1 番を選んでもはみだしてしまった。。

いりや さん 2003年 11月 03日 13時 34分 58秒

マサノさん、

| msgboxを任意の場所に出すことはできませんか?
| 又、大きさを自由に変えることはできませんか?

できなさそうですね、ドキュメントを読む限り。

多分表示内容を利用者が設定可能になっているがゆえに、どういうサイズのダイ
アログを表示すればよいか、msgbox の開発者はあらかじめわからない。そのた
め、大きさと位置を動的におこなうアプローチをとられたのではないかと推測し
ます。(それで利用者にそのパラメータが開放されていない)

余談ですが、可変といいつつどのくらいまでダイアログが広がるか実験をしてみ
ました。縦には少なくともあんまり実感範囲においては制限なく広がりましたが
横はそうではありませんでした。(1600x1200 の解像度で検査しましたが解像度
による縛りは入れていないようですね)

以下は実験スクリプトです。screen.wsf というファイル名で保存し、全角スペー
スを半角スペースに置き換えて実行してください。ダイアログが表示されるまで
若干時間がかかる場合があります。気長にお待ちください。(P2 400MHz だと 3
秒弱ぐらいかかる)

[ WSH/WSF ファイル ]

<job id=screen>
<script language=VBScript>
Function VBInput(prompt, title, default)
    VBInput = InputBox(prompt, title, default)
End Function
</script>

<script language=JavaScript>

var n = ask('1: 画面に収まる場合、2: 収まらない場合 のどちらかを選んでください', 1);
if (n == null)
    WScript.quit();

var screenArray = new Array();
generateScreen(screenArray);
for (var i = 0; i < 7; i++)
    spread_horizontally(screenArray);
if (n == 2)
    spread_horizontally2(screenArray);

WScript.echo(screenArray.join('\n'));

function generateScreen(screenArray) {
    screenArray.push('■□□□□□□□□□');
    screenArray.push('■■□□□□□□□□');
    screenArray.push('■■■□□□□□□□');
    screenArray.push('■■■■□□□□□□');
    screenArray.push('■■■■■□□□□□');
    screenArray.push('■■■■■■□□□□');
    screenArray.push('■■■■■■■□□□');
    screenArray.push('■■■■■■■■□□');
    screenArray.push('■■■■■■■■■□');
    screenArray.push('■■■■■■■■■■');
}

function spread_horizontally(screenArray) {
    screenArray[0] = screenArray[0] + '■□□□□□□□□□';
    screenArray[1] = screenArray[1] + '■■□□□□□□□□';
    screenArray[2] = screenArray[2] + '■■■□□□□□□□';
    screenArray[3] = screenArray[3] + '■■■■□□□□□□';
    screenArray[4] = screenArray[4] + '■■■■■□□□□□';
    screenArray[5] = screenArray[5] + '■■■■■■□□□□';
    screenArray[6] = screenArray[6] + '■■■■■■■□□□';
    screenArray[7] = screenArray[7] + '■■■■■■■■□□';
    screenArray[8] = screenArray[8] + '■■■■■■■■■□';
    screenArray[9] = screenArray[9] + '■■■■■■■■■■';
}

function spread_horizontally2(screenArray) {
    screenArray[0] = screenArray[0] + '■';
    screenArray[1] = screenArray[1] + '■';
    screenArray[2] = screenArray[2] + '■';
    screenArray[3] = screenArray[3] + '■';
    screenArray[4] = screenArray[4] + '■';
    screenArray[5] = screenArray[5] + '■';
    screenArray[6] = screenArray[6] + '■';
    screenArray[7] = screenArray[7] + '■';
    screenArray[8] = screenArray[8] + '■';
    screenArray[9] = screenArray[9] + '■';
}

function ask(promptString, initialValue) {
    var breakPredicate = function (s) {
        return parseFloat(s) == parseInt(s)
            && parseInt(s) > 0
            && parseInt(s) < 3
    }
    var convertFunc = function (s) { return parseInt(s) }
    var caption = 'WSH/JScriptプロンプト';
    return prompt_primitive(promptString, caption, initialValue, breakPredicate, convertFunc);
}

function prompt_primitive(promptString, caption, initialValue, breakPredicate, convertFunc) {
    do {
        var s = VBInput(promptString, caption, initialValue);
        if (s == null)
            break;
    } while (!breakPredicate(s));
    return s != null ? convertFunc(s) : null;
}

</script>
</job>

いりや さん 2003年 11月 03日 12時 34分 34秒

つちやさん、

ポインタ情報ありがとうございます。ちょうど二年前に同じ議論がなされ
ていますね。クリップボードの話も発見したときはひっくりかえりました。
ありゃー、という感じです。

つちや さん 2003年 11月 03日 02時 46分 54秒

VBScriptでのファイル選択ダイアログの件ですが、
2001年 10月 30日 00時 29分 52秒のむたぐちさんの発言(50-35)が、参考になるのでは。
デスクトップのファイルもOKですよ。
以下、引用。

Set Ie = WScript.CreateObject("InternetExplorer.Application","IE_")

Ie.Navigate "about:blank"
Do While Ie.ReadyState<>4

WScript.Sleep 100

Loop

Set document=Ie.Document

document.Write "<html><body><input type=file id=txtFile></body></html>"

document.all.txtFile.focus
document.all.txtFile.click

MsgBox document.all.txtFile.Value

匿名希望 さん 2003年 11月 03日 00時 56分 09秒

>>いりやさん
>>匿名56さん
アドバイスありがとうございます。

マサノ さん 2003年 11月 02日 08時 35分 37秒

いつもお世話になります。
msgboxを任意の場所に出すことはできませんか?
又、大きさを自由に変えることはできませんか?
HELPにはないようなので。
宜しくお願いします。

いりや さん 2003年 10月 31日 19時 09分 10秒

| 操作方法は、特に問題なさそうです。

そうでしたか。

| ちなみに、私の使ってる環境は「Win2K + IE5.0」なのですが、その辺に問
| 題があるのでしょうか?(IE6じゃないとだめでしょうか???)

IE 6.0 には WSH の最新のものがバンドルされている,ときいています。

昨今 WSH の脆弱性も Microsoft 社から報告されていますし,IE も 6.0 に
なって 5.0 台にくらべてずいぶんましになったと感じています。そういう意
味では IE 6.0 をインストールして刷新するのはメリットがあると思ってい
ます。(脆弱性はあいかわらずですが...)

| あと、教えていただいたコーディング内容と同じことをVBScriptで行うこと
| は可能でしょうか?

はい。のはずです。

それでポーティングの結果をおだしできればよいのでしょうが,生兵法は怪
我の基,実行時エラーが頻発してまったく身動きがとれない状況です。面目
ありません。

世界の果て さん 2003年 10月 31日 13時 54分 00秒

⇒いりやさん

操作方法は、特に問題なさそうです。
ちなみに、私の使ってる環境は「Win2K + IE5.0」なのですが、その辺に問題があるのでしょうか?(IE6じゃないとだめでしょうか???)
あと、教えていただいたコーディング内容と同じことをVBScriptで行うことは可能でしょうか?

いりや さん 2003年 10月 31日 13時 06分 10秒

世界の果てさん,

こんにちは。

> ただ、そのままカット&ペーストしただけではうまく動作しなかったのです
> が、何か注意することとかあるのでしょうか?

こちら (Win2K, WinXP & IE 6.0) でも試してみましたが特に問題はなかった
ようです。私の操作履歴をかいてみますので,そちらと一緒かどうかご確認
いただけますか??

(1) var filepath ... から } までをクリップボードにコピーする
(2) テキストエディタを開く
(3) クリップボードの内容をペーストする
(4) 保存する。(デスクトップに test.js というファイル名で)
(5) デスクトップ画面をみると test.js という黄色の巻物 (台本?) が描か
  れたアイコンが確認できる。
(6) そのアイコンをダブルクリックする。(⇔ここで実行される)
(7) ダイアログが表示され,何かファイルを選択する。
(8) 選択されたファイルパスはほにゃららら,とダイアログが表示される。

スクリプトのインデントに全角スペースを使用していて,最初これを半角ス
ペースに置き換えなければならないのかと思っていましたが,そのままでも
動くようです。(多分 wscript.exe の実装仕様) そのため (3) の過程でとく
に半角スペース 2 つに置き換える手続きをここでは入れていません。

世界の果て さん 2003年 10月 31日 11時 24分 14秒

>いりやさん

ありがとうございました。
ただ、そのままカット&ペーストしただけではうまく動作しなかったのですが、何か注意することとかあるのでしょうか?
最近、VBScriptの勉強をはじめたばかりで、ポケットリファレンスを片手に過去のVB経験だけで作成しているような感じなので、JSCriptのことはよくわからないのです。

匿名56 さん 2003年 10月 31日 02時 08分 00秒

修正
読み終わったかの判定を入れてませんでした。

if (FAILED(stream->ReadLine(&str))) {
 break;
}

匿名56 さん 2003年 10月 31日 02時 04分 03秒

>>たとえば、以下のようなコードをC/C++に移植したいのです。

CでやるならCOM無しでやった方が簡単なのでは・・・と思います。
fsoでテキストファイルを読む例を上げておきます。(エラー処理なし)

#import "scrrun.dll"

void ReadText(LPCSTR fname)
{
 ::CoInitialize(NULL);
 {
  CComPtr<IFileSystem3> fso;

  fso.CoCreateInstance(__uuidof(FileSystemObject));
  
  CComPtr<ITextStream> stream;
  CComBSTR str;
  USES_CONVERSION;

  fso->OpenTextFile(W2A(fname), ForReading, 0, TristateFalse, &stream);

  for (;;) {
    str.Empty();
    stream->ReadLine(&str);
    printf("%s\n", W2A(str));
  }
 }
 ::CoUninitialize();
}

いりや さん 2003年 10月 30日 13時 57分 41秒

| たとえば、以下のようなコードをC/C++に移植したいのです。
| マイドキュメントの中にあるファイルを、全てCドライブのBackupというフォルダの中にコピーするスクリプトです。

実はここでリファレンスを得ているオブジェクトは COM Object で
す・・・といっても何かよくわからないですよね。よいポーティン
グの例題はないのかしらん。。

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/objectmap.asp

ここは C/C++ との連携に関する情報がとぼしいですしねぇ。うむ
む。有識者の方いらっしゃいましたらポインタ情報を提供いただけ
ると助かります。

いりや さん 2003年 10月 30日 13時 54分 46秒

> var doc = e.document;

これはいらなかった。ゴミです。。

いりや さん 2003年 10月 30日 13時 52分 39秒

世界の果てさん,

IE のコントロールを間借りする別解を一つご紹介します。

[ 実行の仕方 ]

.js ファイルとして保存してダブルクリックすると起動します。ダ
イアログは最前面にこない場合は Alt + tab などで最前面にもっ
てきてファイルを選択する必要があります。

[ WSH/JScript ソース ]

var filepath = openFileDialog();
if (filepath == null) {
    WScript.echo('キャンセルされましたね!');
    WScript.quit();
} else
    WScript.echo('選択されたファイルパスは [' + filepath + '] です');

function openFileDialog() {
    var e = new ActiveXObject('InternetExplorer.Application');
    e.navigate('about:blank');
    while (e.busy || e.readyState != 4)
        WScript.sleep(0.1 * 1000);
    var doc = e.document;
    e.document.write('<input id=file type=file>');
    e.document.all.file.focus();
    e.document.all.file.click();
    var returnValue = e.document.all.file.value;
    return returnValue == '' ? null : returnValue;
}

//
//
//

世界の果て さん 2003年 10月 30日 13時 39分 10秒

「VBScriptでファイル選択のダイアログを出す方法」を探していたら、ここにたどり着きました。
過去の記事を参考に、shellオブジェクトの"BrowseForFolder"を使ってファイル選択できるようになったのですが、デスクトップのファイルを選択するとエラーになってしまいます。
ただし、"ローカルディスク(C:)" ⇒ "Documents and Settings" ⇒ "Guest" ・・・という感じでデスクトップのファイルを選択するとうまくいきます。
何か解決策はないでしょうか?
(つたない説明で申し訳ありません。理解していただけるかどうか不明???)

匿名希望 さん 2003年 10月 30日 03時 11分 54秒

>>いりやさん
レスありがとうございました。
COMの意味もよく把握できていないのですが、COMを利用するものではないと思います。

たとえば、以下のようなコードをC/C++に移植したいのです。
マイドキュメントの中にあるファイルを、全てCドライブのBackupというフォルダの中にコピーするスクリプトです。

Set WSell = CreateObject("WScript.Shell")
MyDoc = WSell.SpecialFolders("MyDocuments")
Set FS = CreateObject("Scripting.FileSystemObject")
Set F = FS.GetFolder(MyDoc)
For Each Obj In F.Files
Obj.Copy "c:\Backup\"
Next

いりや さん 2003年 10月 30日 02時 48分 41秒

むたぐちさん、

読ませていただきました。おまけの方を WSH/JScript にポーティング
できるかなーと思いましたがちょっと重そうですね。週末にでも取り
組んでみます・・・。

いりや さん 2003年 10月 30日 02時 34分 24秒

先日クリップボードを WSH で使うアイディアが紹介されたので、この応用例
としてクリップボードを介して行ベースのテキスト処理 (フィルタ処理) を
行う仕掛けをつくってみました。WSH/JScript です。


[ 実行の仕方 ]

クリップボードに処理したいテキストデータをコピーしておいてからスクリ
プトを起動します。example1(), example2() ともフィルタ処理の結果をまた
クリップボードに返します。


[ コーディングのポイント ]

ReadStream, WriteStream コンストラクタは、WSH ではポピュラーな
ITextStream インターフェイスのサブセットを Clipboard 上に実装していま
す。なぜこのようなつくりにしたかと言いますと、ここの切り口にその他の
ストリームオブジェクトを与えても動作するようにしたかったからです。

というのは嘘で、もともと File オブジェクトからストリームを生成して与
える切り口に、クリップボード上に作ったストリームをつなげたかったから、
というのが正味なところです。(以前投函した Awk ライクなパターン処理言
語の入り口にも似たところがあったことをおぼえておいででしょうか)

それからフィルタ処理は関数オブジェクトとして与えます。例題では
filterFunc() 関数という名前の関数オブジェクトを与えています。ここの骨
組みの説明は省略します。


[ example1 の実行例 (スクリプトそのものをコピーして実行) ]

D:\Documents and Settings\iriyak\デスクトップ>cscript //nologo preprocess.js
function example1() {
function example2() {
function process(inputStream, outputStream, filterFunc) {
function Clipboard() {
function ReadStream(aClipboard) {
function WriteStream(aClipboard) {
function createTemporaryFile() {
function file→readStream(file) {
function file→writeStream(file) {


D:\Documents and Settings\iriyak\デスクトップ>


[ WSH/JScript ソース ]

example1();
//example2();

// example1: function もしくは Function で始まる行を抜き出す。

function example1() {
    var filterFunc = function (inputStream, outputStream) {
        while (! inputStream.atEndOfStream) {
            var s = inputStream.readLine();
            if (/^[fF]unction/.test(s))
                outputStream.writeLine(s);
        }
    }
    var aClipboard = new Clipboard();
    var inputStream = new ReadStream(aClipboard);
    var outputStream = new WriteStream(aClipboard);
    process(inputStream, outputStream, filterFunc);
    WScript.echo(aClipboard.getText());
}

// example2: /x+/ もしくは /z+/ に適合する行を抜き出す。

function example2() {
    var filterFunc = function (inputStream, outputStream) {
        while (! inputStream.atEndOfStream) {
            var s = inputStream.readLine();
            if (/x+|z+/.test(s))
                outputStream.writeLine(s);
        }
    }
    var aClipboard = new Clipboard();
    var inputStream = new ReadStream(aClipboard);
    var outputStream = new WriteStream(aClipboard);
    process(inputStream, outputStream, filterFunc);
    WScript.echo(aClipboard.getText());
}

function process(inputStream, outputStream, filterFunc) {
    try {
        filterFunc(inputStream, outputStream);
    } finally {
        inputStream.close();
        outputStream.close();
    }
}

function Clipboard() {
    var ie = new ActiveXObject('InternetExplorer.Application');
    ie.navigate('about:blank');
    while (ie.busy || ie.readyState != 4)
        WScript.sleep(0.1 * 1000);
    this.source = ie.document.parentWindow.clipboardData;
    this.clear = function () { this.source.clearData() }
    this.getText = function () { return this.source.getData('TEXT') }
    this.setText = function (s) { return this.source.setData('TEXT', s) }
}

function ReadStream(aClipboard) {
    this.close = function () {
        this.source.close();
        new ActiveXObject('Scripting.FileSystemObject').deleteFile(aFile.path, true);
    }
    this.read = function () {
        var s = this.source.read();
        this.refresh();
        return s;
    }
    this.readAll = function () {
        var s = this.source.readAll();
        this.refresh();
        return s;
    }
    this.readLine = function () {
        var s = this.source.readLine();
        this.refresh();
        return s;
    }
    this.skip = function (n) {
        this.source.skip(n);
        this.refresh();
    }
    this.skipLine = function () {
        this.source.skipLine();
        this.refresh();
    }
    this.refresh = function () {
        // Note that both atEndOfLine and atEndOfStream properties apply only to
        // TextStream files which are OPEN for READing.
        this.atEndOfLine = this.source.atEndOfLine;
        this.atEndOfStream = this.source.atEndOfStream;
        this.column = this.source.column;
        this.line = this.source.line;
    }
    var aFile = createTemporaryFile();
    var writeStream = file→writeStream(aFile);
    writeStream.write(aClipboard.getText());
    writeStream.close();
    var readStream = file→readStream(aFile);
    this.source = readStream;
    this.refresh();
}

function WriteStream(aClipboard) {
    this.close = function () {
        this.source.close();
        var readStream = file→readStream(aFile);
        aClipboard.setText(readStream.readAll());
        readStream.close();
        new ActiveXObject('Scripting.FileSystemObject').deleteFile(aFile.path, true);
    }
    this.write = function (s) {
        var s = this.source.write(s);
        this.refresh();
    }
    this.writeBlankLines = function (n) {
        this.source.writeBlankLines(n);
        this.refresh();
    }
    this.writeLine = function (s) {
        this.source.writeLine(s);
        this.refresh();
    }
    this.refresh = function () {
        // Note that both atEndOfLine and atEndOfStream properties apply only to
        // TextStream files which are OPEN for READing.
        this.column = this.source.column;
        this.line = this.source.line;
    }
    var aFile = createTemporaryFile();
    var writeStream = file→writeStream(aFile);
    this.source = writeStream;
    this.refresh();
}

function createTemporaryFile() {
    var aFileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
    var temporaryFolder = aFileSystemObject.getSpecialFolder(2);
    var filename = aFileSystemObject.getTempName();
    temporaryFolder.createTextFile(filename, true);
    return aFileSystemObject.getFile(temporaryFolder.path + '\\' + filename);
}

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

function file→writeStream(file) {
    var ForWriting = 2;
    var TristateUseDefault = -2;
    return file.openAsTextStream(ForWriting, TristateUseDefault);
}

//
//
//

管理人むたぐち さん 2003年 10月 29日 19時 49分 26秒

ではVBSへポーティング。

Dim onQuit
onQuit = False

Set IE = WScript.CreateObject("InternetExplorer.Application", "IE_")
IE.Visible=True
IE.Navigate "http://www.yahoo.co.jp"

Do
If onQuit Then
WScript.sleep(5 * 1000)
MsgBox "done"
WScript.Quit
End If
WScript.Sleep 100
Loop

Sub IE_OnQuit()
onQuit = True
End Sub


ついでにおまけですが、「他のページを見ようとすると、強制的に終了するスクリプト」です。

Dim onQuit
onQuit = False
sURL = "http://www.yahoo.co.jp/"

Set IE = WScript.CreateObject("InternetExplorer.Application", "IE_")
IE.Visible=True
IE.Navigate sURL

Do
If onQuit Then
WScript.Quit
End If
WScript.Sleep 100
Loop

Sub IE_OnQuit()
onQuit = True
End Sub

Sub IE_DocumentComplete(pDisp, URL)
Set document=IE.Document
Set window=document.ParentWindow
Set body=document.body
If URL = sURL Then
Set body.onunload=GetRef("window_onbeforeunload")
End If
End Sub

Function window_onbeforeunload()
IE.Quit
End Function

いりや さん 2003年 10月 29日 18時 47分 11秒

むたぐちさん,mikey さん,

VBScript へのポーティングありがとうございました。

| いりやさんの方法のように、ブラウザ指定して実行するのだと、IEだと問題ないんですが、
| タブブラウザやネットスケープなどをexecで実行した場合、
| 既存の常駐プロセスに処理を渡して、自らはすぐに終了してしまうので、
| やはりウィンドウが閉じられるのを待つことができないという厄介な問題もあります。

IE でも同様の話があるようです。

デスクトップの IE アイコンをダブルクリックしたり,.htm, .html ファイ
ルの関連付けをみると (プロセスがすでに起動しているのであれば) 常駐プ
ロセスに DDE プロトコルを使用して処理を依頼しています。

そのため前述のように強引にプロセスをあたらに起こすよう指示をしていな
ければ,(プロセスが増えるわけではないので) そのプロセスの生き死にを観
測できず,よって wshScriptExec オブジェクトの status メンバ変数をつかっ
た方式は IE でもうまくいきません。

ということで IE でもよいと条件を緩めてもらう前提で,IE の OnQuit イベ
ントを捕捉する方式を採用してみたスクリプトをご紹介します。

こちらですと,複数のウインドウを開いていても最後の一枚を閉じる瞬間に
OnQuit イベントがホスト (wscript.exe) に届けられます。WSH のイベント
処理の機構をつかってそれを捕捉して終了タイミング (の近辺) を知る,と
いうものです。

この方式もプロセスが消滅する瞬間まで処理がブロックされる訳ではなく途
中のタイミングをホスト (wscript.exe) が知ることになります。そこから消
滅するまでの数秒間はホストの決めうちで終わったと見なします。だからハ
ズれる可能性はゼロではなく完全ではありません。


[ WSH/JScript ソース ]

// InternetExplorer Application の onQuit イベントハンドラを利用して,
// 終了タイミングを捕捉する例。(精度は終了の近辺のレベルにとどまる)
// WSH のイベント処理の機構を利用してプログラミングしています。

var onQuit = false;
main();

function main() {
    var e = new InternetExplorer();
    e.visible(true);
    e.navigate('http://www.yahoo.co.jp');
    eventLoop();
}

function eventLoop () {
    while (true) {
        WScript.sleep(0.1 * 1000);
        if (onQuit) {
            // onQuit イベントが発生した後の前後最中のいずれかのポ
            // イントでこのブロックが実行される。そのため,事前条
            // 件として「後始末が終わっている (ウインドウが閉じてい
            // るなど)」ことは約束されない。よって,こちら側でその
            // 後始末分の時間を予測して,このくらい待てば,次に進ん
            // で大丈夫だろうと割り切る方式を考える。
            // ここでは 5 秒間で後始末が終わると見なして次のステップ
            // へ進む。
            WScript.sleep(5 * 1000);
            WScript.quit();
        }
    }
}

function InternetExplorer_OnQuit() {
    // IE が onQuit イベントを通知すると,受け取った wscript.exe は,
    // この関数を呼び出す。イベントの発信者 (IE) はこの関数の実行が
    // 終わるまで実行がブロックされる (⇔待たされる)。
    onQuit = true;
}

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.wait();
        }
        if (arguments.length == 1 && typeof(arguments[0]) == 'string') {
            this.source.navigate(arguments[0]);
            this.wait();
        }
    }
    this.wait = function () {
        while (this.source.busy || this.source.readyState != 4)
            WScript.sleep(0.1 * 1000);
    }
}

//
//
//

管理人むたぐち さん 2003年 10月 29日 13時 34分 32秒

To: mikey さん & いりや さん

rundll32.exeを使う方法の場合、引数のURLをデフォルトブラウザに与えて起動させる
動作が終了した時点でプロセスが終了してしまうので、うまくいかなかったわけですね。
「デフォルトブラウザで実行」ばかりに目が行って、肝心の所をミスってました。すいません。

いりやさんの方法のように、ブラウザ指定して実行するのだと、IEだと問題ないんですが、
タブブラウザやネットスケープなどをexecで実行した場合、
既存の常駐プロセスに処理を渡して、自らはすぐに終了してしまうので、
やはりウィンドウが閉じられるのを待つことができないという厄介な問題もあります。

まあそれはおいといて、とりあえずいりやさんのスクリプトをVBS風に書くとこんなんです。

Set WshShell = WScript.CreateObject("WScript.Shell")

sURL = "http://www.yahoo.co.jp/"
sApp = "C:\Program Files\Internet Explorer\iexplore.exe"

Set oExec = WshShell.Exec(sApp & " " & sURL)

Do While oExec.Status = 0
WScript.Sleep 100
Loop

MsgBox "done"


ついでにおまけですが、httpの関連付け(すなわち標準ブラウザ)を読み取って、
それを実行するスクリプトを書いてみました。
ブラウザによって、コマンドラインの書式が違うので、このままだとせいぜいIEくらいしか
起動してくれませんが。

Set WshShell = WScript.CreateObject("WScript.Shell")

sURL = "http://www.yahoo.co.jp/"

On Error Resume Next
sAct = WshShell.RegRead("HKEY_CLASSES_ROOT\HTTP\shell\")
On Error Goto 0

If sAct = "" Then
sApp = WshShell.RegRead("HKEY_CLASSES_ROOT\HTTP\shell\open\command\")
Else
sApp = WshShell.RegRead("HKEY_CLASSES_ROOT\HTTP\shell\" & sAct & "\command\")
End If

Set oExec = WshShell.Exec(sApp & " " & sURL)

Do While oExec.Status = 0
WScript.Sleep 100
Loop

msgbox "終了"

いりや さん 2003年 10月 29日 12時 17分 12秒

mikey さん,むたぐちさん,

こんなスクリプトではいかがでしょうか。デフォルト・ブラウザという制約を
緩めて Internet Explorer を利用した実現例です。

[ スクリプトの内容 ]

  WScript.Shell>>exec() メソッドを使って起動したプロセスの終了を待
  ちます。そのプロセスで起動された IEXPLORER.EXE で複数のウインドウ
  を開くとプロセスが終了しません。タスクマネージャでプロセスの生死
  を監視するとよいでしょう。

[ 実行の準備 ]

  下記の全角スペースを半角スペースに置き換えて .js ファイルとして保
  存します。

[ 実行の仕方 ]

  ダブルクリックして実行します。

[ WSH/JScript ソース ]

// 例 (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

example('http://www.yahoo.co.jp/');

function example(url) {
    var argumentsArray = generateArgumentsArray(url);
    var wshScriptExec = invokeExecMethodWith(buildCommadLineWith(argumentsArray));
    WScript.quit(waitUntilFinished(wshScriptExec));
}

function generateArgumentsArray(url) {
    var executableFilePath = 'C:\\Program Files\\Internet Explorer\\IEXPLORE.EXE';
    var argumentsArray = new Array();
    argumentsArray.push(doubleQuote(executableFilePath));
    argumentsArray.push(url);
    return argumentsArray;
}

function doubleQuote(s) {
    var q = String.fromCharCode(34);
    return new Array(q, s, q).join('');
}

function buildCommadLineWith(argumentsArray) {
    return argumentsArray.join(' ');
}

function invokeExecMethodWith(aCommandLine) {
    return new ActiveXObject('WScript.Shell').exec(aCommandLine);
}

function waitUntilFinished(wshScriptExec) {
    while (wshScriptExec.status == 0)
         WScript.sleep(0.1 * 1000);
    return wshScriptExec.status;
}

//
//
//

いりや さん 2003年 10月 29日 10時 19分 01秒

Gen さん,

がんばってください。UWSCについても掲示板が用意されていますので
そちらにスクリプトを掲載して支援を仰ぐのも一手段です。

http://hidebbs.net/bbs/umiumi?sw=7

Gen さん 2003年 10月 29日 01時 59分 47秒

いりやさん、

 素早いレス、ありがとうございました。

 早速UWSCをダウンロードしてみたのですが、
スクリプトの書き方がよくわかりません…

 じっくりとヘルプを読んで研究してみます。

いりや さん 2003年 10月 29日 01時 10分 49秒

> WSHのGetFileやGetFolderに相当する命令は、C/C++にありますでしょうか。

Component Object Model を利用したプログラミングを C/C++ でどうすれ
ばいいか? というご質問ならば babaq さんの解説は参考になるのではない
でしょうか。

http://www.hi-ho.ne.jp/babaq/
から Developer Site の COM プログラミングです。

もう一つ、ちょくとさんの

http://yokohama.cool.ne.jp/chokuto/urawaza/com/index.html

こちら、HSP (Hot Soup Processor) で COM を使う方法が解説されていま
すが COM 一般についてもふれれており、参考になります。

匿名希望 さん 2003年 10月 28日 20時 37分 04秒

板違いかもしませんが、教えていただきたいことがあります。
WSHのGetFileやGetFolderに相当する命令は、C/C++にありますでしょうか。

いりや さん 2003年 10月 28日 19時 09分 46秒

以下の二つのケースを試した見ました。NG Case はさとふさんと同じメッセージが
表示されました。(wscript.exe, cscript.exe ともに)

差異は適切でない名前を CreateObject() の第一引数に与えている,という点です。
さとふさんの環境では第一引数の値はどのようになっているかもう一度ご確認いた
だけませんか??

''
'' OK Case
''

Set xl = CreateObject("EXCEL.Application")
xl.visible = true
xl.workbooks.add

''
'' NG Case
''

Set xl = CreateObject("1EXCEL.Application")
xl.visible = true
xl.workbooks.add

さとふ さん 2003年 10月 28日 18時 23分 42秒

はじめまして、少し知恵を貸してください。
コマンドラインから cscriptでXXXXXX.vbsを実行しています。

Set xl = CreateObject("EXCEL.Application")
を行うとMicrosoft VBScript 実行時エラー: ActiveX コンポーネントはオブジェクトを作成できません。
: 'EXCEL.Application'
とのエラーが出てしまいます。

通常のVBやASPからはこのようなエラーはでません。
原因として考えられることがありましたら教えて下さい。

Microsoft (R) Windows Script Host Version 5.6

mikey さん 2003年 10月 27日 19時 21分 38秒

管理人むたぐちさん、有難うございます。
デフォルトブラウザが起動できました。
しかしながら、やはりブラウザを閉じる前にログオフしてしまいます。
ブラウザを起動するところを
Set oExec = WshShell.Exec("calc.exe")
とすると、電卓を終了してからログオフしてくれます。
もうちょっと調べてみる必要がありそうです。

管理人むたぐち さん 2003年 10月 27日 17時 44分 38秒

To: shobohn さん

> 作業は大変だとは思いますががんばってください。

お久しぶりです。

掲示板のログの引越しは相当な大事業になりそうです。
パンクするまでに何とか移行したいところです。
既存の資源(ログ、AKiOSさんの検索スクリプト)をそのまま引き継ぎつつ、
パワーアップした掲示板にしていきたいです。


To: mikey さん
> Set oExec = WshShell.Run("http://www.yahoo.co.jp/")

RunメソッドではなくExecメソッドを使います。
(Runメソッドはオブジェクトを返しません)

Set oExec = WshShell.Exec("rundll32.exe url.dll,FileProtocolHandler http://www.yahoo.co.jp/")

のようにすれば、デフォルトブラウザが起動します。

mikey さん 2003年 10月 27日 16時 43分 28秒

ブラウザはデフォルトブラウザを起動したいです。

また、VBScriptでも

Dim WshShell, oExec
Set WshShell = WScript.CreateObject("WScript.Shell")
Set oExec = WshShell.Run("http://www.yahoo.co.jp/")
WScript.Sleep 5000
Do While oExec.Status = 0
WScript.Sleep 100
Loop
Set WshShell = Nothing
WScript.Quit

とやると、「オブジェクトがありません'Run(...)'」というエラーダイアログが出ます。
JScriptかVBScriptかはどちらでもよいです。

mikey さん 2003年 10月 27日 15時 51分 19秒

はじめまして。mikeyといいます。

以下のtest.jsを作ってログオフスクリプトに登録したのですが
ブラウザを閉じる前に(5秒したら)ログオフしてしまいます。
ブラウザを閉じてからログオフしたいのですが、
どなたか方法が分かるかたいらっしゃいますでしょうか?

var WShell = WScript.CreateObject("WScript.Shell");
var oExec = WShell.Run("http://www.yahoo.co.jp/");
WScript.Sleep(5000);
while (oExec.Status == 0) {
WScript.Sleep(100);
}
WScript.Quit();

Windows XP
WSH 5.6です。

いりや さん 2003年 10月 27日 14時 10分 50秒

Gen さん,

| 3 ウインドウAから目的のファイルをウインドウBへドラッグ&ドロップする。
|
| 4 パスワードを設定する画面が表示されるので、パスワードを入力すると、MO
|  ドライブへ目的のファイルがコピーされる。

WSH でなければという制約をゆるくしてもよいのであれば,過去一
度投函しましたが,

  86-43 いりや さん 2003/07/03 12:28
  http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list86.shtml

自動化ソフトの併用をおすすめします。

私は WSH と相互補完目的で UWSC (http://www002.upp.so-net.ne.jp/umiumi/)
という自動化ソフトを愛用しています。

ご参考まで。

shobohn さん (shobohn@toys.co.jp) 2003年 10月 26日 01時 43分 57秒

むたぐちさん、おひさしぶりです。shobohnです。

> 今のところコンテンツの分散等は考え中ですが、とりあえずは2chのログ、
> アップローダ、掲示板のログ検索スクリプトなどを設置していこうかと
> 思っています。

作業は大変だとは思いますががんばってください。

# 駄レス失礼。

管理人むたぐち さん 2003年 10月 26日 01時 15分 02秒
URL:http://winscript.s41.xrea.com/

以前もお伝えしましたが、Hi-HOの無料レンタルWeb領域が
そろそろ満杯になりそうなので、XREAの無料スペースを借りました。

今のところコンテンツの分散等は考え中ですが、とりあえずは2chのログ、
アップローダ、掲示板のログ検索スクリプトなどを設置していこうかと
思っています。

http://winscript.s41.xrea.com/

Return