アプリ版:「スタンプのみでお礼する」機能のリリースについて

Cygwin上でRuby言語でInternetExplorerのプログラムを書いています
現在は
1、win32oleでIEを開く
2、プログラム内でhtmlでHPを作成し、IEで開く
3、2をプログラムを終了させるまで続ける

といったものですが、2でURLを習得し、IEで開こうとすると新しい窓(ウィンドウ)が開いてしまいます。新しい窓(ウィンドウ)を開かずに、1で開いたIEを更新させたいです。
または、前に開いたページを閉じて、新たなページを開く。

win32oleやwin32APIなど、Cygwin上のRubyで使える方法ならいいので、ご存知の方いましたらお願いします。

A 回答 (5件)

sleep 1 while @@ie.Busy == true


のsleepが失敗するのは、どこかでsleepメソッドを定義してしまっていることが原因ではないかと思います。

おそらく、
Kernel.sleep 1 while @@ie.Busy == true
を使うことで解決するのではないかと思います。
(Kernel.sleepを再定義していればどうにもなりませんが。)
    • good
    • 0

#3の補足、拝見しました。



どうやら、IEインスタンスを複数生成しているようですね、#3補足のプログラムでは
WIN32OLE.new("InternetExplorer.Application")
が複数回実行されますよ。
initializeメソッドの中とWIN32OLE.newの後ろに
puts "test xxx"
等を入れて、いつ起動するか観察してたりすると、どのようにプログラムが動くか分かるようになると思います。

さて、最初のプログラムの問題点ですが、
IEクラスのインスタンスを複数作る(IE.newを複数実行する)のであれば、
その都度、インスタンス変数である @ie_ole @on も新しく作られますので、意図しない動作となってしまいます。

詳しくは

定数と変数
http://doc.okkez.net/static/191/doc/spec=2fvaria …
クラス変数の概念
http://www.rubylife.jp/ini/class/index8.html
インスタンス変数の概念
http://www.rubylife.jp/ini/class/index4.html
クラス変数・クラスメソッド
http://www.mapee.jp/ruby/post_14.html

等を参照してください。

@ie_ole @on 等のインスタンス変数はnewや補足プログラムのopenを実行すると、古いものとは別に新しいものが生成されます。
@ie_ole と @on をそれぞれ、 クラス変数にの@@ie_ole と @@on に変更すると、インスタンス生成(new)を何回実行しても前の物を参照可能となります。

それと、openメソッドで newを使うことも問題です。
@ie_ole = IE.new(fullscreen = false)
@ie_ole.web(~~~.html)
の部分で、新しくIEのインスタンスを作ってしまうと、インスタンス変数も新しく作成されてそちらを使うので、意図しない動作となってしまいます。
self.web(~~~.html)
のみとするのが意図した動作ではないかと思うのですが。

もくしは、クラスメソッドとして
def IE.open
ie = IE.new(fullscreen = false)
ie.web(~~~.html)
return ie
end
に変更して、IE.openで実行することで意図したメソッドになるかもしれません。(上記のクラスメソッドのリンクを参照してください)

2番目のプログラムも、openは1番目と同じ問題を抱えていて、さらにwebメソッドのie変数はローカル変数(上記定数と変数のリンクを参照してください)となっていて、メソッドを実行するたびに新しく生成されてしまいます。
@on と ie を @@on と @@ie_ole に変更すれば意図した動作に近づくと思います。

この回答への補足

InternetExplorer.new(fullscreen = false)

sleep 1 while @@ie.Busy == true
この2行をなくすことで意図した動作になりました。
sleepの行をなくさないと

