IE 8のInternetExplorer comオブジェクトによって無視されるアクティブタブ
-
27-10-2019 - |
質問
これは、.NET 3.5 Winformで実行されるWebシングルサインオンコードです。 IE8が1つのタブを開いている限り、コードはIE6またはIE8で正常に実行されます。問題は、ユーザーが新しいタブ(タブ2,3など)を開き、Webサイト(組織内の内部内部)に移動する場合、以下のコードが実行されるが、IE COM Automationオブジェクトはhtmldocumentを返すことです。タブ2がアクティブタブである場合でも、最初のタブ(タブ1)の場合。 InternetExplorerまたはhtmldocumentクラスにIEタブの参照はどこにも見つかりません。実際、IE Com Automation DocsにはIEタブ関連のドキュメントがほとんどありません。
AutoResetEvent ie2_NavigateCompleteAutoReset;
/// <summary>
/// Given the handle of an Internet Explorer instance, this method performs single sign on to
/// several known web login forms.
/// </summary>
/// <param name="iEFramHandle"></param>
private void WebFormSignOn(int iEFramHandle)
{
foreach (SHDocVw.InternetExplorer ie2 in new SHDocVw.ShellWindows())
{
if (ie2.HWND == iEFramHandle)
{
while (true)
{
Thread.Sleep(100);
if (ie2.ReadyState == SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
{
try
{
mshtml.HTMLDocument doc = (mshtml.HTMLDocument)ie2.Document;
ie2.NavigateComplete2 += new SHDocVw.DWebBrowserEvents2_NavigateComplete2EventHandler(ie2_NavigateComplete2);
ie2_NavigateCompleteAutoReset = new AutoResetEvent(false);
/*Find the username element and enter the user's username*/
mshtml.HTMLInputElement userID = (mshtml.HTMLInputElement)doc.all.item("username", 0);
userID.value = Globals.Username;
/*Find the password element and enter the user's password*/
mshtml.HTMLInputElement pwd = (mshtml.HTMLInputElement)doc.all.item("password", 0);
pwd.value = Globals.GetAppName();
/*Find the submit element/button and click it*/
mshtml.HTMLInputElement btnsubmit = (mshtml.HTMLInputElement)doc.all.item("submit", 0);
btnsubmit.click();
/*Wait up to 5 seconds for the form submit to complete.
This is to prevent this method from being called multiple times
while waiting for the form submit and subsequent navigation from completing.*/
ie2_NavigateCompleteAutoReset.WaitOne(5000);
return;
}
catch (Exception err)
{
Logger.Log(err.ToString(), Logger.StatusFlag.Error, this.ToString(), "WebFormSignOn");
return;
}
finally
{
/*Remove the event handler*/
ie2.NavigateComplete2 -= ie2_NavigateComplete2;
}
}
}
}
}
}
void ie2_NavigateComplete2(object pDisp, ref object URL)
{
ie2_NavigateCompleteAutoReset.Set();
}
解決
IE 8の各タブには、独自のプロセスとハンドルがあることがわかります。元のコードでは、私は常に最初のIEFRAMEからハンドルを取得していました。コード(以下)を変更しましたが、今では機能します。変更は、最初のIEFRAMEハンドルのみを探す代わりに、コードはWebFormsSignOutを呼び出すメソッドをトリガーするURLに一致するLocationUrlも探します。
private void WebFormSignOn(int iEFramHandle,string addressBarText)
{
var shellWindows = new SHDocVw.ShellWindows();
foreach (SHDocVw.InternetExplorer ie2 in shellWindows)
{
if (ie2.LocationURL==addressBarText)
{ //rest of the code (see orignal post)
他のヒント
Internet Explorerには、パブリックタブAPIがありません(新しいフォアグラウンドまたは背景タブへのナビゲーションをターゲットにすることを可能にします)。各ActiveXコントロールまたはBHOは、個々のタブインスタンスに個別にロードされます。 Shellwindowsコレクションから歩いてみようとすると、一般的に機能する可能性は低いです。代わりに、プラグインをホスティングサイト(例:iobjectwithsite :: setSiteがこの情報を伝える)にアクセスする必要があります。これにより、ホスティングタブを決定できます。