سؤال

لذلك أنا أستخدم MSScriptControl لتشغيل بعض جافا سكريبت في تطبيقي وأريد أن أتمكن من الحصول على بعض المعلومات حول أي أخطاء قد يسببها البرنامج النصي.

MSScriptControl.ScriptControlClass script = new MSScriptControl.ScriptControlClass();
try
{
    script.Language = "JScript";
    script.Timeout = 15000;
    script.Eval(Code);
}
catch (Exception ex)
{
    MSScriptControl.Error err = script.Error;
    ret = new Exception("Error on line: " + err.Line + ", Description: " + err.Description);
}

يعمل الرمز بشكل جيد على جهاز التطوير الخاص بي، وهو جهاز Windows 7، ويعطيني رقم سطر به خطأ.لذلك يسعدني أن أنشره وأدفعه إلى آلة الإنتاج التي تخبرني دائمًا أن الخطأ حدث في السطر 0 ولم يتم تقديم أي وصف.

حاولت الذهاب إلى http://www.microsoft.com/download/en/details.aspx?id=1949 لتنزيل أحدث إصدار ولكن تثبيته لم يكن له أي تأثير.قمت أيضًا بتعيين الخاصية Embed Interop Types على false بالإضافة إلى نسخ ملف msscript.ocx الخاص بي إلى دليل system32 الخاص بخادم Windows 2008 ولكن لم تحل أي من هذه المحاولات أي شيء.

هل لدى أي شخص أي توصيات؟

هل كانت مفيدة؟

المحلول

فيما يتعلق بالمشكلة التي تواجه بعض الأفكار:

  • وفقا للربط الذي قدمته هذا التحكم لا يدعم Windows 7 أو Windows 2008
  • قد تكون مشكلة أمنية فيما يتعلق بالمواد COM / UAC وما إلى ذلك.
  • قد تكون مشكلة بسبب البتنس إذا قمت بتجميعها ل anycpu، فحاول استخدام x86

فيما يتعلق البدائل المحتملة:

  • باستخدام jscript يمكنك إنشاء المقيم بسهولة وهو مدعوم في أي مكان .NET 4 يعمل (بما في ذلك Windowsخادم 2008).
  • باستخدام jint كترجمي جافا سكريبت

نصائح أخرى

إذا كنت تريد القيام بذلك في جميع لغة c# الأصلية دون أي تبعيات خارجية لجهة خارجية أو "مكون"، فاستخدم CodeDomProvider باستخدام تمهيد JScript صغير، مثل هذا:

private static readonly MethodInfo eval = CodeDomProvider
        .CreateProvider("JScript")
        .CompileAssemblyFromSource(new CompilerParameters(), "package e{class v{public static function e(e:String):Object{return eval(e);}}}")
        .CompiledAssembly
        .GetType("e.v")
        .GetMethod("e");

private static object JsEval(string jscript)
{
    try
    {
        return eval.Invoke(null, new[] { jscript });
    }
    catch (Exception ex)
    {
        return ex;
    }
}

الذي يخلق JsEval(string) الطريقة التي يمكنك استخدامها في أي مكان في التعليمات البرمجية الخاصة بك "لتقييم" سلسلة مثل JavaScript (جيدًا JScript) ...لذلك يدعو:

MessageBox.Show("" + JsEval("2 + 2")); // 4
MessageBox.Show("" + JsEval("(function(){ return 3+7; })();")); // 10
MessageBox.Show("" + JsEval("function yay(a) { return a + 1; } yay(2);")); // 3

اعتمادًا على استخدامك، قد لا ترغب في إنشاء مثيل لهؤلاء الأعضاء بشكل ثابت.إذا كنت تريد التعامل مع الكائنات المعقدة، فستحتاج إلى إنشاء غلاف لاستخراج البيانات بشكل عاكس (أو يمكنك تمثيلها كنظير JScript المناسب، لكنني لم أحاول ذلك مطلقًا لأنه سيتعين عليك تضمين تجميعات JScript).

فيما يلي مثال على فئة مجمعة تقوم بكل ما ستتيح لك JavaScript القيام به محليًا، ومن المحتمل أن تكون إضافة المزيد من الوظائف عالية المستوى مرهقة بدرجة كافية بحيث يكون من الأفضل لك إما استخراج الأعضاء في قاموس/جدول تجزئة أو بدلاً من ذلك إجراء تسلسل و إلغاء التسلسل على الطرف الآخر

private class JsObjectWrapper : IEnumerable
{
    public readonly object jsObject;
    private static PropertyInfo itemAccessor = null;
    private static MethodInfo getEnumerator = null;

    public JsObjectWrapper(object jsObject)
    {
        this.jsObject = jsObject;

        if (itemAccessor == null) 
        {
            itemAccessor = jsObject.GetType().GetProperty("Item", new Type[] { typeof(string) });
        }

        if (getEnumerator == null)
        {
            getEnumerator = jsObject.GetType().GetInterface("IEnumerable").GetMethod("GetEnumerator");
        }
    }

    public object this[string key]
    {
        get { return itemAccessor.GetValue(jsObject, new object[] { key }); }
        set { itemAccessor.SetValue(jsObject, value, new object[] { key }); } 
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return (IEnumerator)getEnumerator.Invoke(jsObject, null);
    }
}

يمكنك رؤية هذا عمليًا من خلال القيام بذلك:

var jsObj = JsEval("var x = { a:7, b:9 };");
var csObj = new JsObjectWrapper(jsObj);

MessageBox.Show("a: " + csObj["a"]);  // a: 7
MessageBox.Show("b: " + csObj["b"]);  // b: 9

csObj["yay!"] = 69;

foreach (string key in csObj)
{
    MessageBox.Show("" + key + ": " + csObj[key]); // "key": "value"
}

لقد استخدمت شخصيًا رمزًا مشابهًا لهذا لإحداث تأثير كبير في وقت أو آخر ويمكنني أن أضمن توفره وقابليته للتشغيل داخل بيئة الخادم.آمل أن يساعد هذا -ck

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top