たけゆき さん 2004年 08月 20日 01時 35分 37秒

サービスを停止・開始するVBスクリプトを作成中です。
あるサービス「Service Of A」を停止させる処理として、
Sendkeysを使って実現しようとしているのですが、
サービス名に半角スペースがあり、ダブルコーテーションの
記述法がわからないため、"Service Of A"と認識させることができません。
いろいろ調べましていくつかトライしましたがNGでした。
どなたかおわかりになる方がいらっしゃればご教授お願いします。
【NG例】
・WshShell.SendKeys "NET STOP Service Of A"
・WshShell.SendKeys "NET STOP "Service Of A""
・WshShell.SendKeys "NET STOP '"'Service Of A'"' "

ばんのしゃーによかばんた さん 2004年 08月 19日 23時 24分 00秒

>ちゃきちゃっき〜 さん 2004年 07月 28日 10時 16分 57秒
>VBSでIEを起動,URL表示,アクティブウィンドウキャプチャ後、
>次のURLへという巡回+キャプチャスクリプトを作成していますが、
>その際にポップアップウィンドウが邪魔になります。
>そこで考えたのが以下の方法です。

詳しくないので、コメントを控えていたのですが、
そもそも、ポップアップウィンドウというのは、どうやって出すんでしょう?
インターネットゾーンのセキュリティレベルを高にしていても、出るものでしょうか?

もし、それで出ないものなら、出たものを消すより、出ないようにしたほうが、
安全で確実だと思うのですが。違っていたらゴミです。

ばんのしゃーによかばんた さん 2004年 08月 19日 23時 23分 12秒

>ゆう さん 2004年 08月 19日 14時 28分 06秒
>このプログラムを起動するだけで特定フォルダ内(たとえば"c:\test")の全フォルダや
>ファイルの読取専用属性を解除するプログラム(すでにプログラムの中に"c:\test"が
>指定してある)がほしいのですがどのようにしたらよろしいのでしょう?

こういうのはどうでしょう。

デスクトップで右クリック/新規作成/ショートカット
コマンドラインに
cmd.exe /c attrib -h -s -r c:\test\*.* /s /d

Win98では、フォルダはワイルドカードの対象外となります。
command.com /c attrib -h -s -r c:\test\*.* /s

とても簡単で、かつ、性能もよさそうです。

ばんのしゃーによかばんた さん 2004年 08月 19日 23時 22分 11秒

>管理人むたぐち さん 2004年 05月 18日 08時 09分 12秒
>の記事を参考に、「他のフォルダを閉じる」スクリプトを作ってみました。
>WinXP用です。2000でも動くかも。

チラっと動くのは愛嬌ですが、なんか他に方法はないものかと、
↑を参考に、「他のフォルダを閉じる」スクリプトを作ってみました。
なんか、苦し紛れ、彌縫策のような気もします。

すべてファイル(*)とフォルダに関連付けて、コンテクストメニューから実行します。
[HKEY_CLASSES_ROOT\*\shell\Close&Win\command]
@="WScript.EXE D:\\VBS\\Shell\\CloseWin.VBS \"%1\""

精度やタイミングエラーなど、改良の余地があるかも知れません。

Set Shell=CreateObject("Shell.Application")

If WScript.Arguments.Count=0 Then
WScript.Quit
End If

Dim arr(),ind

For Each ie In Shell.Windows
If ie.Busy Or ie.ReadyState<>4 Then WScript.Quit
If InStr(typename(ie.Document),"IShellFolderViewDual") Then
If UCase(ie.Document.FocusedItem.Path)=Ucase(WScript.Arguments(0)) Then
Else
ind=ind+1
ReDim Preserve arr(ind-1)
Set arr(ind-1)=ie
End If
End If
Next

If Shell.Windows.Count=ind+1 Then
For Each ie In arr
ie.Quit
Next
End If

ゆう さん 2004年 08月 19日 14時 28分 06秒

実用スクリプト内にある読取専用属性解除プログラムのro.lzhを活用したいのですが、このプログラムを起動するだけで特定フォルダ内(たとえば"c:\test")の全フォルダやファイルの読取専用属性を解除するプログラム(すでにプログラムの中に"c:\test"が指定してある)がほしいのですがどのようにしたらよろしいのでしょう?なにとぞ知恵をお貸しください^^

ばんのしゃーによかばんた さん 2004年 08月 18日 19時 39分 06秒

>祥子 さん 2004年 02月 04日 15時 45分 14秒
>InternetExplorerの「インターネット一時ファイルの削除」
>と同じことを、CUIで実現したいです。

Set Shell=CreateObject("Shell.Application")
Set Folder=Shell.NameSpace(32)

では、普通のフォルダやファイルのように見えて、
エクスプローラの表示のようには見えません。なんで?

実ディレクトリ
C:\Documents and Settings\Administrator\Local Settings\Temporary Internet Files
の DESKTOP.INI を見てみると、
[.ShellClassInfo]
UICLSID={7BD29E00-76C1-11CF-9DD0-00A0C9034933}

のようになっていましたす。試しに、これを、

[.ShellClassInfo]
UICLSID={7BD29E00-76C1-11CF-9DD0-00A0C9034933}
CLSID={7BD29E00-76C1-11CF-9DD0-00A0C9034933}

のように書き換えてやると、
Shell.Applicationでも、エクスプローラと同じ情報が見えるようになりました。
Folder.GetDetailsOf(FolderItem,n)

同様に削除もできると思います。(未テスト)
FolderItem.InvokeVerb("削除(&D)")

isp1014 さん 2004年 08月 18日 17時 31分 35秒

素早い返信ありがとうございます。
早速試してみましたが、残念ながらうまくいきませんでした。

そもそもBrowseForFolderのダイアログボックスが画面に表示されるまえに
「書き込みできません」のエラーが返されてしまいます。

エラーがでるので、IEの左下の注意マークをダブルクリックすると、

Set oFolder=Shell.BrowseForFolder(0,"フォルダを選んでください。",BIF_EDITBOX+BIF_DONTGOBELOWDOMAIN+BIF_RETURNONLYFSDIRS,17)

の行で「書き込みできません」エラーが同じように発生しているようです。

やっぱり無理なのでしょうか?
それとも私の理解力不足なのでしょうか?

よろしくお願いします。

ばんのしゃーによかばんた さん 2004年 08月 18日 16時 44分 55秒

少し前のことですが、

>魔界の仮面弁士 さん 2004年 03月 29日 05時 03分 26秒
>セキュリティ上の問題からなのか、最近のバージョンでは、
>ie.Navigate "about:<html><body><input type=file id=txtFile></body></html>"
>の記述が利用できないようです。(IE6SP1からだったかな?)
>ただし、“javascript Protocol”を使った、
>ie.Navigate2 "javascript:document.write('<html><body><input type=file >id=txtFile></body></html>');"
>のような記述であれば、現在のバージョンでも動作するようです。

これは、もっと単純に、about:似に、

>ie.Navigate "about:<html><body><input type=file id=txtFile></body></html>"

ie.Navigate "javascript:'<html><body><input type=file >id=txtFile></body></html>'"

と書けるようです。

about:〜やjavascript:〜は
<HTML><SCRIPT>var __w="〜";if(__w!=null)document.write(__w);</SCRIPT></HTML>

のように内部的に処理(about、window.open/navigate javascript) 、
または展開(ie.Navigate javascript)されるようです。
後者は、例のWScript.Echo ie.document.documentElement.outerHTMLで見えます。

javascript:var x=eval(〜);
という記述をよく見かけて、なんでかなぁ、と思っていたのですが、
if(__w!=null)document.write(__w)で書き込まれるのを避けるためだったのですね。

でも、この記述はie.Navigateでは、構文エラーになるので、また、セマンティックにも、
javascript:void(eval(〜));
のほうがよいと思います。どうなんでしょう。

ばんのしゃーによかばんた さん 2004年 08月 18日 16時 42分 46秒

>ばんのしゃーによかばんた さん 2004年 06月 24日 19時 09分 49秒
>むたぐちさん作、IEのお気に入りをHTMLファイルにするスクリプト
>これがこんなに遅いのは、メモリ上の文字列処理のためです。
>性能問題でよくある間違いのひとつが、IOよりメモリの処理が速い、という思い込みです。
>メモリ処理をIOに変えるだけで随分と速くなります。

