HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0114
ぽちょむきん4分の1くらいの確率で内部エラー(39)が発生します8解決


ぽちょむきん

リンク

2015/1/14(Wed) 00:17:54|NO.66944

皆様明けましておめでとうございます。
今年もどうぞよろしくお願いします。

m(__)m

以前WEB情報を直接読み取る方法として以下のソースを教えて頂きました。

newcom ie, "InternetExplorer.Application",0,0
//IEを表示しない
ie("Visible")=0
URL = "http://yahoo.co.jp"
ie->"Navigate" URL
repeat
wait 10
if ie("readyState") = 4 : break
loop

pDoc = ie("document")
pBody = pDoc("body")
src = pBody("innerHTML")

mes src

delcom pBody
delcom pDoc
ie->"Quit"
delcom ie

こちらをexeファイルにしたところ、4分の1くらいの確率でエラーが発生してしまいます。

#Error 39
-->内部エラーが発生しました(39)

直後に続けて起動しようとすると同じエラーが続きますが
数十秒ほど待つと正常に起動します。

エラーを無くす(または頻度を下げる)には、どのように対処すればよろしいでしょうか?



この記事に返信する


pizza

リンク

2015/1/15(Thu) 04:51:53|NO.66954

ieやpBody等のCOMオブジェクトをvaruseで有効なものかチェックしてみては?



pizza

リンク

2015/1/15(Thu) 04:52:36|NO.66955

↓IEを起動しない方法。
以前もここに貼ったモジュールですが、使えるかと。


#module #define IID_IDispatch "{00020400-0000-0000-C000-000000000046}" #define IID_IPersistFile "{0000010b-0000-0000-C000-000000000046}" #usecom IPersistFile IID_IPersistFile #comfunc IPersistFile_Load 5 wstr, int #uselib "urlmon.dll" #func CreateURLMoniker "CreateURLMoniker" int, wstr, int #uselib "ole32.dll" #func BindMoniker "BindMoniker" comobj, int, int, int #func IIDFromString "IIDFromString" wstr, var #uselib "kernel32.dll" #func GetFullPathName "GetFullPathNameA" sptr, int, int, int #deffunc loadHTML var v, str url // v = Documentオブジェクトを受け取る変数 // url = ロードするURL(PATH) dimtype doc, vartype("comobj"), 1 dimtype moniker, vartype("comobj"), 1 dim iid, 4 _url = url p = "" getstr p, _url, 0, ':' if p == "http" { CreateURLMoniker 0, url, varptr(moniker) if varuse(moniker) == 0 : return // モニカ作成失敗 IIDFromString IID_IDispatch, iid BindMoniker moniker, 0, varptr(iid), varptr(doc) delcom moniker } else { exist url if strsize != -1 { newcom doc, "htmlfile" if varuse(doc) { sdim fullpath, 260 pfilepart = 0 GetFullPathName url, 260, varptr(fullpath), varptr(pfilepart) IPersistFile_Load doc, fullpath, 0 } } } v = doc if varuse(doc) { if doc("readyState") == "uninitialized" : delcom v delcom doc } return #global // 使い方 loadHTML 変数, "URL" /* loadHTML objDoc, "http://yahoo.co.jp" if varuse(objDoc) == 0 : dialog "HTMLDocument取得失敗" : end repeat wait 10 if objdoc("readyState") == "complete" : break loop objBody = objDoc("body") if varuse(objBody) == 0 : delcom objDoc : end buf = objBody("innerHTML") mes buf delcom objBody delcom objDoc stop */



ぽちょむきん

リンク

2015/1/15(Thu) 05:55:13|NO.66956

pizzaさん

ありがとうございます。
「IEを起動しない」のであれば、起動時のエラーは回避できそうですね!
サンプルはうまく行きました。

ただ、起動時の接続(ファイルチェック)後、続けて別のHTMLファイルを表示したいので、可能であれば、IEを復帰させる(または別の方法でWEBページを表示させる)にはどうすればいいでしょうか?



pizza

リンク

2015/1/15(Thu) 07:48:55|NO.66958

ん〜と、処理の流れがちょっとわからないですね。
↑のモジュール命令で別のURLも読めますが、それではダメでした?

とりあえず、元のスクリプトにvaruse入れると↓みたいな感じになります。

