2017年6月1日木曜日

[UWSC]firefoxやchromeを操作できるか試してみる関数 [自作関数]

UWSCという開発ソフトを使って作り上げる作業を実際にやって見せみるカテゴリ。準備した自作関数や使い方、トラブルを記事にしていきます。得るものがあれば幸いです。
現在のブラウザシェアトップのfirefoxやchromeをUWSCから操作できるのかチャレンジします。今回はその準備として、起動、ウィンドウ位置取得、終了させてみました。

記事の内容

○firefoxやchromeを制御する関数群(準備一)
ブラウザのIDを調べる関数
ブラウザに準備をさせる関数
ブラウザを起動する関数
ウィンドウの範囲を得る関数
ブラウザを終了させる関数

スマホで閲覧されている方へ
このブログは画面横幅を広くしてあります。スマホ解像度での閲覧は厳しいと思いますので、ウェブバージョンへどうぞ。

現在のブラウザのシェアはfirefoxやchromeが非常に大きいです。ですが、UWSCはCOMオブジェクト形式を採用しているブラウザ(IEやSleipnir)でないとIDやパスワードをセットする等のアクセスができません。また、取得できるデータが限定されます。
操作のしやすさはIEやSleipnirなのですが、そんなブラウザ使いたくありません。わざわざUWSCでfirefoxやchromeを操作するのはよい選択肢とは思えませんが、敢えてイバラの道を進んでみます…。

【ご注意】今後、うまく行かず粉砕されるかもしれません。参考程度にどうぞ。

------追記(FireFoxの制御に関して)
2017年10月初にFireFoxv56、11月中にv57Quantum(←爆速です)がリリースされました。
少し触ってみたところアクセスビリティの仕様が変更になっているようで、現状のUWSCでは制御できないようです。これはUWSCの対応待ちとなります。(対応するかどうかわかりませんが)


ブラウザのIDを調べる関数

まず、グローバル変数を1つ定義します。(グローバルである必要はないのですが各関数から頻繁に参照すると思うので。)
1   PUBLIC brwz="firefox"//or"chrome"
1行目1   PUBLIC brwz="firefox"//or"chrome"
変数brwz:ブラウザ名を記憶するグローバル変数。

UWSCでは、制御対象となるアプリケーションのIDを指定して操作の指令を出します。そこで、ブラウザのIDを調べるための関数を準備しておきます。
bid()関数
1
2
3
4
5
6
7
8
9
10
11
FUNCTION bid(brwz)
      SELECT brwz
      CASE "firefox"
            RESULT=GETID("Mozilla Firefox","MozillaWindowClass")
      CASE "chrome"
            RESULT=GETID("Google Chrome","Chrome_WidgetWin_1")
            //RESULT=GETID("Google Chrome","Chrome_WidgetWin_1",-1)
      DEFAULT
            RESULT=-1
      SELEND
FEND
関数プログラム説明(○⇒:成り立つ場合、×⇒:成り立たない場合)
1,11行目1
11
FUNCTION bid(brwz)
FEND
bid(brwz)関数宣言
ブラウザのIDを調べる関数。
2,10行目2
10
      SELECT brwz
      SELEND
ブラウザの種類による分岐。
3,4行目3
4
      CASE "firefox"
            RESULT=GETID("Mozilla Firefox","MozillaWindowClass")
ブラウザが"firefox"だった場合、
4行目のようにしてIDを取得する。
5~7行目5
6
7
      CASE "chrome"
            RESULT=GETID("Google Chrome","Chrome_WidgetWin_1")
            //RESULT=GETID("Google Chrome","Chrome_WidgetWin_1",-1)
ブラウザが"chrome"だった場合、
6行目のようにしてIDを取得する。
※UWSCのFAQには、7行目のようにするよう記述があるが、うちの環境(WindowsXP、Windows7)では動かなかったので。
8,9行目8
9
      DEFAULT
            RESULT=-1
それ以外のときは、-1を返す。




ブラウザに準備をさせる関数

既にブラウザが立ち上がっている場合には別窓を立ち上げるのではなく、元々の窓をアクティブな状態に戻すのがよいと思いますので、アクティブに戻す関数を準備します。
bprep()関数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
FUNCTION bprep()
            id=bid(brwz)
      IF (id<>-1)
         IF STATUS(id,ST_ICON)//ウィンドウが最小化かチェック
            CTRLWIN(id,NORMAL)//表示を通常にする
         ENDIF
         IF !STATUS(id,ST_ACTIVE)//ウィンドウが非アクティブかチェック
            CTRLWIN(id,ACTIVATE)//アクティブにする
         ENDIF
            //RESULT=1
            RESULT=id//Ver.20170615で修正
      ELSE
            //RESULT=0
            RESULT=-1//Ver.20170615で修正
      ENDIF
