Le contrôle WebBrowser ne répond pas à InvokeMember ("cliquer")

Après avoir passé 5 jours de ma vie, je vais renoncer à cela, mais je suis en train de consulter les experts une fois auparavant.

J'ai un contrôle WebBrowser qui charge une page Web et je scelle de façon programmée son contenu. En cliquant sur un élément de menu particulier dans la page, vous ouvrez la boîte de dialogue Ouvrir fichier lorsque vous avez terminé dans IE (ou tout autre navigateur). Mais en cliquant sur le même bouton dans le contrôle WebBrowser en utilisant InvokeMember() apparemment, il ne fait rien, peu importe quoi. J'ai examiné plusieurs questions telles que la configuration des fonctionnalités du navigateur pour m'assurer que mon contrôle se comporte exactement comme IE, mais cela n'a pas réussi.

Je suis allé jusqu'à inspecter la fonction javascript actuelle que le bouton s'exécute derrière la scène et l'appeler manuellement à l'aide de HtmlDocument.InvokeScript() mais ne pouvait pas le faire car la fonction sous-jacente prend un argument de type MouseEvent (l'événement de clic en fait) Et je ne sais pas comment puis-je créer cet objet dans C #.

Une autre approche était de mettre l'accent sur ce bouton particulier, puis d'essayer SendKeys , mais cela ne fonctionnera pas car le contrôle WebBrowser n'est pas visible. C'est juste une instance en mémoire. Pour être plus précis, le WebBrowser

MODIFIER

Sur la demande d'un lecteur, voici le code simple que j'utilise pour trouver l'élément:

 var MyButton = WB.Document.GetElementById("processfilelink"); 

processfilelink est une balise d'ancrage ( <a href='#' ... > ) et j'ai confirmé que cet élément existe réellement dans le corps du document. La page Web utilise la fonction delegate de jQuery pour lier l'événement de click cet ancrage à la fonction cible. Après avoir trouvé le bouton, j'appelle InvokeMember() comme ceci:

 MyButton.InvokeMember("click"); 

Remarque: Je vois également les liaisons pour les événements mousedown, mouseup et focus dans le code de la page. Je m'attends à ce que tous ces événements InvokeMember automatiquement lorsque l'on invoque le click , mais juste pour être sûr d'avoir ajouté les appels InvokeMember pour ces événements aussi. Les résultats ne sont pas meilleurs.

À partir des commentaires:

… chargez cette page dans le navigateur IE complet, utilisez F12 Tools pour le déboguer et exécutez button.click () dans la console JavaScript. Est-ce que cela fonctionne comme prévu de cette façon?

Donc, vous avez essayé cela, et le résultat est:

… maintenant c'est intéressant. Cela ne fonctionne pas! Mais cliquer sur l'élément à la main fonctionne parfaitement. Que se passe t-il ici?

Je MyButton.InvokeMember("click") que MyButton.InvokeMember("click") ne fonctionne pas. Apparemment, la page gère ce clic par d'autres moyens que via l'événement onclick . Très probablement, il utilise des événements onmousedown ou sur le onmouseup . Étudiez la logique de script de la page pour vérifier si c'est le cas, utilisez le débogueur F12 et mettez des points de rupture.

Mise à jour , s'il s'avère que la page utilise effectivement onmousedown / onmouseup , vous devriez rendre votre WebBrowser visible et l'automatiser en publiant WM_LBUTTONDOWN :

 using System; using System.Drawing; using System.Runtime.InteropServices; using System.Windows.Forms; namespace WindowsFormsApplication_22979038 { public partial class MainForm : Form { public MainForm() { InitializeComponent(); } private void MainForm_Load(object sender, EventArgs e) { this.webBrowser.DocumentText = "<a id='goLink' href='javascript:alert(\"Hello!\"),undefined'>Go</a><script></script>"; this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted; } void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { var element = this.webBrowser.Document.GetElementById("goLink"); element.Focus(); var hwnd = GetFocus(); if (!IsChild(this.webBrowser.Handle, hwnd)) throw new ApplicationException("Unexpected focused window."); var rect = GetElementRect(element); IntPtr wParam = (IntPtr)MK_LBUTTON; IntPtr lParam = (IntPtr)(rect.Left | rect.Top << 16); PostMessage(hwnd, WM_LBUTTONDOWN, wParam, lParam); PostMessage(hwnd, WM_LBUTTONUP, wParam, lParam); } // get the element rect in window client area coordinates static Rectangle GetElementRect(HtmlElement element) { var rect = element.OffsetRectangle; int left = 0, top = 0; var parent = element; while (true) { parent = parent.OffsetParent; if (parent == null) return new Rectangle(rect.X + left, rect.Y + top, rect.Width, rect.Height); var parentRect = parent.OffsetRectangle; left += parentRect.Left; top += parentRect.Top; } } // interop const int MK_LBUTTON = 0x0001; const int WM_LBUTTONDOWN = 0x0201; const int WM_LBUTTONUP = 0x0202; [StructLayout(LayoutKind.Sequential)] public struct POINT { public int x; public int y; } [DllImport("User32.dll", CharSet = CharSet.Auto)] static extern int PostMessage(IntPtr hwnd, int msg, IntPtr wparam, IntPtr lparam); [DllImport("User32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] static extern IntPtr GetFocus(); [DllImport("User32.dll", SetLastError = true, ExactSpelling = true, CharSet = CharSet.Auto)] static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd); } }