などと、言っておきながら、今更のようで、なんなんですが、
メモリ処理とIO処理を単純に比べれば、当然のことながら、メモリのほうが速い。
以前のは、y=c*x**2とy=b*xの比較で、今回はy=b*x同士のbの比較ですね。

そこで、件のスクリプトですが、

Dim arr()
Dim ind

Sub Write(s)
ReDim Preserve arr(ind)
arr(ind)=s
ind=ind+1
End Sub

Sub WriteLine(s)
Write s & vbCRLF
End Sub

を追加し、

すべてのts.Write を Write に変更し、
すべてのts.WriteLine を WriteLine に変更し、

終わりのところを、

ts.Write Join(arr,"")
ts.Close
WScript.Echo "done."

のように変えれば、相当速くなります。
概算で、10msec*IO回数で見積もります。
ただし、IO Cacheがwrite backの場合は、効果は小さい。

性能にご不満な方はお試しあれ。

ばんのしゃーによかばんた さん 2004年 08月 18日 16時 41分 44秒

IEの終了監視方法ですが、

>ばんのしゃーによかばんた さん 2004年 04月 05日 21時 55分 49秒
> On Error Resume Next
> Do While ie.Visible
> WScript.Sleep 1000
> Loop
> On Error GoTo 0
> Msgbox "IE終了"
> 何かの処理
> WScript.Quit

は、もうひとつでした。タイミングで無限ループすることがあります。
やっぱり、On Errorの使い方がよくないですね。

そこで、On Errorを使わない改良版です。

Do While TypeName(ie)="IWebBrowser2"
'WScript.Echo TypeName(ie)
WScript.Sleep 1000
Loop
Msgbox "IE終了"
WScript.Quit

IEが終了すると、TypeNameが"IWebBrowser2"から"Object"に変化することを利用します。

ばんのしゃーによかばんた さん 2004年 08月 18日 16時 40分 46秒

昔の記事、

>Coco さん 2003年 12月 01日 10時 13分 33秒
>フォルダを選択のダイアログボックスで
>何も選択せず、OK もしくは Cancelを押した場合、
>にWScript.Quitで強制終了をさせたいのですが、
>デフォルトでMy Documentが選択されていますので、
>OKを押された場合、My Documentが対象になってしまいます。
>このような判断はできないのでしょうか?

>Set oFolder=Shell.BrowseForFolder(0,"フォルダを選んでください。",BIF_EDITBOX+BIF_DONTGOBELOWDOMAIN+BIF_RETURNONLYFSDIRS,"")
>If oFolder Is Nothing Then WScript.Quit

ですが、回避策。

ルートに""(デスクトップ)を指定しないで、マイコンピュータを指定する。

Set oFolder=Shell.BrowseForFolder(0,"フォルダを選んでください。",BIF_EDITBOX+BIF_DONTGOBELOWDOMAIN+BIF_RETURNONLYFSDIRS,17)

このとき、マイコンピュータが初期選択されています。
ここで、OKを押すと、マイコンピュータが返ります。

BIF_RETURNONLYFSDIRSと言っているのに、マイコンピュータを返すのは変です。
障害(バグ)ではないでしょうか。

でも、それを逆手にとって、

If oFolder Is Nothing Then WScript.Quit
If Not oFolder.Self.IsFileSystem Then WScript.Quit

とするのです。

isp1014 さん 2004年 08月 18日 15時 43分 37秒

少しWSH Lab.掲示板の主旨とは外れていますが、質問させて下さい。
ASPに記述したVBSについての質問です。

あるWEBページでボタンを押下した時に
ファイル選択ではなくて、フォルダを選択したいのです。
(フォルダ選択ダイアログボックスの表示)
そのときに使用する命令として
BrowseForFolderオブジェクトを使用しています。

例えばこんな感じです。
Set objFol = objSA.BrowseForFolder(0,"選択",BIF_EDITBOX,rDrive)

しかし、実行してみると「書き込みできません」と
VBSのエラーが発生してしまいます。
WEBではない、ただのVBSではうまく動作します。
(クライアント上のVBSファイルを実行)

ひょっとしてWEBでは使用できないのでしょうか?
使用できないのであれば、別の方法があるのでしょうか?

大変困っています。
直接WSHとは関係ないかもしれませんが、
よろしくお願いします。

MMM さん 2004年 08月 17日 16時 16分 33秒

魔界の仮面弁士さん、どうもありがとうございます。
ログインユーザ名は取得できました。

何度も質問ですいません。
このログインユーザ名をコピー先のフォルダパスに指定するには、どうすればよいのでしょうか?
「&」でつないで見たりしたのですが、うまくいきませんでした。

魔界の仮面弁士 さん 2004年 08月 17日 13時 10分 13秒

》 MMM さん
> ログインしたユーザの名前
WshEnvironment オブジェクトを使えば、環境変数を取得出来ます。
MsgBox CreateObject("WScript.Shell").Environment("Process").Item("USERNAME")

もしくは、WshNetwork オブジェクトの UserName プロパティも使えます。
MsgBox CreateObject("WScript.Network").UserName

MMM さん 2004年 08月 17日 10時 19分 53秒

wshをはじめたばかりでつまらない質問ですいませんが、ご意見をください。
ローカルにある特定のフォルダをコピーしたいのですが、コピー先がログインしたユーザの名前のフォルダにしたいのです。
コマンドプロンプトでは、下記のように「%username%」と指定すればよいのですが・・・
Xcopy /h /k /r /d c:\test D:\%USERNAME%\
コマンドプロンプトを使用すれば早いのですが、ログインしたユーザアカウントでは、コマンドプロンプトは使用できないように制限しているために、vbsで書きたいのです。
vbsの場合はどのように指定をすればよいのでしょうか?

いりや さん 2004年 08月 17日 01時 48分 27秒

魔界の仮面弁士さん、

見つかりました!
Office 2000 これでした!

会社のノートにはこれを入れていましたので ActiveX オブジェクトとして生成
することにしていたようです。

しかし Office 2000 を入れると裏でたくさんの開発者用ライブラリが入るんで
すねぇ。よくよく考えてみれば VisualBasic for Applciation (VBA) をエクセ
ルは搭載しているんだから入っているのは必然なのかもしれません。

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

>魔界の仮面弁士 さん 2004年 08月 14日 20時 40分 11秒
>body から parentNode/parentElement で辿る以外の手法としては、
> Set objHtml = IE.document.documentElemnt

そんな便利なのがあるとは、知りませんでした。これからは、これを使わせて頂きます。


別件の元記事について、

>魔界の仮面弁士 さん 2003年 12月 15日 14時 59分 20秒
>> ショートカットをドラッグ&ドロップされると
>この点は、RegisterAsDropTargetをFalseにする事で回避できます。

WebBrowserオブジェクトについては、そのとおりなのですが、
InternetExplorerオブジェクトだと、なぜか、効きません。
いろいろ試してみると、

ie.Navigate src
ie.RegisterAsDropTarget=False

の順序だと駄目で、

ie.RegisterAsDropTarget=False
ie.Navigate src

の順序だと、効きました。変なの。

>> BeforeNavigate2イベントのCancelにTrueを指定したのですが、
>試してみました。なるほど、確かにキャンセルされませんね。
>pDisp.Stop でも駄目なようですし。。。
>InternetExplorerのインターフェイス定義を確認してみたところ、Cancel引数は、
>「ByRef As Variant」ではなく、「ByRef As Boolean」として定義されていましたので、
>もしかしたらVBScriptからだと、Canelの指定は行えないのかも知れません。

こちらのほうは、

Sub IE_BeforeNavigate2(pDisp, URL, Flags, TargetFrameName, PostData, Headers, Cancel)
If URL<>src Then ie.Navigate src
End Sub

という代替策が効きます。

WSH側で何か処理中だとタイミング問題が生じるかも知れません。
他に行くことだけは一応防げます。

魔界の仮面弁士 さん 2004年 08月 16日 17時 00分 08秒

》 いりや さん
> ん〜でもどの製品にバンドルされているものなんだろう。
このあたりの製品に含まれています。

