Passing C# object to JScript - c#

I have this working:
Microsoft.JScript.Vsa.VsaEngine engine = Microsoft.JScript.Vsa.VsaEngine.CreateEngine();
string js = "15+10";
var result = Microsoft.JScript.Eval.JScriptEvaluate(js, engine);
Now I want to pass some objects from C#. Is it possible?
Any help appreciated.

Related

Check if Unity Build Successfully or Not (UNITY C#)

Here's my script for building Programmatically
BuildPlayerOptions szBuildResult = new BuildPlayerOptions();
szBuildResult.scenes = scenes;
szBuildResult.locationPathName = m_szapkFileName;
szBuildResult.target = BuildTarget.StandaloneWindows;
szBuildResult.options = BuildOptions.None;
BuildPipeline.BuildPlayer(szBuildResult);
Now I tried to do something like this
string result = BuildPipeline.BuildPlayer(szBuildResult);
But it's returning me an error saying
Cannot convert type UnityEditor.Build.Reporting.BuildReport to string
How can i check if the build is successful or not?
I'm using Unity 2018.2
BuildPipeline.BuildPlayer will reutrn BuildReport object. so use BuildReport instead of string
BuildReport result = BuildPipeline.BuildPlayer(szBuildResult);

Adding scripting functionality to existing C# project

I work in a research group and I've been tasked with adding in scripting functionality to a data acquisition program. Ideally, I want to have the ability to write scripts while the data acquisition software is running (and save those scripts as files on the go). A command line might also be nice.
I'm not very experienced at all with C#, but I do have quite a bit of coding experience in other language (Objective-C, Python). I saw this link https://blogs.msdn.microsoft.com/cdndevs/2015/12/01/adding-c-scripting-to-your-development-arsenal-part-1/ which details the "Roselyn Scripting Package" but I'm not sure if that's my best option.
Can anybody suggest the easiest way of getting full scripting functionality? (I'm trying to avoid losing months of my life here =p). Links to start at/advice is much appreciated.
Thanks!
You posted an interesting link for me because I just prototyped something like that some weeks ago, but have not implemented yet. My goal is to create a C# "immediate" console on a webpage.
Have some minor issues regarding loading some assemblies programatically and have to reference them explicitly.
Here is the code behind, please later post your solution, I would be interested to know.
This alows to write c# code at runtime and also get a String return.
protected void getImmediateResult_Click(object sender, EventArgs e)
{
//building the code
string source = #"using System;
class MyType{
public static String Evaluate(){
<!expression!>
}}";
string expression = this.txtimmediate.Text;
string finalSource = source.Replace("<!expression!>", expression);
textcodeCheck.Text = finalSource;
var compileUnit = new CodeSnippetCompileUnit(finalSource);
//preparing compilation
CodeDomProvider provider = new Microsoft.CSharp.CSharpCodeProvider();
// Create the optional compiler parameters
//this correctly references the application but no System.Web etc
string[] refArray = new string[2];
UriBuilder uri = new UriBuilder(Assembly.GetExecutingAssembly().CodeBase);
refArray[0] = uri.Path;
//this works
refArray[1] = "System.Web" + ".dll";
////NOT WORKING for non microsoft assemblies
//var allRefs = Assembly.GetExecutingAssembly().GetReferencedAssemblies();
//string[] refArray = new string[allRefs.Length + 1];
//int i = 1;
//foreach (AssemblyName refer in allRefs)
//{
// refArray[i] = refer.Name + ".dll";
// i++;
//}
var compilerParameters = new CompilerParameters(refArray);
CompilerResults compilerResults = provider.CompileAssemblyFromDom(compilerParameters, compileUnit);
if (compilerResults.Errors.Count > 0)
{
//1st error
this.txtResult.Text = compilerResults.Errors[0].ErrorText;
return;
}
//running it
Type type = compilerResults.CompiledAssembly.GetType("MyType");
MethodInfo method = type.GetMethod("Evaluate");
String result = (String)method.Invoke(null, null);
this.txtResult.Text = result;
}
If you're willing to use IronPython, you can execute scripts directly in C#:
using IronPython.Hosting;
using Microsoft.Scripting.Hosting;
private static void doPython()
{
ScriptEngine engine = Python.CreateEngine();
engine.ExecuteFile(#"test.py");
}
Get IronPython here.

Trigger C# method from JavaScript and send parameters

I'm trying to call a C# method from JavaScript and send parameters along with the call. I've done calls to web method but since I can't get to server side controls in static web method, I can't really use it in this case.
I can't do full postback because I need to get Google Map coordinates which in my case I'm accessing them this way, and I'm not able to access them differently:
var map = new google.maps.Map(document.getElementById("dvMap"), mapOptions);
var bounds = new google.maps.LatLngBounds();
bounds = map.getBounds();
var latLng = map.getCenter();
var latSW = bounds.getSouthWest().lat();
var lngSW = bounds.getSouthWest().lng();
var centerLat = latLng.lat();
var centerLng = latLng.lng();
So now since I want to pass some of these parameters to actual c# function it's ok even if I need to do full server side postback as long as I have the controls in my backend code.
Once on server side I need to populate asp.net repeater control with the dataset, that's the biggest issue why I need to trigger backend method.
public void GetData(string latSW, string lngSW, string latNE, string lngNE)
{
DataTable dt = this.GetData(latSW, lngSW, latNE, lngNE);
rptMarkers.DataSource = dt;
rptMarkers.DataBind();
RepDetails.DataSource = dt;
RepDetails.DataBind();
}
I'm unsure, from your question, whether you can or can't make a full post back so here's a fun javascript solution
function myawesomejavascriptfunction(latsw,lngsw,latne,lngne)
{
var myawesomeform=document.createElement('form');
myawesomeform.setAttribute('method','post");
myawesomeform.setAttribute('action','/myawesomewebendpoint');
var myawesomelatsw=document.createElement('input');
myawesomelatsw.setAttribute('type','hidden');
myawesomelatsw.setAttribute('name','latsw');
myawesomelatsw.setAttribute('value',latsw);
var myawesomelngsw=document.createElement('input');
myawesomelngsw.setAttribute('type','hidden');
myawesomelngsw.setAttribute('name','lngsw');
myawesomelngsw.setAttribute('value',lngsw);
var myawesomelatne=document.createElement('input');
myawesomelatne.setAttribute('type','hidden');
myawesomelatne.setAttribute('name','latne');
myawesomelatne.setAttribute('value',latne);
var myawesomelngne=document.createElement('input');
myawesomelngne.setAttribute('type','hidden');
myawesomelngne.setAttribute('name','lngne');
myawesomelngne.setAttribute('value',lngne);
document.getElementsByTagName('body')[0].appendChild(myawesomeform);
myawesomeform.submit();
}
The endpoint method at /myawesomewebendpoint will call the class with the GetData() method and pass on the parameters.
It will work, provided I've not got hold of the entirely wrong end of the stick.

How do I return a JSON string from an Eval call to JScript.NET?

I am trying to use JScript.NET to do dynamic code evaluation. I have a simple JScript.NET eval method that handles that:
public static object Eval(string javascript) {
return Microsoft.JScript.Eval.JScriptEvaluate(javascript, Microsoft.JScript.Vsa.VsaEngine.CreateEngine());
}
I would like to be able to pass objects into the Eval and get them back out again, and I'd like to do that via JSON. I can pass objects from C# into my JScript without any problem by serializing them using JSON.NET. What I'm having trouble doing is getting JSON back out from my javascript program into my C# caller. When I return a object, what I get back is a JSObject (http://msdn.microsoft.com/en-us/library/microsoft.jscript.jsobject.aspx). I apparently cannot JSON.stringify() in JScript.NET either as it doesn't know anything about JSON. Alternately, I can take the JSObject returned by the script if I could serialize it to JSON in C#, but JSON.NET doesn't handle these JSObjects.
Here's a code sample:
// using Newtonsoft.Json; // somewhere at the top
dynamic json = new JObject();
json.Id = 1;
json.Name = new JObject();
json.Name.First = "John";
json.Name.Last = "Doe";
json.Dob = new DateTime(1970, 2, 3);
// dynamically construct a script for eval... could be anything... contrived example below.
var js = new StringBuilder();
// set up a new object, passed from C# world into JScript.NET
js.AppendLine("var person = " + json.ToString() + ";");
// do something useful
js.AppendLine("person.FullName = person.Name.First + ' ' + person.Name.Last;");
// return person object... this comes back as JSObject. Wish I could JSON.stringify!
js.AppendLine("person;");
// objResult is a JSObject, but how do I get json string???
dynamic objResult = JSEvaluator.Eval(js.ToString());
// tried JSON.NET, but it doesn't work!
// var jsonResult = Newtonsoft.Json.JsonConvert.SerializeObject(objResult);
Any help would be greatly appreciated!
Is this what you're looking for? Essentially I just took json2.min.js (per #Michael B's suggestion in the comments) and added it to the javascript as a first order of business. This enables you to stringify your object as you wanted and send the JSON string back to the C# world. From there you can convert it back to a JObject and get the data from it or manipulate it further. A complete program based on your example code follows:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args)
{
dynamic json = new JObject();
json.Id = 1;
json.Name = new JObject();
json.Name.First = "John";
json.Name.Last = "Doe";
json.Dob = new DateTime(1970, 2, 3);
// dynamically construct a script for eval... could be anything... contrived example below.
var js = new StringBuilder();
// Add JSON2.min.js so we can stringify
js.AppendLine(#"var JSON;JSON||(JSON={}),(function(){""use strict"";function i(n){return n<10?""0""+n:n}function f(n){return o.lastIndex=0,o.test(n)?'""'+n.replace(o,function(n){var t=s[n];return typeof t==""string""?t:""\\u""+(""0000""+n.charCodeAt(0).toString(16)).slice(-4)})+'""':'""'+n+'""'}function r(i,e){var h,l,c,a,v=n,s,o=e[i];o&&typeof o==""object""&&typeof o.toJSON==""function""&&(o=o.toJSON(i)),typeof t==""function""&&(o=t.call(e,i,o));switch(typeof o){case""string"":return f(o);case""number"":return isFinite(o)?String(o):""null"";case""boolean"":case""null"":return String(o);case""object"":if(!o)return""null"";n+=u,s=[];if(Object.prototype.toString.apply(o)===""[object Array]""){for(a=o.length,h=0;h<a;h+=1)s[h]=r(h,o)||""null"";return c=s.length===0?""[]"":n?""[\n""+n+s.join("",\n""+n)+""\n""+v+""]"":""[""+s.join("","")+""]"",n=v,c}if(t&&typeof t==""object"")for(a=t.length,h=0;h<a;h+=1)typeof t[h]==""string""&&(l=t[h],c=r(l,o),c&&s.push(f(l)+(n?"": "":"":"")+c));else for(l in o)Object.prototype.hasOwnProperty.call(o,l)&&(c=r(l,o),c&&s.push(f(l)+(n?"": "":"":"")+c));return c=s.length===0?""{}"":n?""{\n""+n+s.join("",\n""+n)+""\n""+v+""}"":""{""+s.join("","")+""}"",n=v,c}}typeof Date.prototype.toJSON!=""function""&&(Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+""-""+i(this.getUTCMonth()+1)+""-""+i(this.getUTCDate())+""T""+i(this.getUTCHours())+"":""+i(this.getUTCMinutes())+"":""+i(this.getUTCSeconds())+""Z"":null},String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()});var e=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,o=/[\\\""\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,n,u,s={""\b"":""\\b"",""\t"":""\\t"",""\n"":""\\n"",""\f"":""\\f"",""\r"":""\\r"",'""':'\\""',""\\"":""\\\\""},t;typeof JSON.stringify!=""function""&&(JSON.stringify=function(i,f,e){var o;n="""",u="""";if(typeof e==""number"")for(o=0;o<e;o+=1)u+="" "";else typeof e==""string""&&(u=e);t=f;if(f&&typeof f!=""function""&&(typeof f!=""object""||typeof f.length!=""number""))throw new Error(""JSON.stringify"");return r("""",{"""":i})}),typeof JSON.parse!=""function""&&(JSON.parse=function(n,t){function r(n,i){var f,e,u=n[i];if(u&&typeof u==""object"")for(f in u)Object.prototype.hasOwnProperty.call(u,f)&&(e=r(u,f),e!==undefined?u[f]=e:delete u[f]);return t.call(n,i,u)}var i;n=String(n),e.lastIndex=0,e.test(n)&&(n=n.replace(e,function(n){return""\\u""+(""0000""+n.charCodeAt(0).toString(16)).slice(-4)}));if(/^[\],:{}\s]*$/.test(n.replace(/\\(?:[""\\\/bfnrt]|u[0-9a-fA-F]{4})/g,""#"").replace(/""[^""\\\n\r]*""|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,""]"").replace(/(?:^|:|,)(?:\s*\[)+/g,"""")))return i=eval(""(""+n+"")""),typeof t==""function""?r({"""":i},""""):i;throw new SyntaxError(""JSON.parse"");})})()");
// set up a new object, passed from C# world into JScript.NET
js.AppendLine("var person = " + json.ToString() + ";");
// do something useful
js.AppendLine("person.FullName = person.Name.First + ' ' + person.Name.Last;");
// return stringified person object
js.AppendLine("JSON.stringify(person);");
// objResult is a JScript.ConcatString
dynamic objResult = Eval(js.ToString());
// Get our manipulated object back to the C# world
json = JsonConvert.DeserializeObject(objResult.ToString());
// Print out the Full Name which was added inside the JS
Console.WriteLine(json.FullName);
}
public static object Eval(string javascript)
{
return Microsoft.JScript.Eval.JScriptEvaluate(javascript, Microsoft.JScript.Vsa.VsaEngine.CreateEngine());
}
}
Output:
John Doe

Call C# BHO method from javascript

I need to call a C# BHO method from javascript
I have followed the solution given in this question
I get the error:
'mshtml.HTMLWindow2Class' does not contain a definition for 'myExtension'.
I cannot assign:
dynamic window = browser.Document.parentWindow;
as parentWindow is undefined, I have to cast to (mshtml.IHTMLDocument2) and (mshtml.IHTMLWindow2)
Does anyone have a full working example I could refer to or any help or alternative solutions
I've the same problem. And the following fix seems work in my BHO:
dynamic window = _webBrowser.Document.parentWindow;
var windowEx = (IExpando)window;
PropertyInfo p = windowEx.AddProperty("myExtension");
p.SetValue(windowEx, this);
instead of:
dynamic window = _webBrowser.Document.parentWindow;
var windowEx = (IExpando)window;
PropertyInfo p = windowEx.AddProperty("myExtension");
window.myExtension = this;

Categories

Resources