我們有一個32位的服務,我們試圖遷移到64位。CodeFluent vs Interop.MSScriptControl.dll
我們使用Interop.MSScriptControl.dll
來評估用戶編寫的VB腳本。
由於沒有64位版本的MSScriptControl
。我創建了一個在服務中被調用的進程。每次我們需要評估用戶腳本時,我們都會調用這個過程。試過這個解決方案之後,我發現它確實很慢。
我剛剛發現了可以評估vb腳本以及JavaScript的CodeFluentRuntimeClient
庫。但是,它評估腳本的方式與MSScriptControl
庫完全不同。
我創建了一個簡單的測試程序來評估用戶編寫的舊VB腳本。
public class VBScriptEvaluator
{
public static dynamic Evaluate(string key, string script, IDictionary<string, object> parameterValuePair)
{
try
{
using (ScriptEngine engine = new ScriptEngine(ScriptEngine.VBScriptLanguage))
{
ParsedScript parsed = engine.Parse(string.Format(@"Function {0}()
{1}
End Function", key, script));
if (script.Contains("NecUserProfile"))
engine.SetNamedItem("NecUserProfile", @"" + "ADMIN" + @""); //Hardcoded For now
if (parameterValuePair != null && parameterValuePair.Count > 0)
{
foreach (var para in parameterValuePair)
engine.SetNamedItem(para.Key, para.Value);
}
dynamic value = parsed.CallMethod(key);
return (value != null) ? value.ToString() : string.Empty;
}
}
catch (Exception ex)
{
throw;
}
}
}
如果我用這樣的,它的正常工作:
static void Main(string[] args)
{
string key = "necGlobalValue";
string script = @"necGlobalValue = ""ADMIN""";
var result = VBScriptEvaluator.Evaluate(key, script, null); //ADMIN
}
喜歡這個作品也很好:
static void Main(string[] args)
{
Dictionary<string, object> parameterValuePair = new Dictionary<string, object>();
parameterValuePair.Add("ZINVOICE_MARGIN_0", 141615427.8);
parameterValuePair.Add("ZINVOICE_AMTNOTLIN_0", 187260276.84);
var script = @"If (ZINVOICE_AMTNOTLIN_0) <> 0 Then
SERVER_FLD0000001 = Abs(ZINVOICE_MARGIN_0)/ZINVOICE_AMTNOTLIN_0
else
SERVER_FLD0000001 = 0
End If";
var key = "SERVER_FLD0000001";
var result = VBScriptEvaluator.Evaluate(key, script, parameterValuePair);
}
在前面的庫它會自動檢測的類型將被評估的變量。我可以傳遞整數作爲字符串,它會工作得很好。
如果我更換字典像使用ScripEngine值時,它會失敗:
Dictionary<string, object> parameterValuePair = new Dictionary<string, object>();
parameterValuePair.Add("ZINVOICE_MARGIN_0", "141615427.8");
parameterValuePair.Add("ZINVOICE_AMTNOTLIN_0", "187260276.84");
而且,如果我這樣做,我沒有收到用戶ADMIN。
string key = "necGlobalValue";
string script = @"necGlobalValue = ""NecUserProfile""";
var result = VBScriptEvaluator.Evaluate(key, script, null); // output NecUserProfile instead of ADMIN
而且BTW我試着給儘可能多的細節,這就是爲什麼這個問題是那麼長。
雖然ScriptEngine的是基於相同的(舊)基本技術爲MSScriptControl(「ActiveX腳本」),他們可能會在某些方面有所不同。但是,它不應該是這樣的問題。在你的例子中,ScriptEngine按預期工作。但是命名項通常用於複雜的對象(如HTML中的'document'或ASP中的'Request'),而不是像字符串或整數這樣的整體對象。如果要傳遞標準參數,請在函數中聲明它們,並使用CallMethod傳遞它們。另外,出於性能原因,您希望保留解析對象,而不是在每次調用時分析。 –
這就是我最後所做的,它的工作很好(使用參數代替'SetNamedItem')。我只是沒有時間回答我自己的問題。順便說一句,我想感謝你的圖書館,這真棒。 – billybob
是否將MSScriptControl放入32位dllhost.exe允許它在沒有任何附加代碼的情況下工作?理論上它應該。 – 2016-09-27 00:23:59