3

I have a webpage that when visited, declares a variable called date using the following:

var date=new Date("03 Oct 2013 16:04:19");

That date is then displayed at the top of the page. Is there a way for me to modify that date variable? (and not just the visible HTML source)

I have been experimenting with InvokeScript but am finding it hard to grasp, if anybody knows and could post some examples relating directly to this I'd be hugely grateful. Thankyou.

3
  • Can you show us what you've tried with invokeScript()? Commented Oct 7, 2013 at 14:15
  • Dim args As Object() = {"javascript:var date=new Date(""07 Oct 2013 14:40:43"");"} WebBrowser1.Document.InvokeScript("test", args) Commented Oct 7, 2013 at 14:20
  • 2
    @johndyas, you have a number of options to do this. Commented Oct 7, 2013 at 14:31

2 Answers 2

3

You can inject any JavaScript code using JavaScript's eval, it works with any IE version. You'd need to make sure the page has at least one <script> tag, but this is easy:

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Call WebBrowser1.Navigate("http://example.com")
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted
        '
        ' use WebBrowser1.Document.InvokeScript to inject script
        '
        ' make sure the page has at least one script element, so eval works
        WebBrowser1.Document.Body.AppendChild(WebBrowser1.Document.CreateElement("script"))
        WebBrowser1.Document.InvokeScript("eval", New [Object]() {"(function() { window.newDate=new Date('03 Oct 2013 16:04:19'); })()"})
        Dim result As String = WebBrowser1.Document.InvokeScript("eval", New [Object]() {"(function() { return window.newDate.toString(); })()"})
        MessageBox.Show(result)

    End Sub

End Class

Alternatively, you can use VB.NET late binding to call eval directly, instead of Document.InvokeScript, which might be easier to code and read:

Public Class Form1

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Call WebBrowser1.Navigate("http://example.com")
    End Sub

    Private Sub WebBrowser1_DocumentCompleted(sender As Object, e As WebBrowserDocumentCompletedEventArgs) Handles WebBrowser1.DocumentCompleted

        '
        ' use VB late binding to call eval directly (seamlessly provided by.NET DLR)
        '
        Dim htmlDocument = WebBrowser1.Document.DomDocument
        Dim htmlWindow = htmlDocument.parentWindow
        ' make sure the page has at least one script element, so eval works
        htmlDocument.body.appendChild(htmlDocument.createElement("script"))
        htmlWindow.eval("var anotherDate = new Date('04 Oct 2013 16:04:19').toString()")
        MessageBox.Show(htmlWindow.anotherDate)
        ' the above shows we don't have to use JavaScript anonymous function,
        ' but it's always a good coding style to do so, to scope the context:
        htmlWindow.eval("window.createNewDate = function(){ return new Date().toString(); }")
        MessageBox.Show(htmlWindow.eval("window.createNewDate()"))

        ' we can also mix late binding and InvokeScript
        MessageBox.Show(WebBrowser1.Document.InvokeScript("createNewDate"))

    End Sub

End Class
Sign up to request clarification or add additional context in comments.

1 Comment

+1 Good call on the eval function. I was going to suggest that too if the OP didn't have access to the source of the webpage.
2

According to the documentation, you need to invoke an existing script defined in the client:
JavaScript:

var extDate = new Date("03 Oct 2013 16:04:19");

function test(date) {
  alert(date);
  extDate = date;
}

You could also call eval and run an anonymous function. This would be the preferred method if you have no control over the page source. Essentially, you would be invoking and running code in the JavaScript interpreter.

C#:

private void InvokeTestMethod(DateTime date)
{
    if (webBrowser1.Document != null)
    {
        webBrowser1.Document.Body.AppendChild(webBrowser1.Document.CreateElement("script"));
        webBrowser1.Document.InvokeScript("eval", (Object)"(function() { window.date=new Date('03 Oct 2013 16:04:19'); })()");
        webBrowser1.Document.InvokeScript("eval", (Object)"(function() { alert(window.newDate.toString()); })()");
        webBrowser1.Document.InvokeScript("eval", (Object)"(function() { window.date=new Date('" + date.ToString("dd MMM yyyy HH:mm:ss") + "'); })()");
        webBrowser1.Document.InvokeScript("eval", (Object)"(function() { alert(window.newDate.toString()); })()");
    }
}

private void Test()
{
    InvokeTestMethod(DateTime.Now);
}

VB.NET

Private Sub InvokeTestMethod([date] As DateTime)
    If webBrowser1.Document IsNot Nothing Then
        webBrowser1.Document.Body.AppendChild(webBrowser1.Document.CreateElement("script"))
        webBrowser1.Document.InvokeScript("eval", new [Object]() {"(function() { window.date=new Date('03 Oct 2013 16:04:19'); })()"}))
        webBrowser1.Document.InvokeScript("eval", new [Object]() {"(function() { alert(window.newDate.toString()); })()"}))
        webBrowser1.Document.InvokeScript("eval", new [Object]() {"(function() { window.date=new Date('" + [date].ToString("dd MMM yyyy HH:mm:ss") + "'); })()"})
        webBrowser1.Document.InvokeScript("eval", new [Object]() {"(function() { alert(window.newDate.toString()); })()"}))
    End If
End Sub

Private Sub Test()
    InvokeTestMethod(DateTime.Now)
End Sub

http://msdn.microsoft.com/en-us/library/system.windows.forms.htmldocument.invokescript.aspx

By using eval, you can invoke anonymous JavaScript functions and run your own code within the context of the web page. In the last two calls to eval, I set the date using DateTime.Now and format the date in a way that JavaScript can understand.

6 Comments

Thanks Cameron, if Date is defined outside of a function does it mean I cannot modify it?
Just declare your date variable externally from the function and set the date from the argument passed to the function. I've updated my answer to show how this is done.
@johndyas, if you do not own the page, you can still add any script to it using WebBrowser.Document.CreateElement("script") or just use JavaScript eval as I explained in my answer.
@CameronTinker, there's one thing missing in the new edition of your answer (at the time of this comment). If the target web page doesn't contain any scripts (e.g., example.com), you won't be able to inject JavaScript with eval. An empty <script> tag needs to be added first.
@Noseratio I've updated my answer to append a <script> element to the DOM.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.