newcom ie, "InternetExplorer.Application",0,0 if varuse(ie) == 0 : end //IEを表示しない ie("Visible")=0 URL = "http://yahoo.co.jp" ie->"Navigate" URL repeat wait 10 if ie("readyState") = 4 : break loop pDoc = ie("document") if varuse(pDoc) { pBody = pDoc("body") if varuse(pBody) { src = pBody("innerHTML") delcom pBody } delcom pDoc } ie->"Quit" delcom ie mes src



774

リンク

2015/1/15(Thu) 18:34:58|NO.66963

ie->"Quit"
delcom ie
辺りが少し怪しい感じがします。
・ie->"Quit"の処理完了前にdelcomして参照元が見つからずエラー39
・COM内では暫く探索を続けるため起動できない
だとすれば辻褄は合いそうです。

delcomするならQuitは省いて良さそうな気もしますが、
メモリリークしちゃったらごめんなさい。

ie->"Quit"を使うのであれば、
Navigateの様に完了まで待機させてみては如何でしょうか。



ぽちょむきん

リンク

2015/1/15(Thu) 23:20:50|NO.66966

pizzaさん

追加のサンプルありがとうございます。
これから本体とうまく融合させてみます!


774さん

ie->"Quit"
delcom ie
を消すだけでいいんでしょうか?
たしかに消しても普通につながりました。

>ie->"Quit"を使うのであれば、
>Navigateの様に完了まで待機させてみては如何でしょうか。

もともと貰いモノなので、「ie->"Quit"」がどういう働きをするのかもわかっていません(^^;)
具体的にはどのように使えばいいんでしょうか。



774

リンク

2015/1/16(Fri) 18:55:46|NO.66971

>ie->"Quit"
すみません、axobjによる生成と混同していました。
IEブラウザを閉じる為にむしろ必要みたいです。

 newcom ie :IEブラウザを起動し操作
 axobj ie :IEオブジェクトをHSPウィンドウ内に作成
 ie->"Quit" :IEブラウザを閉じる
といった感じの様ですので、Quitが無い場合は非表示状態で居座り続けることになります。
よって前回の発言は的外れです、失礼致しましたm(_ _)m


他にエラー発生しそうな箇所としては待機処理辺りでしょうか。
>http://d.hatena.ne.jp/language_and_engineering/20100410/p1
だそうなので、body取得等でエラーの可能性はありそうです。

pizza様のスクリプトの待機処理をCOMイベントに置き換えた上で
エラー箇所特定用の仕込みをうざい位に施してみました。

sdim eLog,$10000 : onerror *put_log ;エラー箇所特定用の仕込み newcom ie, "InternetExplorer.Application",0,0 :eLog+="COM生成\n";;;; if varuse(ie) == 0 : end comevent pEv,ie,"{34A715A0-6587-11D0-924A-0020AFC7AC4D}",*ie_event eLog+="COMイベントハンドラ登録";;;; //IEを表示しない ie("Visible")=0 :eLog+="IE非表示化\n";;;; URL = "http://yahoo.co.jp" ie->"Navigate" URL :eLog+="ページ移動\n";;;; dim fComp ;COMイベント判定用 repeat ;COMイベントでの待機 wait 10 if fComp : break loop eLog+="移動完了\n";;;; pDoc = ie("document") if varuse(pDoc) {eLog+="document取得\n";;;; pBody = pDoc("body") if varuse(pBody) {eLog+="body取得\n";;;; src = pBody("innerHTML") :eLog+="src取得\n";;;; delcom pBody :eLog+="body削除\n";;;; } delcom pDoc :eLog+="document削除\n";;;; } ie->"Quit" :eLog+="ブラウザ終了\n";;;; delcom ie :eLog+="COM削除\n";;;; mes src :eLog+="src表示\n";;;; stop *ie_event if comevdisp(pEv) == 259 : fComp++ ;DISPID_DOCUMENTCOMPLETE return *put_log eLog=strf("== ERROR #%d : line %d ==\n",wparam,lparam)+eLog bsave "error.log",eLog,strlen(eLog) : dialog eLog end:end:end:end
COM自体あまり使った事が無い為comeventの使い方が合ってるかは疑問です。



ぽちょむきん

リンク

2015/1/18(Sun) 11:40:12|NO.66991

pizza さん
774 さん

おかげ様でうまく行きました。
ありがとうございました。



ONION software Copyright 1997-2021(c) All rights reserved.