[ver.1.1.37.15] http://support.microsoft.com/servicedesks/fileversion/moreinfo.asp?Id=60142
[ver.1.1.81.69] http://support.microsoft.com/servicedesks/fileversion/moreinfo.asp?Id=231640
[ver.1.1.83.90] http://support.microsoft.com/servicedesks/fileversion/moreinfo.asp?Id=199067
[ver.1.1.88.4] http://support.microsoft.com/servicedesks/fileversion/moreinfo.asp?Id=187259
[ver.1.1.91.20] http://support.microsoft.com/servicedesks/fileversion/moreinfo.asp?Id=211613


なお、もしも new ActiveXObject/CreateObject ができなかった場合には、
ProgIdが登録されていない可能性がありますので、
》RiffRaff さん 2001年 07月 30日 01時 15分 36秒
の発言にあるように、自前での登録を行ってみてください。

# TlbInf32.chm には、CreateObjectで呼べると書いてあるのですけれどね。。。

いりや さん 2004年 08月 16日 15時 07分 21秒

TLI.TLIApplication を発見。ん〜でもどの製品にバンドルされている
ものなんだろう。オフィス製品はごそっと入っているのですが・・・。

エクセルのオブジェクトブラウザでどのコンポーネントなのかさがして
みましたが、見つかりませんでした。どこだろう。

いりや さん 2004年 08月 16日 02時 38分 05秒

魔界の仮面弁士さん、

TLI.TLIApplication オブジェクトを使った説明、ありがとうございました。わ
たしがこの ActiveX オブジェクトのことを知ったのは今日がはじめてのような
気がします。(たぶん前に投函があったとしても見過ごしています...)

手元の WinXP にはインストールされていなかったので、明日オフィスで調べて
みます。

| > コンパイル言語処理系や、インタープリタ言語処理系でも、組込まれた ActiveX
| > オブジェクトが固定なのであれば、処理系を作成するタイミングで DISPID が解
| > 決できるので、後者が利用できます。
|
| で、いずれかの方法で、DISPID さえ分かってしまえば、
|  var /* const */ INVOKE_FUNC = 1;
|  var /* const */ idFileExists = 0x2720;
|  var ret = TLIApp.InvokeHook(FSO, idFileExists, INVOKE_FUNC, "C:\\A.TXT");
| などのようにして呼び出す事もできますね。
|
| # …ただ、有効な利用方法は思い浮かびませんけれども。