FEND
関数プログラム説明(○⇒:成り立つ場合、×⇒:成り立たない場合)
1,16行目1
16
FUNCTION bprep()
FEND
bprep()関数宣言
ブラウザが非アクティブ状態、最小化状態時に、アクティブに戻す関数。
2行目2            id=bid(brwz)
作成したbid関数を使用してブラウザのIDを変数idに代入。
3,12,15行目3
12
15
      IF (id<>-1)
      ELSE
      ENDIF
変数idの値により条件分岐。
○⇒(立ち上がっている場合)
 4~11行目へ。
×⇒(立ち上がっていない場合)
 13、14行目へ。
4~11行目4
5
6
7
8
9
10
11
         IF STATUS(id,ST_ICON)//ウィンドウが最小化かチェック
            CTRLWIN(id,NORMAL)//表示を通常にする
         ENDIF
         IF !STATUS(id,ST_ACTIVE)//ウィンドウが非アクティブかチェック
            CTRLWIN(id,ACTIVATE)//アクティブにする
         ENDIF
            //RESULT=1
            RESULT=id//Ver.20170615で修正
(立ち上がっている場合)
変数idのアプリ(つまりブラウザ)のステータスによる処理。
STATUS(id,パラメータ)はidのアプリの状態を得るUWSCの標準関数。
 ST_ICON …対象アプリが最小化されているかどうか
 ST_ACTIVE …対象アプリがアクティブかどうか(7行目ではNOTを意味する ! をつける)
 上記の結果は"True"or"False"のboolean型で返される。 
CTRLWIN(id,パラメータ)はidのアプリを操作するUWSCのコマンド。 
 NORMAL …対象アプリを通常の表示にする
 ACTIVATE …対象アプリをアクティブにする

戻り値として変数idを返す。(仕様変更いたしました。2017年6月15日)
13,14行目13
14
            //RESULT=0
            RESULT=-1//Ver.20170615で修正
(立ち上がっていない場合)
戻り値として-1を返す。(仕様変更いたしました。2017年6月15日)




ブラウザを起動する関数

ブラウザを起動するための関数です。現在のところブラウザアプリケーションのパスを指定するしか起動方法が見つかりませんでした。パス指定が不要な方法あったら教えてください。m(_ _)m
bstrat()関数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
FUNCTION bstart(path)
      IF (bid(brwz)=-1)//-1:立ち上がっていない
            id=EXEC(bpathfix(path))//exeの起動
         IF STATUS(id,ST_PATH)=""//idの絶対パス、見つからなかった場合は空白が返ってくる模様
            MSGBOX("無効なパスが指定されました。")
            RESULT=0
         ELSE
            RESULT=1
         ENDIF
      else//既に立ち上がっている
            bprep()
            RESULT=1
      ENDIF
FEND
関数プログラム説明(○⇒:成り立つ場合、×⇒:成り立たない場合)
1,14行目1
14
FUNCTION bstart(path)
FEND
bstart(path)関数宣言:
引数path:ブラウザソフトのパス。
2,10,13行目2
10
13
      IF (bid(brwz)=-1)//-1:立ち上がっていない
      else//既に立ち上がっている
      ENDIF
作成したbid関数の戻り値により条件分岐。
○⇒(立ち上がっていない場合)
 3~9行目へ。
×⇒(立ち上がっている場合)
 11、12行目へ。
3~9行目3
4
5
6
7
8
9
            id=EXEC(bpathfix(path))//exeの起動
         IF STATUS(id,ST_PATH)=""//idの絶対パス、見つからなかった場合は空白が返ってくる模様
            MSGBOX("無効なパスが指定されました。")
            RESULT=0
         ELSE
            RESULT=1
         ENDIF
(立ち上がっていない場合)
EXEC(p)は変数p:パスを与えると指定された実行ファイル(.exe)を起動するUWSCの標準関数。戻り値はそのアプリケーションのID。
3行目のEXEC関数の引数にあるbpathfix関数は下にある自作関数。(chromeの場合起動オプションを付ける必要があるらしいので、変数pathを修正する関数。)

