2011-01-20 7 views
14

tengo un rastreador simple que rastrea y busca en la página. pero ahora tengo un problema sobre cómo ejecutar y analizar el enlace js desde esa página. ¿Alguien tiene alguna idea de cómo analizar y ejecutar js page?analizar y ejecutar JS por C#

ejemplo:

  • some_url es simple de analizar con webhtmltoolktit
  • JAVASCRIPT: runmeat (1,7,0,2,7,9) es el enlace js que redirigir entonces a some_url2 página y esta página Necesito gatear entonces. pero el problema es cómo ejecutar este javascript en C# para obtener ese enlace some_url2?

Respuesta

48

Para responder al título de pregunta "Cómo analizar y ejecutar JS en C#", aquí hay un fragmento de código que ajusta el Windows Script Engines. Admite entornos de 32 bits y 64 bits.

En su caso específico, significa que dependiendo del código .JS, puede que tenga que emular/implementar algún elemento HTML DOM como 'documento', 'ventana', etc. (usando la función 'elementos nombrados', con la clase MyItem. Eso es exactamente lo que hace Internet Explorer).

Éstos son algunos ejemplos de lo que puede hacer con él:

1) dirigir la evaluación expresiones:

Console.WriteLine(ScriptEngine.Eval("jscript", "1+2/3")); 

mostrará 1.66666666666667

2) La llamada a función, con argumentos opcionales:

using (ScriptEngine engine = new ScriptEngine("jscript")) 
{ 
    ParsedScript parsed = engine.Parse("function MyFunc(x){return 1+2+x}"); 
    Console.WriteLine(parsed.CallMethod("MyFunc", 3)); 
} 

Se mostrará 6

3) llamada a función con elementos cuyos nombres y argumentos opcionales:

using (ScriptEngine engine = new ScriptEngine("jscript")) 
{ 
    ParsedScript parsed = engine.Parse("function MyFunc(x){return 1+2+x+My.Num}"); 
    MyItem item = new MyItem(); 
    item.Num = 4; 
    engine.SetNamedItem("My", item); 
    Console.WriteLine(parsed.CallMethod("MyFunc", 3)); 
} 

[ComVisible(true)] // Script engines are COM components. 
public class MyItem 
{ 
    public int Num { get; set; } 
} 

mostrará 10.

Editar: He añadido la posibilidad de utilizar un CLSID en lugar de un nombre de lenguaje de script, por lo que puede volver a utilizar el nuevo y rápido IE9 + "chakra" javascript motor, así:

using (ScriptEngine engine = new ScriptEngine("{16d51579-a30b-4c8b-a276-0ff4dc41e755}")) 
{ 
    // continue with chakra now 
} 

Aquí es la fuente completa:

/// <summary> 
/// Represents a Windows Script Engine such as JScript, VBScript, etc. 
/// </summary> 
public sealed class ScriptEngine : IDisposable 
{ 
    /// <summary> 
    /// The name of the function used for simple evaluation. 
    /// </summary> 
    public const string MethodName = "EvalMethod"; 

    /// <summary> 
    /// The default scripting language name. 
    /// </summary> 
    public const string DefaultLanguage = JavaScriptLanguage; 

    /// <summary> 
    /// The JavaScript or jscript scripting language name. 
    /// </summary> 
    public const string JavaScriptLanguage = "javascript"; 

    /// <summary> 
    /// The javascript or jscript scripting language name. 
    /// </summary> 
    public const string VBScriptLanguage = "vbscript"; 

    /// <summary> 
    /// The chakra javascript engine CLSID. The value is {16d51579-a30b-4c8b-a276-0ff4dc41e755}. 
    /// </summary> 
    public const string ChakraClsid = "{16d51579-a30b-4c8b-a276-0ff4dc41e755}"; 

    private IActiveScript _engine; 
    private IActiveScriptParse32 _parse32; 
    private IActiveScriptParse64 _parse64; 
    internal ScriptSite Site; 
    private Version _version; 
    private string _name; 