ひょんさんのサイトの技術資料 ( http://hyons.hp.infoseek.co.jp/cgi-bin/pp.cgi?view=prog/vb003 )
で言及されていましたが、バインディングのための名前解決の費用がけっこうか
さむ場合には、こうしてあらかじめ済ませておけば基本性能の底上げに貢献する
かもしれません。

あと、遅延評価 (Lazy Evaluation) の道具としても TLI.TLIApplication オブ
ジェクトは利用できそうです。まだ漠然としか思いつきませんが・・・。

| > でも、魔界の仮面弁士さんが示してくれた実例から考えると、この一行をすっと
| > ばかしているインプリメンタがいる、ということなんでしょうね〜。
|
| case sensitive な呼び出しには、IDispatchEx::GetDispID が使われているのかも知れません。
| これならば、第2引数の呼び出しに応じて、例えば「Length」と「length」を区別するような
| コンポーネントを実装する事ができるのかも? と予想しています。
|
| http://msdn.microsoft.com/library/en-us/script56/html/lrfidispatchexgetdispid.asp
|
| # 私自身、そういった細かい部分に関しては詳しく無いので、間違ってるかも。

第二引数というのは、

| fdexNameCaseSensitive
|
| Requests that the name lookup be done in a case-sensitive manner. May be
| ignored by object that does not support case-sensitive lookup.

ですね。このパラメタを設定したときの IDispatchEx::GetDispID のインプリメ
ンタがそのパラメタの通りにプログラムしている ActiveX オブジェクトに対し
ては、魔界の仮面弁士さんの予想の通りだと思います。

ところで、この新しいインターフェイスのことは初めて知りました。msdn の
Component Development の目次で見つけることが出来ませんでしたが、なーんと、
script56.chm にも入っているじゃないですか。灯台下暗し。(^^;

また、IDispatchEx でググってみたら五年前に発行された Microsoft 社のドキュ
メントにヒットしました。

http://www.microsoft.com/mind/1099/dynamicobject/dynamicobject.asp

こちらに、

| IDispatch also makes no provision for case-sensitive access to members,
| as opposed to JScript.
[中略]
| To remedy these deficiencies, Microsoft created the IDispatchEx
| interface. This interface allows for enumeration of members, the
| addition/deletion of members, and case-sensitive calling of members.

と書いてありました。IDispatch インターフェイスを規定していた頃から状況が
かわって、それに伴い仕様を追加していますね。

IDispatchEx インターフェイスをサポートする ActiveX オブジェクトに対して、
ActiveX クライアントは、IDispatchEx::GetDispID で Case
sensitive/insensitive をクライアントの都合で設定して起動してよい、ことに
なるのか。

IDispatch インターフェイスの時は、仕様上は Case insensitive という前提を
おけるので話はシンプルでしたが、ActiveX クライアントが IDispatchEx イン
ターフェイスを使用している場合は、クライアントの事情も勘定に入れないとい
けないですね。

いりや

魔界の仮面弁士 さん 2004年 08月 15日 19時 56分 39秒

》 いりや さん
> ActiveX クライアントは IDispatch インターフェイスを通じてアクセスすると
> き、DISPID を得るための方法が二つあって、一つは、実行時に
> IDispatch::GetIDsOfNames を通じて DISPID (ディスパッチ ID) を得る方法。

# VB6などで「実行時バインディング」を行った時にも使われる方法ですね。
# http://www.microsoft.com/japan/developer/library/VBCon98/vbconhowbindingaffectsolecomponentperformance.htm

なお、TLIのInvokeIDメソッドが、IDispatch::GetIDsOfNames を
カプセル化しているようです。

たとえば、FileSystemObject::FileExists に対して、
  var TLIApp = new ActiveXObject("TLI.TLIApplication");
  var FSO = new ActiveXObject("Scripting.FileSystemObject");
  var idFileExists = TLIApp.InvokeID(FSO, "FileExists");
  WScript.Echo(idFileExists.toString(16));
を実行して見ますと、"2720" という値が返されてきます。

実際に、OleView を使ってタイプライブラリ情報を調べてみると、
》 [id(0x00002720), helpstring("Check if a file exists"), helpcontext(0x00214b97)]
》 VARIANT_BOOL FileExists([in] BSTR FileSpec);
のように、DISPID == 0x00002720 である事が確認できます。


上記以外の方法では、
 With CreateObject("TLI.TypeLibInfo")
  .ContainingFile = "SCRRUN.DLL"
  idFileExists = TLInfo.GetTypeInfo("FileSystemObject").DefaultInterface.GetMember("FileExists").MemberId
 End With
のように、ファイルから直接調べたり、あるいは、Members を列挙して、
一致する名前を探し出す事もできるようです。


> コンパイル言語処理系や、インタープリタ言語処理系でも、組込まれた ActiveX
> オブジェクトが固定なのであれば、処理系を作成するタイミングで DISPID が解
> 決できるので、後者が利用できます。

で、いずれかの方法で、DISPID さえ分かってしまえば、
 var /* const */ INVOKE_FUNC = 1;
 var /* const */ idFileExists = 0x2720;
 var ret = TLIApp.InvokeHook(FSO, idFileExists, INVOKE_FUNC, "C:\\A.TXT");
などのようにして呼び出す事もできますね。

# …ただ、有効な利用方法は思い浮かびませんけれども。



> でも、魔界の仮面弁士さんが示してくれた実例から考えると、この一行をすっと
> ばかしているインプリメンタがいる、ということなんでしょうね〜。

case sensitive な呼び出しには、IDispatchEx::GetDispID が使われているのかも知れません。
これならば、第2引数の呼び出しに応じて、例えば「Length」と「length」を区別するような
コンポーネントを実装する事ができるのかも? と予想しています。
http://msdn.microsoft.com/library/en-us/script56/html/lrfidispatchexgetdispid.asp

# 私自身、そういった細かい部分に関しては詳しく無いので、間違ってるかも。


> わたしは、メンバ (メソッド、プロパティー) 名を書くときは小文字で始まる流
> 儀なので、名前解決に失敗するエラーのリスクは引き受ける方針でいこうと思っ
> ています。

私の場合は、JScriptの時は小文字始まり、VBScriptでは大文字始まりで
宣言する事が多いです。ただ、.NET や COM などの外部コンポーネントの
呼び出し時には、自分の流儀を押し付けるわけにも行かないので、
相手側の命名に仕方なく合わせています。(;_;)


/***** C:\TEST.JS *****/
import System;
var S : String = "ABCD";
System.Console.WriteLine(S.toString()); // JScriptの命名規則
System.Console.WriteLine(S.ToString()); // .NET Frameworkの命名規則
// System.Console.WriteLine(S.tostring()); // 未定義メンバなので、コンパイルエラー

var O = "ABCD";
System.Console.WriteLine(O.toString());
System.Console.WriteLine(O.ToString());
System.Console.WriteLine(O.tostring()); // コンパイルは通るが、実行時エラー

いりや さん 2004年 08月 15日 14時 57分 18秒

魔界の仮面弁士さん、

魔界の仮面弁士 wrote:
| 》 いりや さん
| > COM オブジェクトの名前からディスパッチ ID を返す
| > 手続きの実装に目を付けたものですね。
|
| なお、FileオブジェクトのDeleteメソッド自体は、タイプライブラリ上は
| 「最初が大文字」で定義されていますので、delete ではなく、Delete と
| 記述するのが、本来は正しい表記となります。

なるほど〜。情報ありがとうございます。

               ★☆

これを読みながら、今まで呼び出し方についてあんまり考えたことがなかったの
で、ちょっと時間をかけて msdn を追ってみました。Automation に関する項の
あたり。

以下は、そのメモです。

[ Automation ]

Automation は IDispatch インターフェイスをサポートする必要があります。
( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap5_78v9.asp )

ActiveX クライアントは IDispatch インターフェイスを通じてアクセスすると
き、DISPID を得るための方法が二つあって、一つは、実行時に
IDispatch::GetIDsOfNames を通じて DISPID (ディスパッチ ID) を得る方法。

もう一つは IDispatch::GetTypeInfo を通じて DISPID をあらかじめ引き当てて
おくというもの。

前者は、プログラムが実行される前にどの ActiveX オブジェクトが使われるか
分からない場合に必要。これはインタープリタ言語処理系などの ActiveX クラ
イアントがインプリメントするのでしょう。

後者は、逆にどの ActiveX オブジェクトが使われるかプログラムが実行される
前に、プログラムの中でどの ActiveX オブジェクトが使われるか分かっている
場合に使われるのでしょう。

コンパイル言語処理系や、インタープリタ言語処理系でも、組込まれた ActiveX
オブジェクトが固定なのであれば、処理系を作成するタイミングで DISPID が解
決できるので、後者が利用できます。


[ IDispatch::GetIDsOfNames における大文字小文字の区別 ]

IDispatch::GetIDsOfNames の解説 ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap5_32cz.asp )
によれば、

  The implementation of GetIDsOfNames is case insensitive. Users that
  need case-sensitive name mapping should use type information
  interfaces to map names to DISPIDs, rather than call GetIDsOfNames.

とありました。IDispatch::GetIDsOfNames のインプリメンタは、メンバとして
大文字と区別を区別しない、と読めます。

でも、魔界の仮面弁士さんが示してくれた実例から考えると、この一行をすっと
ばかしているインプリメンタがいる、ということなんでしょうね〜。

それに、実際に検証していないのですが、DispGetIDsOfNames() Win32 API ( http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap5_1jxv.asp )
が IDispatch::GetIDsOfNames の模範インプリメンテーションとして紹介されて
います。説明によれば Type Info をもとに、と説明されています。

とすれば DispGetIDsOfNames() は Type Info にあるシグネチャをそのまま比較
しているのか?!

もしそうならば、同ページに掲載されている例題そのままに IDispatch::GetIDsOfNames
をインプリメントしているとくだんの事象が確認されることになりますね。


[ ActiveX クライアント側のメンバ呼び出しの留意点 ]

上記を踏まえて、ActiveX クライアントは、ActiveX オブジェクトのメンバを名
前で呼び出す時に留意することがあるとすれば、それはどんなことか。

まず ActiveX オブジェクトを提供する側の IDispatch::GetIDsOfNames のイン
プリメンテーションによるので何にでもあてはまる原則というものはない。

msdn に

  The implementation of GetIDsOfNames is case insensitive.

とあるので、メンバの呼び出しにあたっては大文字小文字の区別をする必要はな
い。さらに、インタープリタ言語処理系のようなプログラミング言語のデータオ
ブジェクトとして使われるのであれば、構文規則を守る必要があるのでそれを忘
れずに。

ただし、この前提が成り立たない IDispatch::GetIDsOfNames をインプリメント
している ActiveX オブジェクトを相手にする場合もある。

そのため、メンバの呼び出しでエラーが発生した場合は、タイプライブラリを確
認してそこに記されているシグネチャ通りに書いてみて確かめる。

あるいは ActiveX オブジェクトの都合に左右されないために、むたぐちさんや
魔界の仮面弁士さんのおっしゃるとおり、タイプライブラリに記されているシグ
ネチャを使う。

そんな感じでしょうか。

わたしは、メンバ (メソッド、プロパティー) 名を書くときは小文字で始まる流
儀なので、名前解決に失敗するエラーのリスクは引き受ける方針でいこうと思っ
ています。

いりや

魔界の仮面弁士 さん 2004年 08月 14日 21時 47分 48秒

》 魔界の仮面弁士
> 「HTML」の childNodes は、「HEAD」と「BODY」を返すのに、

調べてみると、「HTML」の children は、「HEAD」だけを返すようです。

この、「chidren で取得した場合の階層構造」を図に表してみると、

 <HTML>
  └<HEAD>
    ├<TITLE>
    ├<META>
    └<BASE>
      └<BODY>
         ├……


のようなイメージで解析されているようです。

一方、「childNodes で取得した場合の階層構造」の場合は、

 <HTML>
  ├<HEAD>
  │ ├<TITLE>
  │ ├<META>
  │ └<BASE>
  └──┴<BODY>
          ├……


というイメージになるようです。BODY の親が2人いる感じですね。

# VBScript の Is 演算子で比較して見たところ、
# 『objHtml.childNodes(1) Is objHtml.childNodes(0).childNodes(2).childNodes(0)』
# が、True を返す状態になっていました。


> その「BODY」の parentElement が 「BASE」を返してきてます。

ちなみに、「BODY」の parentNode も「BASE」を返してきました。

魔界の仮面弁士 さん 2004年 08月 14日 20時 40分 11秒

》 ばんのしゃーによかばんた さん
> BASEタグが付いていると、HTMLタグでなく、BASEタグが取れてしまいます。障害?
あれま、本当ですね。親子関係がおかしい…。

「HTML」の childNodes は、「HEAD」と「BODY」を返すのに、
その「BODY」の parentElement が 「BASE」を返してきてます。
(next/previousSibling を辿ってみると、兄弟関係は正しいようです)


しかも「BASE」の outerHTML を出力してみたら、
-------------
<BASE target=_blank></HEAD>
<BODY text=#00006f bgColor=#dedbf7>
<H1 align=left><FONT color=#0000a0 size=5>WSH Lab.掲示板</FONT></H1>
 :
(中略)
 :
</P></BODY>
-------------
という、とんでも無い結果になってしまいました。(/_;)


なお、
 <HEAD>
  <BASE href="〜"></BASE>
  <TITLE>〜</TITLE>
 </HEAD>
のように、BASE要素の終了タグを記述すれば、正しく読み込まれるみたいです。
もっとも、これではHTML的には文法違反になってしまいますけれどね。:(



> 辿れる限り、parentElementを辿る、というのが清く正しい方法なのかも。

body から parentNode/parentElement で辿る以外の手法としては、
 Set objHtml = IE.document.all.tags("HTML")(0)
 Set objHtml = IE.document.getElementsByTagName("HTML").item(0)
 Set objHtml = IE.document.documentElemnt
なども利用できます。

# allなら、ターゲットがIE4でも大丈夫かも? (未確認)

ばんのしゃーによかばんた さん 2004年 08月 14日 17時 22分 01秒

body.parentElement.outerHTMLでHTMLソースを取る方法について。

この掲示版にも最近BASEタグが追加されましたが、
BASEタグが付いていると、HTMLタグでなく、BASEタグが取れてしまいます。障害?
辿れる限り、parentElementを辿る、というのが清く正しい方法なのかも。

サンプル
アクティブな(i.e.メモリ上の)HTMLソースを表示するコンテクストメニュー拡張です。
JScript版
――――――――――――――――――――――――――――――――――――――
<html>
<object id=fso classid="CLSID:0D43FE01-F093-11CF-8940-00A0C9054228">
</object>
<object id="wShell" classid="CLSID:F935DC22-1CF0-11D0-ADB9-00C04FD58A0B">
</object>
<script>
for(var Element=external.menuArguments.document.body;Element.parentElement;Element=Element.parentElement){
//window.alert(Element.tagName);
}
//window.alert(Element.tagName);
var TempName=fso.BuildPath(fso.GetSpecialFolder(2).Path,fso.GetTempName());
var File=fso.CreateTextFile(TempName);
File.Write(Element.outerHTML);
File.Close();
wShell.Run("NotePad.Exe " + TempName);
</script>
</html>
――――――――――――――――――――――――――――――――――――――
VBScript版
――――――――――――――――――――――――――――――――――――――
<html>
<object id=fso classid="CLSID:0D43FE01-F093-11CF-8940-00A0C9054228">
</object>
<object id="wShell" classid="CLSID:F935DC22-1CF0-11D0-ADB9-00C04FD58A0B">
</object>
<script language="vbscript">
Dim File
Dim TempName
Dim Element
TempName=fso.BuildPath(fso.GetSpecialFolder(2).Path,fso.GetTempName())
Set File=fso.CreateTextFile(TempName)
Set Element=external.menuArguments.document.body
Do While Not Element.parentElement Is Nothing
Set Element=Element.parentElement
'window.alert(Element.TagName)
Loop
File.Write Element.outerHTML
File.Close
wShell.Run "NotePad.Exe " & TempName
</script>
</html>
――――――――――――――――――――――――――――――――――――――

魔界の仮面弁士 さん 2004年 08月 14日 17時 01分 57秒

》 いりや さん
> COM オブジェクトの名前からディスパッチ ID を返す
> 手続きの実装に目を付けたものですね。

なお、FileオブジェクトのDeleteメソッド自体は、タイプライブラリ上は
「最初が大文字」で定義されていますので、delete ではなく、Delete と
記述するのが、本来は正しい表記となります。


[uuid(C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0),
hidden,dual,nonextensible]
dispinterface IFile {
properties:
methods:
(中略)
[id(0x000004b0)]
void Delete([in, optional, defaultvalue(0)] VARIANT_BOOL Force);
(中略)
}


[uuid(C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0),
odl,hidden,dual,nonextensible,oleautomation]
interface IFile : IDispatch {
(中略)
[id(0x000004b0)]
HRESULT Delete([in, optional, defaultvalue(0)] VARIANT_BOOL Force);
(中略)
}


> WScript.quit();
これも、本来は「WScript.Quit();」ですね。



》 魔界の仮面弁士
> # ActiveXコンポーネントの中には、大文字小文字を
> # 区別する物もありますけれどね。
JScript関連のコンポーネントが、まさにこれに当たりますね。
(JScript.dll とかもそうかな?)

『JScript の Arrayオブジェクトを受け取る ActiveX DLL』を
VB6 で試しに作成してみたのですが、
  objArray.push "ほげ"
  CallByName objArray, "push", VbMethod, "はげ"
などは呼び出せましたが、
  objArray.Push "ひげ"
  CallByName objArray, "Push", VbMethod, "まげ"
などと書くと、
| 実行時エラー: '438'
| オブジェクトは、このプロパティまたはメソッドをサポートしていません。
というエラーになってしまいました。

魔界の仮面弁士 さん 2004年 08月 14日 17時 01分 01秒

》 いりや さん
> COM オブジェクトの名前からディスパッチ ID を返す
> 手続きの実装に目を付けたものですね。

なお、FileオブジェクトのDeleteメソッド自体は、タイプライブラリ上は
「最初が大文字」で定義されていますので、delete ではなく、Delete と
記述するのが、本来は正しい表記となります。


[uuid(C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0),
hidden,dual,nonextensible]
dispinterface IFile {
properties:
methods:
(中略)
[id(0x000004b0)]
void Delete([in, optional, defaultvalue(0)] VARIANT_BOOL Force);
(中略)
}


[uuid(C7C3F5A4-88A3-11D0-ABCB-00A0C90FFFC0),
odl,hidden,dual,nonextensible,oleautomation]
interface IFile : IDispatch {
(中略)
[id(0x000004b0)]
HRESULT Delete([in, optional, defaultvalue(0)] VARIANT_BOOL Force);
(中略)
}


> WScript.quit();
これも、本来は「WScript.Quit();」ですね。



》 魔界の仮面弁士
> # ActiveXコンポーネントの中には、大文字小文字を
> # 区別する物もありますけれどね。
JScript関連のコンポーネントが、まさにこれに当たりますね。
(JScript.dll とかもそうかな?)

『JScript の Arrayオブジェクトを受け取る ActiveX DLL』を
VB6 で試しに作成してみたのですが、
  objArray.push "ほげ"
  CallByName objArray, "push", VbMethod, "はげ"
などは呼び出せましたが、
  objArray.Push "ひげ"
  CallByName objArray, "Push", VbMethod, "まげ"
などと書くと、
| 実行時エラー: '438'
| オブジェクトは、このプロパティまたはメソッドをサポートしていません。
というエラーになってしまいました。

いりや さん 2004年 08月 14日 14時 10分 26秒

魔界の仮面弁士さん、むたぐちさん、

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

               ★☆

魔界の仮面弁士さん wrote:
| その問題に関しては、
| > files.do_(function (file) { file.delete(true) }); //★
| の替わりに、
| > files.do_(function (file) { file['delete'](true) }); //★
| という構文が利用可能です。

確認しました。これは、ドット表記で識別子を書くところをサブスクリプト表記
で識別子を排除することによって処理系の検査をすり抜けるトリックですね。

実はここにあらわれている Array オブジェクトの要素に対して繰り返しをさせ
る do_ メソッド。この do_ を最初は do としようと思っていたのです。でも
do は予約語なので delete と同じ理由で、ドット表記で識別子として使えず
do_ で代替したのでした。これをサブスクリプト表記におきかえれば

files['do'](function (file) { file['delete'](true) });

となりますね。

むたぐちさんのアイディアは、JScript 処理系が Case sensitive で大文字小文
字を区別して予約語かどうかの比較をおこなうことと COM オブジェクトの名前
からディスパッチ ID を返す手続きの実装に目を付けたものですね。たぶん
JScript 処理系の内部に持っている予約語の辞書には delete だけ入っているん
でしょう。


これでワークアラウンドは合計三つになりました。
ありがとうございました!!

               ★☆

それで、私としては、識別子として許される表現は、置かれることが許される任
意の場所において置いてよい、という ECMAScript の仕様上の保証の上にプログ
ラミングしたいので、こんな方針をたてました。

(1) Host Object の世界と衝突した場合には、deleteFile() のような形で代替
  案を探して、そういう世界を JScript 処理系の世界に持ち込まないように
  する。

  そうすることによって、識別子として書ける場所に書けない状況そのものを
  取り除く。(そういう所で縛りを入れられないことの方が嬉しいという立場)

(2) 代替案が見つからない場合は、サブスクリプト表記による識別子の表現をな
  くすことによって処理系の検査を回避する。

               ★☆


ところで、今回の話を調べてみて二つのことを考えるきっかけとなりました。

一つ目は、ECMAScript の仕様の予約語に対する使用上の制限のきつさ。これは
Douglas Crockford さんがすでに指摘していて Recommendations for
Modifications to the ECMAScript Language Specification でまとめられてい
ます。私も、もう少し緩めてくれてもいいのに〜、と思います。

http://www.crockford.com/javascript/recommend.html

二つ目は、仕様で規定しない Host object -- 処理系が独自に組み込んだオブジェ
クト -- と仕様との整合性。

JScript の Host object である Component Object Model オブジェクトには、
そんな予約語をメソッド名として使っちゃいけないなんていう話はない。という
ことは、組み込む判断をした時点で、不整合を処理系として許容していることに
なる。

別の世界のものをつなぐということは、機能が増えるから単純に嬉しいのかと思
いましたが、今回のように記法上の表現の自由度がさがることもあって、組み込
むかどうかを判断するには、そうすることがトータルでみて本当に有難いのか見
極めをしなきゃいかんと感じました。

不整合を何でも許容してどんどん制約を増やしてその重さにつぶれないようにし
なきゃいけないですね。

ま、COM オブジェクトは私にとって Windows Script Host の要 (かなめ) なの
で、なきゃ話にならないんですが ... (^^;

いりや

魔界の仮面弁士 さん 2004年 08月 14日 00時 04分 01秒

》 いりや さん
その問題に関しては、
> files.do_(function (file) { file.delete(true) }); //★
の替わりに、
> files.do_(function (file) { file['delete'](true) }); //★
という構文が利用可能です。


》 管理人むたぐち さん
> FileオブジェクトのDeleteメソッドは、正式には
> deleteじゃなくてDeleteだと思うんですが…。

FileSystemObject の IDispatch::GetIDsOfNames は、大文字小文字を
区別しないので、その点に関しては、どちらでも問題ありません。
 file['delete'](); // …OK
 file['Delete'](); // …OK
 file.Delete();   // …OK
 file.dElEtE();   // …OK
 file.delete();   // …NG (delete は予約語)

# ActiveXコンポーネントの中には、大文字小文字を
# 区別する物もありますけれどね。


> file.Delete();
ちなみに、Fileオブジェクトの場合は、
 file.Delete;
ではメソッドを呼び出せませんが、ADODB.Recordsetオブジェクトの
MoveNextメソッドの場合は、
 RS.MoveNext;
でもメソッドが実行されます。
このあたりは、COM側の実装による違いですね。

ばんのしゃーによかばんた さん 2004年 08月 13日 19時 23分 04秒

>とうしろう さん 2004年 08月 06日 15時 13分 44秒
>HTAウィンドウ内のフレームにドラッグ&ドロップを禁止する方法

どうしてもフレームなら、禁止ではなく、無効にする方法。
あまり美しくないですが、こんなんは如何でしょうか。
ドロップを初期値で上書きして無効にします。

<html>
<head>
<script language=vbscript>
dim src
Sub iframe1_onload()
If src="" Then src=iframe1.document.location
set iframe1.document.body.onunload=GetRef("unload")
End Sub
Sub unload()
iframe1.document.location=src
End Sub
</script>
</head>
<body onload="iframe1_onload()">
<iframe id=iframe1 src="res://mshtml.dll/about.moz" >
</iframe>
</body>
</html>


管理人むたぐち さん 2004年 08月 13日 19時 13分 02秒

To: いりや さん

FileオブジェクトのDeleteメソッドは、正式には
deleteじゃなくてDeleteだと思うんですが…。

var FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var file = FileSystemObject.GetFile("C:\\Document\\test.txt");
file.Delete();
WScript.Echo ("done.");

これなら問題なく動きます。

いりや さん 2004年 08月 13日 14時 47分 07秒

あっ WScript.sleep(0.1) って 0.1 ミリ秒ですね。100 の誤りでした。

いりや さん 2004年 08月 13日 14時 05分 40秒

件名: JScript で File>>delete() を実行できない

いりやです。

既出かもしれませんがお知らせします。

ECMAScript の仕様から来る制約なので仕様には合致するのでしょ
うが、JScript 上で Host object (Component Object Model オブ
ジェクト) を使用する時の制約になるのではないでしょうか。


[ 概要 ]

File オブジェクトの delete メソッドを起動するプログラムを書
くと、JScript 処理系において「識別子がありません」というメッ
セージとともにコンパイルエラーが発生する。

たとえば

aFile.delete(true);

といったプログラムで発生する。(aFile には File オブジェクト
がバインドされている)

[ 環境 ]

WinXP SP1, IE 6.0 SP1, WSH 5.6

[ 想定される理由 ]

ECMAScript の仕様によれば、(メソッド名などを指す) 識別子とし
て予約語は使用してはいけないことになっている。delete は予約
語なので構文解析時に delete を認識したタイミングにエラーを引
き起こしていると思われる。

[ ワークアラウンド ]

Scripting.FileSystemObject>>deleteFile() メソッドで代替が可
能なので、File オブジェクトの path プロパティーを抜き出して
deleteFile() メソッドの引数に与えてやることで、同じ効果を得
ることができる。

[ サンプルスクリプト ]

スクリプトは、folderpath 配下のファイルで a もしくは A で始
まるファイル群を検索して削除を行う。

fileDeletion1() が File>>delete() を使用する
fileDeletion2() が Scripting.FileSystemObject>>deleteFile() を使用する

実行にあたっては、★のコメントと fileDeletion1(), fileDeletion2()
のコメントを外す。コンパイルエラーを確認後に、★を再度コメン
トアウトしてから実行する。fileDeletion2() によって削除が完了
する。

folderpath には、削除対象のファイルが格納されているフォルダ
のパスが設定されている。

discriminator は、引数に File オブジェクトがバインドされるこ
とを前提に、削除対象かどうかを true/false で返す一引数の関数
オブジェクトが設定されている。

この二つは自由に変更可能。

[ ソースコード ]

var FileSystemObject = new ActiveXObject('Scripting.FileSystemObject');
var folderpath = 'F:\\a';
var discriminator = function (file) { return /^[aA]/.test(file.name) }

var files = new Enumerator(FileSystemObject.getFolder(folderpath).files).asArray();
var targets = files.select_(discriminator);

WScript.echo(new Array(
    '適合条件: ' + discriminator.toString(),
    '適合結果: ' + targets.toString()
).join('\n'));

//fileDeletion1();
//fileDeletion2();

function fileDeletion1() {
    try {
        //files.do_(function (file) { file.delete(true) }); //★
    } finally {
        WScript.quit();
    }
}

function fileDeletion2() {
    var paths = targets.collect_(function (file) { return file.path });
    paths.do_(function (path) { FileSystemObject.deleteFile(path) });
    do {
        WScript.sleep(0.1);
        var files = paths.select_(function (path) { return FileSystemObject.fileExists(path) });
    } while (files.length > 0);
}

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

function Array.prototype.select_(discriminator) {
    var anArray = new Array();
    this.do_(function (each) { if (discriminator(each)) anArray.push(each) });
    return anArray;
}

function Array.prototype.collect_(transformer) {
    var anArray = new Array();
    this.do_(function (each) { anArray.push(transformer(each)) });
    return anArray;
}

function Enumerator.prototype.asArray() {
    var anArray = new Array();
    for (; !this.atEnd(); this.moveNext())
        anArray.push(this.item());
    return anArray;
}

vagabond さん 2004年 08月 12日 18時 48分 18秒

to むたぐちさん/あんのうんさん

お返事ありがとうございます。
今回は、Win98でも適用する可能性がありますので、WshExecを使ってスクリプトを作ってみようと思います。
ただ、Win98だとIPCONFIGが使えませんので、OSの種類で条件分岐させねばなりませんが、、
がんばって作ってみようと思います。参考になりました。


ばんのしゃーによかばんた さん 2004年 08月 11日 22時 23分 44秒

>とうしろう さん 2004年 08月 06日 15時 13分 44秒
>HTAウィンドウ内のフレームにドラッグ&ドロップを禁止する方法を

フレームが、

>管理人むたぐち さん 2004年 08月 09日 17時 19分 40秒
>フレームを使用しないのであれば、<head>内に、<hta:application navigable="no">
>という記述を加えればOKなのですが、フレームだと禁止することができません。
>おそらくHTAの仕様かバグだと思います。

駄目なら、

>魔界の仮面弁士 さん 2003年 12月 15日 14時 59分 20秒
>> ショートカットをドラッグ&ドロップされると
>この点は、RegisterAsDropTargetをFalseにする事で回避できます。

を参考に、
フレームでなく、WebBrowserオブジェクトを使用してみては如何でしょうか。

<html>
<head>
<script language=vbscript>
Sub onload()
ie.Navigate "about:mozilla"
ie.RegisterAsDropTarget=False
End Sub
</script>
</head>
<body onload=onload>
<object id=ie classid="clsid:8856F961-340A-11D0-A96B-00C04FD705A2}">
</object>
</body>
</html>

録画代行サービス さん (arai42@mail.goo.ne.jp) 2004年 08月 11日 17時 15分 11秒
URL:http://

はじめまして,こんにちは
管理人さん、不愉快でしたら削除お願いしたします。

〓番組録画代行いたします。〓

関東の地上波・スカパー・WOWOW・BSデジタル・CS110度
PPV(録画不可も含む)BS−1・BS−2
日本国内、全ての衛星放送録画可能です。!

音楽・映画・スポーツ・アニメ・ドキュメント
バラエティー・舞台・演劇・その他・録画可能です。!

様々なメディアに録画可能です。
DVD-R・VHS・S−VHS・D−VHS

安心の料金後払いシステムです。
詳細はメールにてお願いいたします。

いりや さん 2004年 08月 10日 12時 19分 42秒

むたぐちさん、tetsu さん、

| > Windows2000 SP3 VB6.0の環境で
| > CDO(Collaboration Data Objects)を使ったメール自動送信プログラムを作成しています。
| > LAN接続により、STMPサーバーに接続する場合はメール送信できるのですが、
| > ダイヤルアップ接続でメール送信しようとすると、自動ダイアルアップ接続されないため、メールが送信されません。
|
| そこまで融通は利かないということだと思います。
| ダイヤルアップするためのコントロールを使うか、
| そういうルーチンを組み込むかするしかないのではないでしょうか?

もし自動ダイアルアップ接続の手続きが完了した後にプログラムを
実行させてメール送信に成功したならば、むたぐちさんのおっしゃ
る通りプログラムを実行する前に接続の手続きを指示する必要があ
るんじゃないかとおもわれます。

そういう前提で書きますね。

通信プロトコルを上位層から下位層に降りていくとこんなイメージ
なのかと思いますが、上位層を使う前に下位層のセットアップが完
了していることがその条件となります。

(ユーザプログラム/CDO) → SMTP → TCP → IP → PPP → モデム

tetsu さんの報告されたケースは、

(1) PPP のセッション確立が終わらずに IP のサービスが利用でき
  ないにもかかわらず上位層のサービスを利用しようとした。
(2) CDO の内部ロジックは、下位層 (SMTP, TCP, IP サービス) が
  返したエラーをそのままユーザプログラムに報告している。
(3) ユーザプログラムとしてはメールが送信されないという不具合
  として確認される。

こんなシナリオかなーと想像します。

これを起きなくするためには【下位層の準備が整っている】状況に
していればよい、ということなので、例えば、そのための手続きを
仕込むことになるのでしょう。

ただ、そうすると、ユーザプログラムの責任分解点が、層という切
り口で不明瞭になり、層の境界によって責任を分解すべきだという
観点からは好ましいプログラミングと言えなない。あくまで PPP
セッションの確立に責任を持つのは、ユーザプログラムではない、
という前提をおくべきです。

ユーザプログラムは、こうした異常系において、そのエラーを補足
し処理を中断したりユーザにその旨を伝えて異常の回復を依頼する
[*]、そういうコーディングをすることによって責任分解点が明瞭
になると思います。

いりや

[*] 注釈

インターネット接続のプロパティー:接続タグに、ネットワーク接
続が存在しない場合はダイアルして自動的に PPP セッションを確
立する仕掛けが用意されています。これを使うことによってシステ
ムが異常ケースを救済する支援をしてくれます。こうした仕掛けを
利用することで、ユーザへの異常回復の負担も軽減されるのではな
いでしょうか。

あんのうん さん 2004年 08月 09日 20時 21分 49秒

To: vagabond さん

もし、DHCP自体の情報を取得したいのであれば、以下のURLも
参考になるかも知れません。

http://www.microsoft.com/japan/technet/community/scriptcenter/network/scrnet12.mspx

http://www.microsoft.com/japan/technet/community/scriptcenter/network/scrnet06.mspx


管理人むたぐち さん 2004年 08月 09日 17時 19分 40秒

To: とうしろう さん

> HTAウィンドウ内のフレームにドラッグ&ドロップを禁止する方法をどなたかご存知ありませんか?

フレームを使用しないのであれば、<head>内に、<hta:application navigable="no">
という記述を加えればOKなのですが、フレームだと禁止することができません。
おそらくHTAの仕様かバグだと思います。
もしフレーム内のHTMLを自前で用意するのであれば、
そこにドロップ(というか移動)を禁止するコードを加えれば良さそうです。

<html>
<head>
<script language="vbscript">
Sub onbeforeunload()
window.event.returnValue = "キャンセルを押してください"
End Sub
</script>
</head>
<body onbeforeunload="onbeforeunload">
このウィンドウにはリンクをドロップできません。
<a href="http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/index.shtml">リンク</a>
</body>
</html>

この方法だとリンクを子フレームにドロップした場合、移動するかしないかを
問うダイアログが表示されます。(OKしてしまうとやっぱり移動してしまうが)
また、HTA終了時にもダイアログが出てしまうので、そこは要工夫です。


To: はじめて さん

> サーバーのwindowsscript.admを修正してて、クライアントからの指示を受け付けるように変更しろと書いてありますが、ファイル検索してもこのファイルが見つからず、

実はwindowsscript.admはこの世に存在しないので、レジストリを直接いじる必要があります。
http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list82.shtmlの
管理人むたぐち さん 2003年 05月 21日 17時 41分 31秒 の記事をご覧ください。

また、サーバーとクライアントは同一のドメイン(ActiveDirectory or NTドメイン)
にいることと、DCOMの設定がきちんとなされていることが必須条件となります。


To: vagabond さん

> DHCPでIPアドレスを取得しているPCの、IPアドレス(またはデフォルトゲートウェイ)で条件判断をさせて、特定のレジストリ値を修正させたいのですが、、

WMIを使用すれば可能です。
http://www.roy.hi-ho.ne.jp/mutaguchi/bbs/list23.shtmlの
おじゃる さん (jza02660@niftyserve.or.jp) 2000年 10月 24日 16時 22分 18秒 の記事などを
参考にしてみてください。

WshExecを使って、ipconfigの出力を読むという方法もあります。
@IT:運用 Windows管理者のためのWindows Script Host入門 第5回 WshShellオブジェクトの詳細(1) 3.プログラムの実行方法2―Execメソッド
http://www.atmarkit.co.jp/fwin2k/operation/wsh05/wsh05_03.html

vagabond さん 2004年 08月 06日 18時 19分 27秒

こんにちわ(^^)ノ
いつも参考にさせて頂いてます。

DHCPでIPアドレスを取得しているPCの、IPアドレス(またはデフォルトゲートウェイ)で条件判断をさせて、特定のレジストリ値を修正させたいのですが、、
出来ればVBScriptでこれを実現したいのですが、可能なのでしょうか?
VBSやWSHにDHCP情報を取得する手段は無いように思えますが、、上手い手段があれば、ご教示下さい。
スクリプト初心者なので、出来れば具体例で教えて頂けるとありがたいです。
図々しくてすいません。





はじめて さん (masayuki_doi@hotmail.com) 2004年 08月 06日 15時 39分 41秒

サーバーのbatをクライアントから指示して起動するのにwshが使えそうだと思ったのですが。MSのサイトでは、サーバーのwindowsscript.admを修正してて、クライアントからの指示を受け付けるように変更しろと書いてありますが、ファイル検索してもこのファイルが見つからず、上記のサイトで、このファイルはダウンロード可能と書いてあるので探しましたがそれも見つかりませんでした。どなたかリモートスクリプティングを実行された方がいらしたら、これをどこで入手されたか教えていただけないでしょうか。

とうしろう さん 2004年 08月 06日 15時 13分 44秒

HTAウィンドウ内のフレームにドラッグ&ドロップを禁止する方法をどなたかご存知ありませんか?
ネットを探し回ってもなかなか見つけることができませんです

ばんのしゃーによかばんた さん 2004年 08月 04日 21時 08分 25秒

>管理人むたぐち さん 2004年 08月 02日 15時 43分 14秒
>CDOを使ってmhtファイルを作成する方法。Win2000/XPで動作。

こういうのもあります。

Library MIMEEDIT
C:\WINDOWS\SYSTEM\INETCOMM.DLL
Microsoft MIMEEDIT Type Library 1.0

set MimeEdit=createobject("OutLookExpress.MimeEdit")
msgbox typename(MimeEdit) 'IMimeEdit

ここまで。例によって、WSHからは、使えないようです。

IEに貼り付けると、HTMLの編集画面が出てきます。

Set ie=CreateObject("InternetExplorer.Application")
ie.Visible=True
ie.Navigate "res://mshtml.dll/blank.htm"
Do While ie.Busy Or ie.ReadyState<>4
WScript.Sleep 100
Loop
Set MimeEdit=ie.Document.CreateElement("object")
MimeEdit.classid="CLSID:1C82EAD9-508E-11D1-8DCF-00C04FB951F9"
call ie.document.body.insertadjacentelement("AfterBegin",MimeEdit)
MimeEdit.width="100%"
MimeEdit.height="100%"
MimeEdit.editmode=True
MimeEdit.src="http://〜〜〜/index.shtml"
Wscript.Echo "MessageSource:",MimeEdit.MessageSource
ie.Quit
Wscript.Quit

MessageSourceを取り出すとMHT形式のようです。

今のところ、使い道が分かりません。
自作メーラにHTMLメール編集機能を付けようっていうひとには使えるかも ?
そんなひとはいないって。。。

ほげ さん 2004年 08月 04日 16時 21分 40秒

通りすがりの素人です。
もっとスマートにできるのかもしれません・・。

Const TARGET_DIR="d:\test"
Const SERCH_WORD="A"

Dim Fs, objFiles, objFile, cnt

Set Fs = WScript.CreateObject("Scripting.FileSystemObject")
Set objFiles=Fs.GetFolder(TARGET_DIR).Files

cnt=0
For Each objFile in objFiles
If InStr(SERCH_WORD, objFile.Name)=1 Then
cnt=cnt+1
End If
Next

MsgBox cnt

あん さん 2004年 08月 03日 18時 00分 02秒

はじめまして。初心者なので教えてください。
あるフォルダの中にAで始まるファイルが何個あるかを調べて、
その後そのファイルはすべて削除したいのですが。
削除はFs.DeleteFile("d:\test\A*.*")でできると思うのですが
Aで始まるファイルが何個あるのかはどうやって調べたらよいのでしょうか?
簡単なことを質問しているのだと思うのですが、どうかよろしくお願いします。

なっちか さん 2004年 08月 03日 17時 29分 24秒

下のリンク見つけました!
失礼しました。。。

なっちか さん 2004年 08月 03日 16時 00分 17秒

こんにちは。
ここに来るのは2回目です。
また画像がビットマップにしか保存できなくなってしまいました…JJ
魔界の仮面弁士さん、またあのページのURLを教えていただけませんか?

管理人むたぐち さん 2004年 08月 02日 16時 52分 50秒

前ページの返信です。


To: 魔界の仮面弁士 さん

> また、WMIは、95/98等には標準ではサポートされていないので、別途インストールが必要となりますね。

ちなみにWinMEは9x系のくせに、なぜかWMIが標準で入っていたりしますね。


To: ちゃきちゃっき〜 さん

> なのですが、vbs起動時にIEが起動していないと
> 行:16
> エラー:起動されたオブジェクトはクライアントから切断されました
> コード:80010108
> ソース:(null)
> のエラーで落ちる場合があります。

何となくですが、
For Each objWindow In objShell.Windows
の中で、IEのオブジェクトを終了させる処理を入れているからという気がします。
一度別の配列にobjShell.Windowsの各要素を格納してから、
その後ポップアップかどうかを判定し、ポップアップなら終了させる処理を
入れてみてはいかがでしょうか。


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

> view-source:〜を使って、VBScriptからWebページを保存する方法。

view-source:した場合、エディタの引数にキャッシュのパスが渡される
ところがポイントですね。
キャッシュをコピーするので無駄がなく効率的だと思います。

他にもっと簡単にキャッシュのパスを取得する方法があれば、
レジストリを弄る必要はなくなるわけですが、何かありませんかね。


To: あんのうん さん

> HTAでスクリーンセーバを作ってみました。

HTAでタイトルバーを隠して、サイズをディスプレイと同じにすると
まさにスクリーンセーバーだなーと常日頃から思ってたんですけど、
本物のスクリーンセーバーに仕立てたわけですね。
HTA部分を入れ替えて実行できるのがいい感じです。
HTML+JavaScript/VBScriptでスクリーンセーバーを記述できるわけですから。

ところでWikiのアップローダーにあげられていたファイルがいくつか
消えてますね。
添付ファイルは誰でも削除できる上、バックアップが効かない
みたいなので、ファイルは各自で取って置いてください。
消えてるようなら、気づいた方(でファイルを持っている方)が
再アップをお願いします。
私もできる限り保存しておくようにします。
Wikiはこのあたりの管理が難しいなあ…。


To: tetsu さん

> Windows2000 SP3 VB6.0の環境で
> CDO(Collaboration Data Objects)を使ったメール自動送信プログラムを作成しています。
> LAN接続により、STMPサーバーに接続する場合はメール送信できるのですが、
> ダイヤルアップ接続でメール送信しようとすると、自動ダイアルアップ接続されないため、メールが送信されません。

そこまで融通は利かないということだと思います。
ダイヤルアップするためのコントロールを使うか、
そういうルーチンを組み込むかするしかないのではないでしょうか?

管理人むたぐち さん 2004年 08月 02日 15時 43分 14秒

2chのあるスレッドを見ていて発見したんですが、
CDOを使ってmhtファイルを作成する方法。Win2000/XPで動作。

Set CDOMsg=WScript.CreateObject("CDO.Message")
Const adSaveCreateOverWrite = 2
CDOMsg.CreateMHTMLBody "http://www.roy.hi-ho.ne.jp/mutaguchi/wsh/"
CDOMsg.GetStream.SaveToFile "C:\test.mht",adSaveCreateOverWrite

なんとこれだけで出来てしまいます。
元はDelphiのコードだったんですがVBSにしました。
http://delphi.about.com/library/weekly/aa062904a.htm

課題としては、HTMLのタイトルを取得してファイル名を自動生成
すること、ですね。

ふみふみ さん 2004年 08月 02日 09時 39分 31秒

> 管理人むたぐち さん 2004年 07月 25日 15時 16分 01秒
>
> > url2htm.vbs
>
> お二人が改良された分をマージして再アップロードしました。

Version Update 確認させて頂きました。
ハンドルネームのクレジットも入れて頂いて有難うございます。
良い思い出になりました。(笑)


> vbCrLf & _
>
> Sanitize(Link.TargetPath)
> Sanitize(FolderItem.Path)
> Sanitize(str)
> Sanitize(FolderItem.path)
>
> Function Sanitize(ByVal strText)
> strText = Replace(strText,"&","&amp;")
> strText = Replace(strText,">","&gt;")
> strText = Replace(strText,"<","&lt;")
> strText = Replace(strText,"""","&quot;")
> Sanitize = strText
> End Function

文字化けの対策には効率が良さそうなので、個人利用しているものと差し替えてみました。
末永く愛用させて頂きたく存知ます。


> 今回のurl2htm.vbsでは、meta要素をそもそも記述しないことにしました。
> Unicode(UTF-16)だと、ブラウザがエンコード形式を間違える可能性は
> 皆無のはずなので…。

そうですね、これを利用するブラウザは IE のはずなので、IE 以外は考慮しなくて良いのかも。(笑)



> ばんのしゃーによかばんた さん 2004年 07月 25日 16時 59分 46秒

こんにちは、いつもご指導有難うございます。

> IEの、名前を付けて保存、でunicodeを選ぶと、
> <META http-equiv=Content-Type content="text/html; charset=unicode">
> と書き出すようです。

あ、本当ですね。
それで、
<META http-equiv=Content-Type content="text/html; charset=unicode">
と安易に記述してしまったのかも知れません。(謎)


> ですから、最初から、言ってますように、
> (中略させて頂きました)
> この二つの選択肢の中から、SJISの方を選べばよいのですが。。。

あ、そうでした。(笑)
Set ts=fso.CreateTextFile(strPath,True)
に変更して利用することにしました。

皆様には、重ね重ねご指導を頂きまして有難うございます。
今後とも、宜しくご指導を賜りたく重ねてお願いを申し上げます。

Return