Reflexão Terminal Emulator - Integração com o IE
-
03-07-2019 - |
Pergunta
Eu estou tentando implementar alguma integração entre um aplicativo legado correndo na reflexão Terminal Emulator e um aplicativo baseado em navegador em execução no IE.
Eu estou usando scripts anfitrião Iniciada de forma que problemas de manutenção e implantação são isoladas para o aplicativo legado. Todos os scripts serão gerados no aplicativo legado e transmitido para Reflexão utilizando sequências de escape.
Atualmente, estou apto a:
- Lançamento IE
- Definir opções como esconder as barras de ferramentas
- Navegue até uma URL
- Transmitir informações de status de volta para o aplicativo legado
- esperar por um sinal "fechar" a partir do aplicativo legado
- Fechar IE
Aqui está o código VBA para fazer isso:
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = CreateObject("InternetExplorer.Application")
objIE.ToolBar = false
objIE.Navigate("http://www.google.com/")
objIE.Visible = true
Session.Transmit "OK" & CR
Session.WaitForString "CLOSE", 0, rcAllowKeystrokes
objIE.Quit
End Sub
O problema com isto é que o script continua a executar até que ele recebe o comando de fechamento do aplicativo legado.
O que eu quero fazer é usar um script para iniciar o navegador, e outro, quer fechá-lo ou re uso-lo para outra URL. No entanto, eu não tenho sido capaz de encontrar uma maneira de salvar a minha referência a IE através de chamadas de script. Declarando objIE como global fora Sub Main não ajudou. O objeto de sessão persiste entre as chamadas de script, mas não parece ter uma propriedade que eu possa usar para essa finalidade. (Session tem uma propriedade UserData, mas isso é uma String, não um objeto.)
Aqui está um exemplo do que eu gostaria de fazer:
Script 1 - Abra o IE e deixá-la aberta:
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = CreateObject("InternetExplorer.Application")
objIE.ToolBar = false
objIE.Navigate("http://www.google.com/")
objIE.Visible = true
Session.Transmit "OK" & CR
End Sub
Script 2 - Enviar janela original IE para um novo URL
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = FindOriginalIE()
objIE.Navigate("http://www.stackoverflow.com/")
Session.Transmit "OK" & CR
End Sub
Script 3 - Fechar IE
Sub Main
Dim CR as String
CR = CHR$(rcCR)
Dim objIE as Object
Set objIE = FindOriginalIE()
objIE.Quit
Session.Transmit "OK" & CR
End Sub
A parte que eu não consigo entender é como implementar a função FindOriginalIE () usado em Scripts 2 e 3.
Eu tentei usar GetObject () em vez de CreateObject (), mas que me levou a lugar nenhum. GetObject () não irá abrir uma nova janela do IE, ou encontrar um existente. Eu suspeito que isso é porque eu estou correndo sob Citrix, mas eu não tenho certeza.
As minhas únicas ligações agora estão a tentar usar hWND do IE para se reconectar à janela original, ou para usar DDE em vez de OLE. Eu não tive muita sorte com qualquer um desses no entanto, principalmente por causa da falta de documentação.
Então, minhas perguntas são:
- É o que eu estou tentando fazer possível usando OLE? Ou seja, há uma maneira a persistir o meu punho para IE através acolhimento chamadas de script iniciado?
- Devo esperar GetObject () para trabalho, ou isso é um beco sem saída?
- É possível utilizar a API Win32 em um host de script iniciado para re-connect para IE usando hWND?
Todos os links para artigos relacionados, código de exemplo, ou outras idéias são muito apreciados.
Solução
AFAIK GetObject não é apenas suportada para o objeto InternetExplorer. No entanto, este não é o fim :) Entre muitas outras maneiras você pode puxar para fora da coleção de janelas de shell32. Para o código de exemplo (adaptado de código no link acima) para funcionar, você precisa definir uma referência para o seguinte:
- Microsoft Internet Controls
- Microsoft HTML Object Library
- Controles Microsoft Shell e Automação
Public Sub RunMeFirst()
Dim objIE As SHDocVw.InternetExplorer
Set objIE = New SHDocVw.InternetExplorer
objIE.Visible = True
objIE.navigate "http://www.google.com/"
Do Until objIE.readyState = READYSTATE_COMPLETE
DoEvents
Loop
End Sub
Public Sub RunMeSecond()
Dim objIE As SHDocVw.InternetExplorer
Dim doc As MSHTML.HTMLDocument
Set objIE = GetIEByURL("http://www.google.com/")
Set doc = objIE.document
MsgBox doc.body.innerText
End Sub
Private Function GetIEByURL(ByVal URL As String) As SHDocVw.InternetExplorer
Dim objShell As Shell32.Shell
Dim objExplorer As Shell32.ShellFolderView
Dim obj As Object
Set objShell = New Shell
For Each obj In objShell.Windows
If TypeOf obj Is SHDocVw.InternetExplorer Then
If StrComp(obj.LocationURL, URL, vbTextCompare) = 0& Then
Exit For
End If
End If
Next obj
Set GetIEByURL = obj
End Function
Eu acho que talvez valha a pena discutir o que você está tentando realizar embora. Roboting IE é uma abordagem muito kludgey (da qual sou frequentemente culpado), mas pode haver um melhor, menos recursos forma intensiva.