I've read through the discussion at The calling thread cannot access this object because a different thread owns it but it's all about UI.
I have two C# EXEs that are purely command-line, but are throwing this error as well.
Perhaps the full exception message will help:
System.InvalidOperationException
HResult=0x80131509
Message=The calling thread cannot access this object because a different thread owns it.
Source=WindowsBase
StackTrace:
at System.Windows.Threading.Dispatcher.VerifyAccess()
at Microsoft.ClearScript.Windows.WindowsScriptEngine.Dispose(Boolean disposing)
at Microsoft.ClearScript.ScriptEngine.Finalize()
This exception was originally thrown at this call stack:
[External Code]
This would seem to imply, to my un-educated eye, that the problem is not in my code but in the ClearScript finalization code. Yes, these are ClearScript-enabled applications which attach to Windows JScript interpreter to provide run-time extensions.
Suggestions welcome.
LATER
Code was requested. Here it is, slightly redacted.
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Security.Permissions;
using System.Text;
using Microsoft.ClearScript.Windows;
namespace NormanEmailHandler
{
internal static class Program
{
private static JScriptEngine JSengine;
private static Dictionary<string, object>
Settings = new Dictionary<string, object>();
public static string ProcessName = Process.GetCurrentProcess().ProcessName;
public static string
UserDomain = Environment.GetEnvironmentVariable("USERDOMAIN");
public static string DomainProcess = "[" + UserDomain + "] " + ProcessName;
private static void JSSetup(JScriptEngine jse)
{
jse.AddHostType("CSString", typeof (String));
jse.AddHostType("CSConsole", typeof (Console));
jse.AddHostType("CSFile", typeof (File));
jse.AddHostType("CSFileInfo", typeof (FileInfo));
jse.AddHostType("CSDirectory", typeof (Directory));
jse.AddHostType("CSPath", typeof (Path));
jse.AddHostType("CSSearchOption", typeof (SearchOption));
jse.AddHostType("CSEncoding", typeof (Encoding));
jse.AddHostType("CSMemoryStream", typeof (MemoryStream));
jse.AddHostObject("CSSettings", Settings);
jse.AddHostType("CSTimeSpan", typeof (TimeSpan));
jse.AddHostType("CSConfig", typeof (Config));
jse.AddHostType("CSThread", typeof (System.Threading.Thread));
}
private static void MyHandler(
object sender,
UnhandledExceptionEventArgs args
)
{
Exception e = (Exception) args.ExceptionObject;
var msgBlock = new StringBuilder();
msgBlock
.Append("[")
.Append(Environment.GetEnvironmentVariable("USERDOMAIN"))
.Append("] ")
.Append(Process.GetCurrentProcess().ProcessName)
.Append(" ")
.AppendLine(e.Message);
msgBlock.Append(sender).AppendLine();
msgBlock.AppendLine(e.StackTrace);
msgBlock
.AppendLine(e.InnerException == null ? e.InnerException.Message : "");
msgBlock
.Append("Runtime terminating: ")
.Append(args.IsTerminating)
.AppendLine();
T.Inform(msgBlock.ToString()); // T is a logging tool
}
[
SecurityPermission(
SecurityAction.Demand,
Flags = SecurityPermissionFlag.ControlAppDomain)
]
private static void Main(string[] args)
{
var currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += MyHandler;
config = new Config();
config.SetErrorOnNull(true);
config
.Reload(Path
.Combine(".\\Configuration", Path.GetFileName(config.Path)));
Dictionary<string, string> Params =
CommandLineArguments.Arguments(keepSlash: true);
if (Params.ContainsKey("/DEBUG"))
{
Debugger.Launch();
}
string connectionString = config.Retrieve("connection.string");
string MarshallerEmailHandler = config.Retrieve("marshaller.sproc");
string MarshallerEmailHandler_01_StartUpdate =
config.Retrieve("start.sproc");
string MarshallerEmailHandler_03_FinishUpdate =
config.Retrieve("finish.sproc");
T.Inform("Attempting to instantiate JScriptEngine");
try
{
JSengine =
new JScriptEngine(WindowsScriptEngineFlags.EnableDebugging |
WindowsScriptEngineFlags.EnableJITDebugging);
T.Inform("Succesfully instantiated JScriptEngine");
}
catch (Exception exc)
{
T
.Fail("Failed to instantiate JScriptEngine",
exc.Message,
exc.Source,
exc.StackTrace,
exc.InnerException.Message);
return;
}
JSSetup (JSengine); // JSengine);
JSengine.AddHostObject("T", T);
SQL sqlServer = new SQL(connectionString);
Settings["CSDatabase"] = sqlServer;
string sql;
while (true)
{
sql = "EXEC " + MarshallerEmailHandler;
T.Inform($"Attempting to execute {sql}");
DataTable dt = sqlServer.DTEval(sql, 60, 3);
if (sqlServer.LastError == null)
{
T.Inform($"Successfully executed {sql}");
}
else
{
T.Fail($"Failed to execute {sql} : {sqlServer.LastError.Message}");
break;
}
if (dt.Rows == null || dt.Rows.Count == 0)
{
T.Inform("No records marshalled");
break;
}
foreach (DataRow dr in dt.Rows)
{
SQL.UpdateDictionaryFromDataRow(ref Settings, dr);
int RetrievedEmailID = (int) dr["RetrievedEmailID"];
int EmailRetrievalControllerFK =
(int) dr["EmailRetrievalControllerFK"];
int database_UserFK = (int) dr["database_UserFK"];
int EmailRetrievalUserID = (int) dr["EmailRetrievalUserID"];
string RetrievedEmailMessageID =
(string) dr["RetrievedEmailMessageID"];
string RetrievedEmailFrom = (string) dr["RetrievedEmailFrom"];
string RetrievedEmailTOs = (string) dr["RetrievedEmailTOs"];
string RetrievedEmailCCs = (string) dr["RetrievedEmailCCs"];
string RetrievedEmailSubject = (string) dr["RetrievedEmailSubject"];
string RetrievedEmailBody = (string) dr["RetrievedEmailBody"];
string ThisName = (string) dr["ThisName"];
string EmailHandlingRuleSetJson =
(string) dr["EmailHandlingRuleSetJson"];
string EmailHandlingSourceName =
(string) dr["EmailHandlingSourceName"];
//start the job
sql =
"EXEC " +
MarshallerEmailHandler_01_StartUpdate +
" " +
RetrievedEmailID;
T.Inform($"Attempting to execute {sql}");
sqlServer.Exec(sql, 60, 3);
if (sqlServer.LastError == null)
{
T.Inform($"Successfully executed {sql}");
}
else
{
T.Fail($"Failed to execute {sql} : {sqlServer.LastError.Message}");
break;
}
string script =
Path
.Combine(@"C:\Web\Data\RetrievedEmails\RuleSets",
"EmailHandler.js");
T.Inform("Attempting to execute ruleset script:", script);
string errorMsg = string.Empty;
string scriptText = File.ReadAllText(script);
object answer = JSengine.Evaluate(scriptText);
if (answer.ToString() == "OK")
{
T.Inform("Script OK.");
sql =
"EXEC " +
MarshallerEmailHandler_03_FinishUpdate +
" " +
RetrievedEmailID;
T.Inform($"Attempting to execute {sql}");
sqlServer.Exec(sql, 60, 3);
if (sqlServer.LastError != null)
{
T
.Fail($"Failed to execute {sql} : {
sqlServer.LastError.Message}");
}
else
{
T.Inform($"Successfully executed {sql}");
}
}
else
{
string msg =
string
.Format("Handler: ruleset {0} failure: RetrievedEmailID={2}\nEmailRetrievalControllerFK={3}\ndatabase_UserFK={4}\nEmailRetrievalUserID={5}",
script,
string.Empty,
RetrievedEmailID,
EmailRetrievalControllerFK,
database_UserFK,
EmailRetrievalUserID);
T.Fail (msg);
}
}
}
sqlServer.Close();
}
}
}
Given some of the comments, I expect that object answer = JSengine.Evaluate(scriptText);
is the offending line and that extra bits need to be added to that invocation.
User contributions licensed under CC BY-SA 3.0