立ち上げた(つもり)のアプリのステータスによる条件分岐。
STATUS(id,パラメータ)はidのアプリの状態を得るUWSCの標準関数。
 ST_PATH …対象アプリの絶対パス。
○⇒(指定のパスの実行ファイルが見つからなかった場合
 6行目へ。エラーを表示し、戻り値として0を返す。
×⇒(見つかった場合)
 8行目へ。戻り値として1を返す。
11,12行目11
12
            bprep()
            RESULT=1
(立ち上がっている場合)
作成したbprep関数でアクティブ状態に戻し、戻り値として1を返す。


UWSCのFAQにはchromeを操作する場合起動オプションが必要とあります。現在は使用していないのですが、起動時に与えた引数pathを修正する関数として以下を準備しておきます。

⇒問題が出ました。起動オプションなしだとchromeからITM_LINKが取得できません。使用するように修正。(2017年7月22日修正)

bpathfix()関数
1
2
3
4
5
6
7
8
9
10
11
12
13
FUNCTION bpathfix(path)
      SELECT brwz
      CASE "firefox"
            RESULT=path
      CASE "chrome"
         //Chromeの場合は、起動オプションを付けておかないといけない…らしい。
         //必要な起動オプションaccessibilityをOnにする文字列を追加
         
   RESULT=path+" --force-renderer-accessibility --process-per-tab --new-window http://www.google.co.jp/"
        
//RESULT=path
      DEFAULT
            RESULT=path
      SELEND
FEND
関数プログラム説明(○⇒:成り立つ場合、×⇒:成り立たない場合)
1,13行目1
13
FUNCTION bpathfix(path)
FEND
bpathfix(path)関数宣言:
作成したbatart関数に渡された引数pathに起動オプションを付加するための修正用の関数。
2,12行目2
12
      SELECT brwz
      SELEND
グローバル変数brwzによる条件分岐。
3,4行目3
4
      CASE "firefox"
            RESULT=path
ブラウザが"firefox"だった場合、
与えられた引数そのままを戻り値として返す。
5~9行目5
6
7
8
9
      CASE "chrome"
         //Chromeの場合は、起動オプションを付けておかないといけない…らしい。
         //必要な起動オプションaccessibilityをOnにする文字列を追加
         
   RESULT=path+" --force-renderer-accessibility --process-per-tab --new-window http://www.google.co.jp/"
        
//RESULT=path
ブラウザが"chrome"だった場合、
UWSCのFAQには5~7行目にあるように起動オプションが必要とあります。ですが、現在はそれらをコメントアウトし、9行目のように与えられた引数そのままを戻り値として返してあります。※問題が出たときに修正します
⇒問題が出ました。9行目を使用するとchromeからITM_LINKが取得できません。9行目をコメントアウトし、8行目を使用するように修正。(2017年7月22日修正)
10,11行目10
11
      DEFAULT
            RESULT=path
それ以外だった場合、
与えられた引数そのままを戻り値として返す。




ウィンドウの範囲を得る関数

画像検索などのための検索範囲として頻繁に使用すると想定されるので、左上と右下座標を得る関数を準備しておきます。
bset()関数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FUNCTION bset()
            bprep()
            SLEEP(0.2)
            DIM A[3]
      IF bid(brwz)<>-1
            id=bid(brwz)
            A[0]=STATUS(id,ST_X)//X座標を取得
            A[1]=STATUS(id,ST_Y)//Y座標を取得
            A[2]=
A[0]+STATUS(id,ST_WIDTH)//幅を取得し右下X座標を求める
            A[3]=
A[1]+STATUS(id,ST_HEIGHT)//幅を取得し右下Y座標を求める
      ELSE
            A[0]=0
            A[1]=0
            A[2]=G_SCREEN_W
            A[3]=G_SCREEN_H
      ENDIF
            RESULT=SLICE(A,0,LENGTH(A)-1)
FEND
プログラム説明(○⇒:成り立つ場合、×⇒:成り立たない場合)
1,18行目1
18
FUNCTION bset()
FEND
bset()関数宣言:
ブラウザソフトのウィンドウの範囲(左上と右下座標)を得る関数。
2,3行目2
3
            bprep()
            SLEEP(0.2)
作成したbprep()関数で、ブラウザをアクティブにします。
瞬時に反応できないことも考慮し、0.2秒間を待ち時間とします。
4行目4            DIM A[3]
使用する配列変数の宣言
ウィンドウの四隅の座標を代入するために使用します。
5,11,16行目5
11
16
      IF bid(brwz)<>-1
      ELSE
      ENDIF
作成したbid関数の戻り値により条件分岐
○⇒(立ち上がっている場合)
 6~10行目へ。
×⇒(立ち上がっていない場合)
 12~15行目へ。
6~10行目6
7
8
9
10
            id=bid(brwz)
            A[0]=STATUS(id,ST_X)//X座標を取得
            A[1]=STATUS(id,ST_Y)//Y座標を取得
            A[2]=
A[0]+STATUS(id,ST_WIDTH)//幅を取得し右下X座標を求める
            A[3]=
A[1]+STATUS(id,ST_HEIGHT)//幅を取得し右下Y座標を求める
(立ち上がっている場合)
ブラウザのIDを調べ変数idへ代入。
配列A[0、1]にウィンドウ左上X、Y座標、配列A[2、3]にウィンドウ右下X、Y座標を代入。
STATUS(id,パラメータ)はidのアプリの状態を得るUWSCの標準関数。
 ST_X …対象アプリの左上X座標
 ST_Y …対象アプリの左上Y座標
 ST_WIDTH …対象アプリのウインドウ幅
 ST_HEIGHT …対象アプリのウインドウ高さ
12~15行目12
13
14
15
            A[0]=0
            A[1]=0
            A[2]=G_SCREEN_W
            A[3]=G_SCREEN_H
(立ち上がっていない場合)
ブラウザが立ち上がっていないので、画面全体の値を代入しておく。
以下はUWSCの特殊変数。
 G_SCREEN_W …ディスプレイ画面の幅
 G_SCREEN_H …ディスプレイ画面の高さ
17行目17            RESULT=SLICE(A,0,LENGTH(A)-1)
配列変数A[]を関数の戻り値として返す。




ブラウザを終了させる関数

UWSCで作成するプログラムは大抵の場合非同期だと思います。他のアプリケーションを制御する上で、確実に終了させた後次の処理をするなどの手順が大切なので、終了待ちのルーチンを含んだ終了関数を作成しておきます。
bquit()関数
1
2
3
4
5
6
7
8
9
10
11
12
13
FUNCTION bquit()
            //id=bid(brwz)
            id=bprep()//Ver.20170615で修正
      //if bprep()=1
      IF bprep()<>-1//Ver.20170615で修正
            CTRLWIN(id,CLOSE)//CLOSE2の場合内容破棄で閉じる
         WHILE (bid(brwz)<>-1 and tout_loop(10)=0)//完全に終了するまでの待ち
         WEND
            RESULT=1
      ELSE
            RESULT=0
      ENDIF
FEND
関数プログラム説明(○⇒:成り立つ場合、×⇒:成り立たない場合)
1,13行目1
13
FUNCTION bquit()
FEND
bquit()関数宣言:
ブラウザを終了させる関数。
2,3行目2
3
            //id=bid(brwz)
            id=bprep()//Ver.20170615で修正
ブラウザソフトのIDを取得。(修正しました。2017年6月15日)
4~5,10,12行目4
5
10
12
      //if bprep()=1
      IF bprep()<>-1//Ver.20170615で修正
      ELSE
      ENDIF
作成したbprep関数の戻り値により条件分岐(修正しました。2017年6月15日)
○⇒(立ち上がっている、準備ができている場合)
 6~9行目へ。
×⇒(立ち上がっていない場合)
 11行目へ。
6~9行目6
7
8
9
            CTRLWIN(id,CLOSE)//CLOSE2の場合内容破棄で閉じる
         WHILE (bid(brwz)<>-1 and tout_loop(10)=0)//完全に終了するまでの待ち
         WEND
            RESULT=1
(立ち上がっている、準備ができている場合)
 6行目: ブラウザを終了させる。
  CTRLWIN(id,CLOSE):idのアプリケーションを終了させるコマンド。
 7、8行目: アプリケーションが完全に終了するまでの待ち。
ループ条件は、作成したbid関数でIDが-1になっていること、または、10秒間のタイムアウト。tout_loop(10)はこちらの記事[UWSC]タイムアウト関数(作り直し)で作成した自作関数。
 9行目: 戻り値として1を返す。
11行目11            RESULT=0
(立ち上がっていない場合)
戻り値として0を返す。




動作確認

動作確認プログラム
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
   PRINT "----------firefox"
   brwz="firefox"
   path="C:\Program Files
........\firefox.exe"

bstart(path)
   w_posi=bset()
FOR i=0 TO ubound(w_posi)
   PRINT w_posi[i]
NEXT
SLEEP(2)
bquit()

   PRINT "----------chrome"
   brwz="chrome"
   path="C:\Program Files
........\chrome.exe"

bstart(path)
   w_posi=bset()
FOR i=0 TO ubound(w_posi)
   PRINT w_posi[i]
NEXT
SLEEP(2)
bquit()
動作確認プログラム説明(○⇒:成り立つ場合、×⇒:成り立たない場合)
1,13行目1
13
   PRINT "----------firefox"
   PRINT "----------chrome"
テストするブラウザ名を表示
2~3,14~15行目2
3
14
15
   brwz="firefox"
   path="C:\Program Files
........\firefox.exe"
   brwz="chrome"
   path="C:\Program Files........\chrome.exe"
変数brwzと変数path(ブラウザのパス)を代入します。
変数pathは各環境で異なるので、その環境用に書き換えます。
実際使用する際には、iniファイルなどに記録したものを呼び出して使用することになります。
5,17行目5
17
bstart(path)
bstart(path)
作成したbstart関数にブラウザソフトのパスを渡して、ブラウザを起動します。
6~9,18~21行目6
7
8
9
18
19
20
21
   w_posi=bset()
FOR i=0 TO ubound(w_posi)
   PRINT w_posi[i]
NEXT
   w_posi=bset()
FOR i=0 TO ubound(w_posi)
   PRINT w_posi[i]
NEXT
bset関数からの戻り値(配列)を表示します。
ubound関数というのは、こちらの記事[UWSC]配列の最大要素を返す関数で作成した自作関数です。
10~11,22~23行目10
11
22
23
SLEEP(2)
bquit()
SLEEP(2)
bquit()
2秒間の休止の後、bquit関数でブラウザソフトを終了させます。

結果
----------firefox
273
0
1723
1012
----------chrome
240
0
1684
1012

firefox起動→窓座標表示→firefox終了→chrome起動→窓座標表示→chrome終了と動きました。また、それぞれ起動しておき非アクティブ状態のときにテストすると、起動の代わりにアクティブ化を行います。


記事の内容

記事の内容は伝わりましたでしょうか。
○firefoxやchromeを制御する関数群(準備一)
ブラウザのIDを調べる関数
ブラウザに準備をさせる関数
ブラウザを起動する関数
ウィンドウの範囲を得る関数
ブラウザを終了させる関数


【関連記事】
[UWSC]firefoxやchromeの読み込み完了を判定する関数(再)
人気![UWSC]firefoxやchromeを実際にUWSCで操作してみた
人気![UWSC]firefoxやchrome上のリンクやボタン等を調べる方法
[UWSC]firefoxやchromeの読み込み完了を判定する関数
[UWSC]firefoxやchromeの開かれているタブ数を得る関数
人気![UWSC]firefoxやchromeでタブを作ってページを開く関数


スポンサーリンク



↓ ランキングに参加しています!(Ctrlキーを押しながら) ↓

blogramのブログランキング

ポク太郎の「俺の説明聞いてくれ」 
目次
ポク太郎の「俺の説明聞いてくれ」最キラー記事 IT関連
電気回路やプログラムの記事。元々のメインコンテンツ。
UWSC奮闘記
プログラミングのできる子に
デジタルの世界って
映画・ドラマ・芸能
ハリウッドが主のエンターテイメントの記事。最近は似顔絵多し。
戦士の息抜き
落書き漫画
数コマ漫画とアホ漫画。結局最大コンテンツに。
物思いに耽る
今日の数学
アホの雑記
取りとめもなく好き勝手に書く記事。不本意にも一番人気だったり。
役に立つかも
休むに似たり
好き勝手に書く
ブログ運営
AnalyticsやSerchConsolなどの使い方、アクセスアップに関する話題。
アドセンス関連
他のGoogleツール
その他
アホのもくろみ

免責事項 ホームへ戻る

スポンサーリンク





2 件のコメント :

  1. EXEC("rundll32.exe url.dll,FileProtocolHandler <#DBL>https://www.google.co.jp/?gws_rd=ssl#spf=1<#DBL>")

    これで通常開くブラウザが開きます

    返信削除
  2. >Unknownさん
    (最近、コメントの返信が上手く動かずこちらで返信いたします。)
    ぉぉ!ありがとうございます!
    それならブラウザのパスを指定、記録せずとも立ち上げられますね。

    自分で理解した上“ブラウザを起動する関数”を改良して記事をアップデートさせて頂きたいと思います。ありがとうございました。

    返信削除