2011-02-15 31 views
1

導航後,無法調用在注入WebBrowser文檔的代碼中創建的JavaScript對象的方法我發現了其他一些類似的問題,但不完全,以及解決方案無法解決此特定問題。我正在開發一個類似Internet Explorer iMacros的項目。這是我的簡化代碼:在導航

public partial class Form1 : Form 
{ 
    public JSObject jsObject = new JSObject(); 
    int uniqueNameEnsurer = 0; 

    public Form1() 
    { 
     InitializeComponent(); 
     webBrowser1.Navigate("www.google.com"); 
    } 

    private void InvokeCode(string functionCode) 
    { 
     HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0]; 
     HtmlElement scriptEl = webBrowser1.Document.CreateElement("script"); 
     IHTMLScriptElement element = (IHTMLScriptElement)scriptEl.DomElement; 
     element.text = "function MyInjectedFunction" + uniqueNameEnsurer + "(Param){" + functionCode + "}"; 
     head.AppendChild(scriptEl); 
     webBrowser1.Document.InvokeScript("MyInjectedFunction" + uniqueNameEnsurer, new object[] { jsObject }); 
     uniqueNameEnsurer++; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     InvokeCode(@" 
      function MyObject() 
      { 
       this.Something = 'hello'; 
       this.SomeFunc = function(){ 
        alert('in SomeFunc!!!'); 
       } 
      } 

      Param.UserData = new MyObject(); 
     "); 
    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     webBrowser1.Navigate("www.bing.com"); 
    } 

    private void button3_Click(object sender, EventArgs e) 
    { 
     InvokeCode(@" 
      alert(Param.UserData.Something); 
      Param.UserData.SomeFunc(); 
     "); 
    } 
} 

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 
[System.Runtime.InteropServices.ComVisibleAttribute(true)] 
public class JSObject 
{ 
    public object UserData; 
} 

所以,我做的是什麼,單擊button(它調用button1_Click),然後BUTTON2(它調用button2_Click),等一下加載,然後單擊按鈕3(它調用button3_Click )。 當我點擊button3時,我收到一條警告,提示「hello」(這意味着該對象在導航後以某種方式持續存在),但在此之後,我收到一條錯誤,提示「無法從釋放的腳本執行代碼」。這可能是某種安全的事情。我發現一些帖子在談論,但沒有一個解決我的問題。我可以通過創建我的SomeFunc作爲字符串,然後使用eval來解決,但這是一個討厭的解決方案。如果有什麼我可以對我的C#代碼做的事情,讓我保持JavaScript代碼的方式(當然是工作),那將是非常酷的。如果沒有,最好的解決辦法是什麼,以便我可以在導航後致電SomeFunc

+0

我想我可以通過將對象序列化爲一個字符串來解決這個問題,但該方法也需要序列化,不知道最好的方法是什麼。 – Juan 2011-02-16 04:31:29

回答

0

好吧,顯然這只是不可能做我想用C#做的事情。我需要在JavaScript中實現某種對象序列化和反序列化系統,並在導航之後導航並反序列化之前序列化UserData

0

這裏有幾件事情我不明白。首先,我不會指望在調用Navigate之後腳本在那裏。一旦你導航,我認爲你應該重新注入你想要的所有腳本。

第二我沒有看到「MyObject」的定義在哪裏?我看到「新的MyObject();」在你的腳本中,但是我沒有在任何地方看到MyObject函數,所以我沒有意識到你的SomeFunc()沒有被定義。假設樣本不完整。

最後你應該考慮在你的JSObject上實現IReflect和IExpando。它可能會解決你所有的問題。

+0

MyObject是在第一次調用JavaScript代碼時定義的,MyObject的一個實例被創建並傳遞迴我的C#應用​​程序,然後傳遞迴第二個JavaScript調用。在調用導航之後,我不指望腳本在那裏。他們不會。但是我想讓對象的實例在導航之後保持不變。 – Juan 2011-02-22 03:51:44