    [Guid("BB1A2AE1-A4F9-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    private interface IActiveScript 
    { 
     [PreserveSig] 
     int SetScriptSite(IActiveScriptSite pass); 
     [PreserveSig] 
     int GetScriptSite(Guid riid, out IntPtr site); 
     [PreserveSig] 
     int SetScriptState(ScriptState state); 
     [PreserveSig] 
     int GetScriptState(out ScriptState scriptState); 
     [PreserveSig] 
     int Close(); 
     [PreserveSig] 
     int AddNamedItem(string name, ScriptItem flags); 
     [PreserveSig] 
     int AddTypeLib(Guid typeLib, uint major, uint minor, uint flags); 
     [PreserveSig] 
     int GetScriptDispatch(string itemName, out IntPtr dispatch); 
     [PreserveSig] 
     int GetCurrentScriptThreadID(out uint thread); 
     [PreserveSig] 
     int GetScriptThreadID(uint win32ThreadId, out uint thread); 
     [PreserveSig] 
     int GetScriptThreadState(uint thread, out ScriptThreadState state); 
     [PreserveSig] 
     int InterruptScriptThread(uint thread, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo, uint flags); 
     [PreserveSig] 
     int Clone(out IActiveScript script); 
    } 

    [Guid("4954E0D0-FBC7-11D1-8410-006008C3FBFC"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    private interface IActiveScriptProperty 
    { 
     [PreserveSig] 
     int GetProperty(int dwProperty, IntPtr pvarIndex, out object pvarValue); 
     [PreserveSig] 
     int SetProperty(int dwProperty, IntPtr pvarIndex, ref object pvarValue); 
    } 

    [Guid("DB01A1E3-A42B-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    private interface IActiveScriptSite 
    { 
     [PreserveSig] 
     int GetLCID(out int lcid); 
     [PreserveSig] 
     int GetItemInfo(string name, ScriptInfo returnMask, out IntPtr item, IntPtr typeInfo); 
     [PreserveSig] 
     int GetDocVersionString(out string version); 
     [PreserveSig] 
     int OnScriptTerminate(object result, System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo); 
     [PreserveSig] 
     int OnStateChange(ScriptState scriptState); 
     [PreserveSig] 
     int OnScriptError(IActiveScriptError scriptError); 
     [PreserveSig] 
     int OnEnterScript(); 
     [PreserveSig] 
     int OnLeaveScript(); 
    } 

    [Guid("EAE1BA61-A4ED-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    private interface IActiveScriptError 
    { 
     [PreserveSig] 
     int GetExceptionInfo(out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo); 
     [PreserveSig] 
     int GetSourcePosition(out uint sourceContext, out int lineNumber, out int characterPosition); 
     [PreserveSig] 
     int GetSourceLineText(out string sourceLine); 
    } 

    [Guid("BB1A2AE2-A4F9-11cf-8F20-00805F2CD064"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    private interface IActiveScriptParse32 
    { 
     [PreserveSig] 
     int InitNew(); 
     [PreserveSig] 
     int AddScriptlet(string defaultName, string code, string itemName, string subItemName, string eventName, string delimiter, IntPtr sourceContextCookie, uint startingLineNumber, ScriptText flags, out string name, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo); 
     [PreserveSig] 
     int ParseScriptText(string code, string itemName, IntPtr context, string delimiter, int sourceContextCookie, uint startingLineNumber, ScriptText flags, out object result, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo); 
    } 

    [Guid("C7EF7658-E1EE-480E-97EA-D52CB4D76D17"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] 
    private interface IActiveScriptParse64 
    { 
     [PreserveSig] 
     int InitNew(); 
     [PreserveSig] 
     int AddScriptlet(string defaultName, string code, string itemName, string subItemName, string eventName, string delimiter, IntPtr sourceContextCookie, uint startingLineNumber, ScriptText flags, out string name, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo); 
     [PreserveSig] 
     int ParseScriptText(string code, string itemName, IntPtr context, string delimiter, long sourceContextCookie, uint startingLineNumber, ScriptText flags, out object result, out System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo); 
    } 

    [Flags] 
    private enum ScriptText 
    { 
     None = 0, 
     //DelayExecution = 1, 
     //IsVisible = 2, 
     IsExpression = 32, 
     IsPersistent = 64, 
     //HostManageSource = 128 
    } 

    [Flags] 
    private enum ScriptInfo 
    { 
     //None = 0, 
     //IUnknown = 1, 
     ITypeInfo = 2 
    } 

    [Flags] 
    private enum ScriptItem 
    { 
     //None = 0, 
     IsVisible = 2, 
     IsSource = 4, 
     //GlobalMembers = 8, 
     //IsPersistent = 64, 
     //CodeOnly = 512, 
     //NoCode = 1024 
    } 

    private enum ScriptThreadState 
    { 
     //NotInScript = 0, 
     //Running = 1 
    } 

    private enum ScriptState 
    { 
     Uninitialized = 0, 
     Started = 1, 
     Connected = 2, 
     Disconnected = 3, 
     Closed = 4, 
     Initialized = 5 
    } 

    private const int TYPE_E_ELEMENTNOTFOUND = unchecked((int)(0x8002802B)); 
    private const int E_NOTIMPL = -2147467263; 

    /// <summary> 
    /// Determines if a script engine with the input name exists. 
    /// </summary> 
    /// <param name="language">The language.</param> 
    /// <returns>true if the engine exists; false otherwise.</returns> 
    public static Version GetVersion(string language) 
    { 
     if (language == null) 
      throw new ArgumentNullException("language"); 

     Type engine; 
     Guid clsid; 
     if (Guid.TryParse(language, out clsid)) 
     { 
      engine = Type.GetTypeFromCLSID(clsid, false); 
     } 
     else 
     { 
      engine = Type.GetTypeFromProgID(language, false); 
     } 
     if (engine == null) 
      return null; 

     IActiveScript scriptEngine = Activator.CreateInstance(engine) as IActiveScript; 
     if (scriptEngine == null) 
      return null; 

     IActiveScriptProperty scriptProperty = scriptEngine as IActiveScriptProperty; 
     if (scriptProperty == null) 
      return new Version(1, 0, 0, 0); 

     int major = GetProperty(scriptProperty, SCRIPTPROP_MAJORVERSION, 0); 
     int minor = GetProperty(scriptProperty, SCRIPTPROP_MINORVERSION, 0); 
     int revision = GetProperty(scriptProperty, SCRIPTPROP_BUILDNUMBER, 0); 
     Version version = new Version(major, minor, Environment.OSVersion.Version.Build, revision); 
     Marshal.ReleaseComObject(scriptProperty); 
     Marshal.ReleaseComObject(scriptEngine); 
     return version; 
    } 

    private static T GetProperty<T>(IActiveScriptProperty prop, int index, T defaultValue) 
    { 
     object value; 
     if (prop.GetProperty(index, IntPtr.Zero, out value) != 0) 
      return defaultValue; 

     try 
     { 
      return (T)Convert.ChangeType(value, typeof(T)); 
     } 
     catch 
     { 
      return defaultValue; 
     } 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="ScriptEngine"/> class. 
    /// </summary> 
    /// <param name="language">The scripting language. Standard Windows Script engines names are 'jscript' or 'vbscript'.</param> 
    public ScriptEngine(string language) 
    { 
     if (language == null) 
      throw new ArgumentNullException("language"); 

     Type engine; 
     Guid clsid; 
     if (Guid.TryParse(language, out clsid)) 
     { 
      engine = Type.GetTypeFromCLSID(clsid, true); 
     } 
     else 
     { 
      engine = Type.GetTypeFromProgID(language, true); 
     } 
     _engine = Activator.CreateInstance(engine) as IActiveScript; 
     if (_engine == null) 
      throw new ArgumentException(language + " is not an Windows Script Engine", "language"); 

     Site = new ScriptSite(); 
     _engine.SetScriptSite(Site); 

     // support 32-bit & 64-bit process 
     if (IntPtr.Size == 4) 
     { 
      _parse32 = (IActiveScriptParse32)_engine; 
      _parse32.InitNew(); 
     } 
     else 
     { 
      _parse64 = (IActiveScriptParse64)_engine; 
      _parse64.InitNew(); 
     } 
    } 

    private const int SCRIPTPROP_NAME = 0x00000000; 
    private const int SCRIPTPROP_MAJORVERSION = 0x00000001; 
    private const int SCRIPTPROP_MINORVERSION = 0x00000002; 
    private const int SCRIPTPROP_BUILDNUMBER = 0x00000003; 

    /// <summary> 
    /// Gets the engine version. 
    /// </summary> 
    /// <value> 
    /// The version. 
    /// </value> 
    public Version Version 
    { 
     get 
     { 
      if (_version == null) 
      { 
       int major = GetProperty(SCRIPTPROP_MAJORVERSION, 0); 
       int minor = GetProperty(SCRIPTPROP_MINORVERSION, 0); 
       int revision = GetProperty(SCRIPTPROP_BUILDNUMBER, 0); 
       _version = new Version(major, minor, Environment.OSVersion.Version.Build, revision); 
      } 
      return _version; 
     } 
    } 

    /// <summary> 
    /// Gets the engine name. 
    /// </summary> 
    /// <value> 
    /// The name. 
    /// </value> 
    public string Name 
    { 
     get 
     { 
      if (_name == null) 
      { 
       _name = GetProperty(SCRIPTPROP_NAME, string.Empty); 
      } 
      return _name; 
     } 
    } 

    /// <summary> 
    /// Gets a script engine property. 
    /// </summary> 
    /// <typeparam name="T">The expected property type.</typeparam> 
    /// <param name="index">The property index.</param> 
    /// <param name="defaultValue">The default value if not found.</param> 
    /// <returns>The value of the property or the default value.</returns> 
    public T GetProperty<T>(int index, T defaultValue) 
    { 
     object value; 
     if (!TryGetProperty(index, out value)) 
      return defaultValue; 

     try 
     { 
      return (T)Convert.ChangeType(value, typeof(T)); 
     } 
     catch 
     { 
      return defaultValue; 
     } 
    } 

    /// <summary> 
    /// Gets a script engine property. 
    /// </summary> 
    /// <param name="index">The property index.</param> 
    /// <param name="value">The value.</param> 
    /// <returns>true if the property was successfully got; false otherwise.</returns> 
    public bool TryGetProperty(int index, out object value) 
    { 
     value = null; 
     IActiveScriptProperty property = _engine as IActiveScriptProperty; 
     if (property == null) 
      return false; 

     return property.GetProperty(index, IntPtr.Zero, out value) == 0; 
    } 

    /// <summary> 
    /// Sets a script engine property. 
    /// </summary> 
    /// <param name="index">The property index.</param> 
    /// <param name="value">The value.</param> 
    /// <returns>true if the property was successfully set; false otherwise.</returns> 
    public bool SetProperty(int index, object value) 
    { 
     IActiveScriptProperty property = _engine as IActiveScriptProperty; 
     if (property == null) 
      return false; 

     return property.SetProperty(index, IntPtr.Zero, ref value) == 0; 
    } 

    /// <summary> 
    /// Adds the name of a root-level item to the scripting engine's name space. 
    /// </summary> 
    /// <param name="name">The name. May not be null.</param> 
    /// <param name="value">The value. It must be a ComVisible object.</param> 
    public void SetNamedItem(string name, object value) 
    { 
     if (name == null) 
      throw new ArgumentNullException("name"); 

     _engine.AddNamedItem(name, ScriptItem.IsVisible | ScriptItem.IsSource); 
     Site.NamedItems[name] = value; 
    } 

    internal class ScriptSite : IActiveScriptSite 
    { 
     internal ScriptException LastException; 
     internal Dictionary<string, object> NamedItems = new Dictionary<string, object>(); 

     int IActiveScriptSite.GetLCID(out int lcid) 
     { 
      lcid = Thread.CurrentThread.CurrentCulture.LCID; 
      return 0; 
     } 

     int IActiveScriptSite.GetItemInfo(string name, ScriptInfo returnMask, out IntPtr item, IntPtr typeInfo) 
     { 
      item = IntPtr.Zero; 
      if ((returnMask & ScriptInfo.ITypeInfo) == ScriptInfo.ITypeInfo) 
       return E_NOTIMPL; 

      object value; 
      if (!NamedItems.TryGetValue(name, out value)) 
       return TYPE_E_ELEMENTNOTFOUND; 

      item = Marshal.GetIUnknownForObject(value); 
      return 0; 
     } 

     int IActiveScriptSite.GetDocVersionString(out string version) 
     { 
      version = null; 
      return 0; 
     } 

     int IActiveScriptSite.OnScriptTerminate(object result, System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo) 
     { 
      return 0; 
     } 

     int IActiveScriptSite.OnStateChange(ScriptState scriptState) 
     { 
      return 0; 
     } 

     int IActiveScriptSite.OnScriptError(IActiveScriptError scriptError) 
     { 
      string sourceLine = null; 
      try 
      { 
       scriptError.GetSourceLineText(out sourceLine); 
      } 
      catch 
      { 
       // happens sometimes... 
      } 
      uint sourceContext; 
      int lineNumber; 
      int characterPosition; 
      scriptError.GetSourcePosition(out sourceContext, out lineNumber, out characterPosition); 
      lineNumber++; 
      characterPosition++; 
      System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo; 
      scriptError.GetExceptionInfo(out exceptionInfo); 

      string message; 
      if (!string.IsNullOrEmpty(sourceLine)) 
      { 
       message = "Script exception: {1}. Error number {0} (0x{0:X8}): {2} at line {3}, column {4}. Source line: '{5}'."; 
      } 
      else 
      { 
       message = "Script exception: {1}. Error number {0} (0x{0:X8}): {2} at line {3}, column {4}."; 
      } 
      LastException = new ScriptException(string.Format(message, exceptionInfo.scode, exceptionInfo.bstrSource, exceptionInfo.bstrDescription, lineNumber, characterPosition, sourceLine)); 
      LastException.Column = characterPosition; 
      LastException.Description = exceptionInfo.bstrDescription; 
      LastException.Line = lineNumber; 
      LastException.Number = exceptionInfo.scode; 
      LastException.Text = sourceLine; 
      return 0; 
     } 

     int IActiveScriptSite.OnEnterScript() 
     { 
      LastException = null; 
      return 0; 
     } 

     int IActiveScriptSite.OnLeaveScript() 
     { 
      return 0; 
     } 
    } 

    /// <summary> 
    /// Evaluates an expression using the specified language. 
    /// </summary> 
    /// <param name="language">The language.</param> 
    /// <param name="expression">The expression. May not be null.</param> 
    /// <returns>The result of the evaluation.</returns> 
    public static object Eval(string language, string expression) 
    { 
     return Eval(language, expression, null); 
    } 

    /// <summary> 
    /// Evaluates an expression using the specified language, with an optional array of named items. 
    /// </summary> 
    /// <param name="language">The language.</param> 
    /// <param name="expression">The expression. May not be null.</param> 
    /// <param name="namedItems">The named items array.</param> 
    /// <returns>The result of the evaluation.</returns> 
    public static object Eval(string language, string expression, params KeyValuePair<string, object>[] namedItems) 
    { 
     if (language == null) 
      throw new ArgumentNullException("language"); 

     if (expression == null) 
      throw new ArgumentNullException("expression"); 

     using (ScriptEngine engine = new ScriptEngine(language)) 
     { 
      if (namedItems != null) 
      { 
       foreach (KeyValuePair<string, object> kvp in namedItems) 
       { 
        engine.SetNamedItem(kvp.Key, kvp.Value); 
       } 
      } 
      return engine.Eval(expression); 
     } 
    } 

    /// <summary> 
    /// Evaluates an expression. 
    /// </summary> 
    /// <param name="expression">The expression. May not be null.</param> 
    /// <returns>The result of the evaluation.</returns> 
    public object Eval(string expression) 
    { 
     if (expression == null) 
      throw new ArgumentNullException("expression"); 

     return Parse(expression, true); 
    } 

    /// <summary> 
    /// Parses the specified text and returns an object that can be used for evaluation. 
    /// </summary> 
    /// <param name="text">The text to parse.</param> 
    /// <returns>An instance of the ParsedScript class.</returns> 
    public ParsedScript Parse(string text) 
    { 
     if (text == null) 
      throw new ArgumentNullException("text"); 

     return (ParsedScript)Parse(text, false); 
    } 

    private object Parse(string text, bool expression) 
    { 
     const string varName = "x___"; 
     object result; 

     _engine.SetScriptState(ScriptState.Connected); 

     ScriptText flags = ScriptText.None; 
     if (expression) 
     { 
      flags |= ScriptText.IsExpression; 
     } 

     try 
     { 
      // immediate expression computation seems to work only for 64-bit 
      // so hack something for 32-bit... 
      System.Runtime.InteropServices.ComTypes.EXCEPINFO exceptionInfo; 
      if (_parse32 != null) 
      { 
       if (expression) 
       { 
        // should work for jscript & vbscript at least... 
        text = varName + "=" + text; 
       } 
       _parse32.ParseScriptText(text, null, IntPtr.Zero, null, 0, 0, flags, out result, out exceptionInfo); 
      } 
      else 
      { 
       _parse64.ParseScriptText(text, null, IntPtr.Zero, null, 0, 0, flags, out result, out exceptionInfo); 
      } 
     } 
     catch 
     { 
      if (Site.LastException != null) 
       throw Site.LastException; 

      throw; 
     } 

     IntPtr dispatch; 
     if (expression) 
     { 
      // continue our 32-bit hack... 
      if (_parse32 != null) 
      { 
       _engine.GetScriptDispatch(null, out dispatch); 
       object dp = Marshal.GetObjectForIUnknown(dispatch); 
       try 
       { 
        return dp.GetType().InvokeMember(varName, BindingFlags.GetProperty, null, dp, null); 
       } 
       catch 
       { 
        if (Site.LastException != null) 
         throw Site.LastException; 

        throw; 
       } 
      } 
      return result; 
     } 

     _engine.GetScriptDispatch(null, out dispatch); 
     ParsedScript parsed = new ParsedScript(this, dispatch); 
     return parsed; 
    } 

    /// <summary> 
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 
    /// </summary> 
    public void Dispose() 
    { 
     if (_parse32 != null) 
     { 
      Marshal.ReleaseComObject(_parse32); 
      _parse32 = null; 
     } 

     if (_parse64 != null) 
     { 
      Marshal.ReleaseComObject(_parse64); 
      _parse64 = null; 
     } 

     if (_engine != null) 
     { 
      Marshal.ReleaseComObject(_engine); 
      _engine = null; 
     } 
    } 
} 

public sealed class ParsedScript : IDisposable 
{ 
    private object _dispatch; 
    private readonly ScriptEngine _engine; 

    internal ParsedScript(ScriptEngine engine, IntPtr dispatch) 
    { 
     _engine = engine; 
     _dispatch = Marshal.GetObjectForIUnknown(dispatch); 
    } 

    public object CallMethod(string methodName, params object[] arguments) 
    { 
     if (_dispatch == null) 
      throw new InvalidOperationException(); 

     if (methodName == null) 
      throw new ArgumentNullException("methodName"); 

     try 
     { 
      return _dispatch.GetType().InvokeMember(methodName, BindingFlags.InvokeMethod, null, _dispatch, arguments); 
     } 
     catch 
     { 
      if (_engine.Site.LastException != null) 
       throw _engine.Site.LastException; 

      throw; 
     } 
    } 

    void IDisposable.Dispose() 
    { 
     if (_dispatch != null) 
     { 
      Marshal.ReleaseComObject(_dispatch); 
      _dispatch = null; 
     } 
    } 
} 

[Serializable] 
public class ScriptException : Exception 
{ 
    public ScriptException() 
     : base("Script Exception") 
    { 
    } 

    public ScriptException(string message) 
     : base(message) 
    { 
    } 

    public ScriptException(Exception innerException) 
     : base(null, innerException) 
    { 
    } 

    public ScriptException(string message, Exception innerException) 
     : base(message, innerException) 
    { 
    } 

    protected ScriptException(SerializationInfo info, StreamingContext context) 
     : base(info, context) 
    { 
    } 

    public string Description { get; internal set; } 
    public int Line { get; internal set; } 
    public int Column { get; internal set; } 
    public int Number { get; internal set; } 
    public string Text { get; internal set; } 
} 
+0

Hola. ¿Puedes compartir el código completo? Hay un problema con ConvertUtilities, ScriptException ... Realmente necesito esa funcionalidad. – Hooch

+0

¡Oh, gracias por informar esto, nadie lo comentó antes :-) He actualizado el código que debería compilar bien ahora. No todos los comentarios están ahí porque las respuestas están limitadas a 30000 caracteres. –

+0

Siempre puede pegar su código en pastebin.com – Hooch

0

Para hacer eso por completo necesitarías emular un modelo completo de navegador, nunca sucederá.

Dado que usted afirma "mi página", el truco habitual aquí es hacer algo como:

<a id="foo" href="crawlableRoute">text</a> 

y (más tarde) adjuntar javascript para los click que retornos falsos, suprimiendo el enlace original. Su rastreador navega a través del crawlableRoute. Por ejemplo (usando jQuery):

$(function() { 
    $('#foo').click(function() { 
     // do stuff; 
     return false; // suppress navigation 
    }); 
}); 

De esta manera usted no necesita para manejar el js.

+0

¿qué pasa si la página es Joomla, wp, ... o algo más. Necesito una solución general. – senzacionale

+0

simplemente idea no implementación – senzacionale

4

Quizás no sea la respuesta que estabas buscando, pero esta cuestión fue publicada hace 3 años. Las opciones alternativas están disponibles hoy.

Ver también: Embedding JavaScript engine into .NET

Estos días se puede hacer uso de los paquetes "JavaScript Motor de Conmutación" NuGet para su proyecto. Elija cuál es el mejor para su entorno.

Por ejemplo, v8 requerirá asegurarse de que se instalen ciertos binarios en su servidor , mientras que el paquete Jint NuGet lo envuelve todo por su cuenta (también conocido como "simplemente funciona").

Jint se ha trasladado a GitHub y está disponible aquí: https://github.com/sebastienros/jint

Para llevar a cabo el tipo de funcionalidad dirigida por su pregunta, es posible que necesite para permitir el acceso a los ensamblados .NET en su motor de secuencias de comandos y utilícelos para llamadas AJAX. Otras opciones de configuración pueden proporcionar aún más funcionalidad.

1

Un poco tarde quizás (4 años después de que se publicó la pregunta), pero puede usar el motor de JavaScript Jurrasic escrito en C# nativo. Esto está 100% escrito en C# administrado e incluso funciona en Mono, lo que significa que puede aislar sus necesidades de scripting como plataforma independiente. Si le gustan las aplicaciones mono y usan GTK + como interfaz gráfica de usuario para su aplicación, tiene una solución que funciona en Windows, Linux y OS X, sin mencionar WP, iOS y Android.

El proyecto se puede encontrar aquí https://jurassic.codeplex.com/

Cuestiones relacionadas