64ビットに移行しようとしている32ビットサービスがありました。CodeFluentとInterop.MSScriptControl.dll
ユーザーが作成したVBスクリプトを評価するのにInterop.MSScriptControl.dll
を使用しています。
MSScriptControl
の64ビットバージョンがないため、私はサービス内で呼び出されたプロセスを作成しました。ユーザースクリプトを評価する必要があるたびに、プロセスを呼び出します。この解決策を試した後、私はそれが本当に遅いと感じました。
私はちょうど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
私は多くの詳細を与えようとしましたが、その理由はそれほど長いことです。
たScriptEngineがMSScriptControl(「ActiveXのスクリプティング」)と同じ(旧)基本的な技術に基づいているが、彼らはいくつかの点で異なる場合があります。しかし、それはそのような問題であってはならない。あなたの例では、ScriptEngineは期待通りに動作します。しかし、名前付きアイテムは一般に複雑なオブジェクト(HTMLの 'document'やASPの 'Request'など)に使用され、文字列や整数などの整数オブジェクトでは使用されません。標準パラメータを渡したい場合は、関数で宣言し、CallMethodで渡します。また、パフォーマンス上の理由から、各呼び出し時に解析するのではなく、解析されたオブジェクトを保持する必要があります。 –
これは私が最後にやったことです。うまく動いています( 'SetNamedItem'ではなくパラメータを使用しています)。私は自分の質問に答える時間がなかっただけです。そしてbtw、私は図書館に感謝したい、それは素晴らしいです。 – billybob
MSScriptControlを32ビットdllhost.exeに入れると、追加コードなしで動作するのですか?理論的にはそれはすべきです。 –