`sleep': wrong number of arguments (1 for 0) (ArgumentError)

とでてしまいました。

補足日時:2012/02/07 15:52
    • good
    • 0

#1のプログラムが動くなら、プログラムを修正すれば大丈夫ですね。



説明があいまいだったせいかうまく伝わらなかったようなので、詳細にOLEコマンドの説明をします。
ie変数は、IEクラスのインスタンスと勘違いしないように、ole_ie変数に変更しています。

ole_ie = WIN32OLE.new("InternetExplorer.Application") # ・・・(1)
の部分は、IEの新規ウィンドウを作成するコマンドなので、プログラムを通じて1回だけ実行するようにしましょう。
何度も実行すると、複数のウィンドウが起動します。

ole_ie.visible = true # ・・・(2)
の部分は、(2)で作成したウィンドウを画面に表示するためのものです。これを実行せずにプログラムを終了させると、非表示のIEプロセスが残ることになるので、注意しましょう。(タスクマネージャなどで終了可能です。)

ole_ie.navigate2(url) # ・・・(3)
の部分は、navigate2 メソッドを第2引数を省略して実行すると、(1)で作成したIEウィンドウの既存のタブでブラウズします。

sleep 1 whlle ole_ie.Busy == true # ・・・(4)
の部分は、ブラウザが全てを更新するまで1秒間隔で監視して待機します。

ですので#1 の補足のプログラムで、webメソッドを何回も実行すると、(1)が複数回実行され、navigateメソッド、navigate2メソッドどちらを使用しても、新しいウィンドウで表示してしまいます。

#1補足のIEクラスは別のクラスを継承しているとのことなので、IEインスタンスを複数作ることもあるかもしれないので、(1)(2)の部分を分離して、
補足プログラムIEクラスのwebメソッドを下記のようにしてしまいましょう。
def web(url, ole_ie)
ole_ie.navigate(url)
sleep 1 while ole_ie.Busy == true
end

その上で、プログラムで1回だけ(1)(2)を実行して、ole_ie変数をwebメソッドに渡すようにすればよいのではないかと思います。

付録として、win32oleを使わない方法も紹介
(1) IEの設定でインターネットオプション→タブの設定→他のプログラムからリンクを開く方法を「現在のタブまたはウィンドウ」に設定
(2) 標準のインターネットブラウザをIEに設定
(3) system("explorer ~~.html")
 システムコマンドを使って、IEを呼び出す。
この方法で、IEのタブ設定を変えてしまうとIEの使い勝手が悪くなりますけどね。

この回答への補足

class IE
def initialize(start,fullscreen = false)



end
def IEnew
if @on == nil then
@ole_ie = WIN32OLE.new("InternetExplorer.Application")
@on = 1
end
end

def open
@ole_ie = InternetExplorer.new(fullscreen = false)
@ole_ie.web(~~~.html)
end

def web(url)
self.IEnew
@ole_ie.navigate2(url)
@ole_ie.Visible = true
sleep 1 while @ole_ie.Busy == true
return @ole_ie
end

という感じでやりましたが複数のブラウザが開いてしまいました。
@onはinitializeやその他では定義していない。

また
class IE
  def initialize(start, fullscreen = false)
   ~~
   ~~
  end
  def open
    ie = IE.new(fullscreen = false)
    ie.web(~~~.html)       
  end

def web(url)
    if @on == nil then
ie = WIN32OLE.new("InternetExplorer.Application")
@on = 1
    end
    ie.navigate2(url)
    ie.visible
    sleep 1 while ole_ie.Busy == true
    return ie
  end
end
とやっても結果は同じでした
WIN32OLE.newを1回だけ実行する部分がうまくできてないようです
initializeで@onを定義すると毎回その値が入ってifなどできないし・・・

補足日時:2012/02/07 12:09
    • good
    • 0

補足のプログラム拝見しました。



メインのプログラムがどのようにループしているか分からないので、的外れかもしれませんが、
毎回web("~.html") を実行すると、その都度新しいIEウィンドウが作成されますので、最初に開いたものにnavigate2を実行する必要があります。
2回目以降は web(~)の戻したオブジェクトに対して、navigate2を実行してみてください。
#質問と関係ないですしおせっかいかも知れませんが、補足のIEクラスはWIN32OLEクラスを継承したほうが綺麗になると思いますよ。
class IE < WIN32OLE
def initialize(start, fullscreen = false)
~~
~~
super("InternetExplorer.Application")
self.visible=true
end
def web(url)
self.navigate2(url)
sleep 1 while self.Busy
end
end


的外れなら、#1で私が書いたサンプルを実行してyahoo!がどう開くか、お手持ちのIE8+cygwinで動作するか、教えてもらえませんか?
新しいウィンドウで開くか、既存のウィンドウ(googleが表示)の新しいタブで開くか、既存のウィンドウの既存のタブで開くか?どれでしょうかね?

この回答への補足

#1とは一番最初の回答に記載されていたプログラムでしょうか?
実行した結果正常に新しいタブ・ウィンドウを開くことなくgoogleとyahooを開き閉じることが出来ました。
メインプログラムでは<<EOS
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">~~EOS
を使ってhtml言語でページを作成し、2回目以降の新しいページは同じファイル名で上書きされて作成されます。


またWin32OLEクラスを継承とありますがIEクラスはすでに他のクラスを継承しているので・・・

補足日時:2012/02/06 12:36
    • good
    • 0

win32oleでnavigate2を使えば実現可能ではないでしょうか。



参考URL
IEオブジェクトを操作する(VBScript)
http://www.happy2-island.com/vbs/cafe02/capter00 …

rubyからIEを制御する
http://www.tech-notes.dyndns.org/win32ole/ie_ctr …

リファレンス(英語)
http://nerds-central.blogspot.com/2007/02/intern …

↓goolgleを開いて、5秒後にyahooに切り替え、更に5秒後に終了。
require 'win32ole'

urls = ["http://www.google.co.jp/","http://www.yahoo.co.j …]

ie = WIN32OLE.new("InternetExplorer.Application")
ie.visible = true

urls.each { |url|
ie.navigate2(url)
sleep 5
}
ie.quit

この回答への補足

現在のプログラムとしては
class IE
def initialize(start, fullscreen = false)
~~
~~
end
def open
ie = IE.new(fullscreen = false)
ie.web(~~~.html)        ←ほかのプログラムでhtmlの中身を書き換えてる
end

def web(url)
ie = WIN32OLE.new("InternetExplorer.Application")
ie.navigate(url)
ie.visible
while ie.Busy == true
sleep 1
end
return ie
end
end
となっています。

kanemoto_sさんの答えのように
navigateをnavigate2にしたりと自分なりにいろいろ試しましたがやり方が悪いのかできませんでした

IEのVersionは8
initializeで
private,new,framemergingをtrueにしています(他はデフォルト?)

補足日時:2012/02/04 15:30
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!