2015-09-03 2 views
2

Мое приложение компилирует часть кода javascript из исходного файла на лету с помощью CodeDom. В Windows все работает нормально. Но запуск приложения на Linux заканчивается тем, что он бросает InvalidOperationException, что не дает никакой полезной информации для отладки. В чем причина этой ситуации?CodeDom.CompileAssemblyFromSource throws weird error

Я тестировал приложение на Debian Jessie с Mono 4.0.x

private JScriptCodeProvider compiler = new JScriptCodeProvider(); 
private CompilerParameters parameters = new CompilerParameters(); 

Параметры:

parameters.ReferencedAssemblies.Add("System.dll"); 
parameters.GenerateExecutable = false; 
parameters.GenerateInMemory = true; 

компилирования:

// This line throws InvalidOperationException 
var result = compiler.CompileAssemblyFromSource(parameters, scriptCode); 

Трассировка информация:

e 
{System.InvalidOperationException: Process has not been started. 
at System.Diagnostics.Process.get_ExitCode() [0x00015] in <filename 
unknown>:0  

at (wrapper remoting-invoke-with-check) 
System.Diagnostics.Process:get_ExitCode() 

at System.CodeDom.Compiler.Executor.InternalExecWaitWithCapture 
(System.String cmd, System.String currentDir, 
System.CodeDom.Compiler.TempFileCollection tempFiles, System.String& 
outputName, System.String& errorName) [0x000f1] in <filename 
unknown>:0  

at System.CodeDom.Compiler.Executor.ExecWaitWithCapture 
(System.String cmd, System.CodeDom.Compiler.TempFileCollection 
tempFiles, System.String& outputName, System.String& errorName) 
[0x00006] in <filename unknown>:0  

at System.CodeDom.Compiler.CodeCompiler.Compile 
(System.CodeDom.Compiler.CompilerParameters options, System.String[] 
fileNames, Boolean keepFiles) [0x0009c] in <filename unknown>:0  

at System.CodeDom.Compiler.CodeCompiler.FromSourceBatch 
(System.CodeDom.Compiler.CompilerParameters options, System.String[] 
sources) [0x0006b] in <filename unknown>:0  

at System.CodeDom.Compiler.CodeCompiler.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch 
(System.CodeDom.Compiler.CompilerParameters options, System.String[] 
sources) [0x00000] in <filename unknown>:0  

at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource 
(System.CodeDom.Compiler.CompilerParameters options, System.String[] 
sources) [0x00014] in <filename unknown>:0  

at ***.ScriptEngine.compile() [0x00036] in 
***ScriptEngine.cs:139 }  
System.InvalidOperationException 

ответ

0

По некоторым причинам CodeDom не смог создать новый процесс для компиляции исходного кода во временную сборку. Я предполагаю, что что-то пошло не так, когда вы имеете дело с разрешением. След. След.:

converting method System.CodeDom.Compiler.Executor:ExecWaitWithCapture (string,System.CodeDom.Compiler.TempFileCollection,string&,string&) 
Method System.CodeDom.Compiler.Executor:ExecWaitWithCapture (string,System.CodeDom.Compiler.TempFileCollection,string&,string&) emitted at 0x42060b90 to 0x42060bd5 (code length 69) [MyApp.exe] 
converting method System.CodeDom.Compiler.Executor:InternalExecWaitWithCapture (string,string,System.CodeDom.Compiler.TempFileCollection,string&,string&) 
Method System.CodeDom.Compiler.Executor:InternalExecWaitWithCapture (string,string,System.CodeDom.Compiler.TempFileCollection,string&,string&) emitted at 0x42060c00 to 0x42061080 (code length 1152) [MyApp.exe] 
converting method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:.ctor() 
Method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:.ctor() emitted at 0x42061150 to 0x42061189 (code length 57) [MyApp.exe] 
converting method System.Diagnostics.Process:.ctor() 
Method System.Diagnostics.Process:.ctor() emitted at 0x420611a0 to 0x420611b5 (code length 21) [MyApp.exe] 
converting method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_StartInfo() 
Method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_StartInfo() emitted at 0x420611c0 to 0x42061222 (code length 98) [MyApp.exe] 
converting method System.Diagnostics.Process:get_StartInfo() 
Method System.Diagnostics.Process:get_StartInfo() emitted at 0x42061240 to 0x420612d0 (code length 144) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:.ctor() 
Method System.Diagnostics.ProcessStartInfo:.ctor() emitted at 0x420612e0 to 0x42061302 (code length 34) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:.cctor() 
Method System.Diagnostics.ProcessStartInfo:.cctor() emitted at 0x42061310 to 0x42061338 (code length 40) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:set_FileName (string) 
Method System.Diagnostics.ProcessStartInfo:set_FileName (string) emitted at 0x42061340 to 0x420613a0 (code length 96) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:set_CreateNoWindow (bool) 
Method System.Diagnostics.ProcessStartInfo:set_CreateNoWindow (bool) emitted at 0x420613a0 to 0x420613bf (code length 31) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:set_UseShellExecute (bool) 
Method System.Diagnostics.ProcessStartInfo:set_UseShellExecute (bool) emitted at 0x420613c0 to 0x420613df (code length 31) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:set_RedirectStandardOutput (bool) 
Method System.Diagnostics.ProcessStartInfo:set_RedirectStandardOutput (bool) emitted at 0x420613e0 to 0x420613ff (code length 31) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:set_RedirectStandardError (bool) 
Method System.Diagnostics.ProcessStartInfo:set_RedirectStandardError (bool) emitted at 0x42061400 to 0x4206141f (code length 31) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:set_WorkingDirectory (string) 
Method System.Diagnostics.ProcessStartInfo:set_WorkingDirectory (string) emitted at 0x42061420 to 0x42061480 (code length 96) [MyApp.exe] 
converting method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:Start() 
Method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:Start() emitted at 0x42061480 to 0x420614e2 (code length 98) [MyApp.exe] 
converting method System.Diagnostics.Process:Start() 
Method System.Diagnostics.Process:Start() emitted at 0x42061500 to 0x42061555 (code length 85) [MyApp.exe] 
converting method System.Diagnostics.Process:Start_common (System.Diagnostics.ProcessStartInfo,System.Diagnostics.Process) 
Method System.Diagnostics.Process:Start_common (System.Diagnostics.ProcessStartInfo,System.Diagnostics.Process) emitted at 0x42061560 to 0x420616d0 (code length 368) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_FileName() 
Method System.Diagnostics.ProcessStartInfo:get_FileName() emitted at 0x42061730 to 0x4206175e (code length 46) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_StandardErrorEncoding() 
Method System.Diagnostics.ProcessStartInfo:get_StandardErrorEncoding() emitted at 0x42061760 to 0x42061774 (code length 20) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_StandardOutputEncoding() 
Method System.Diagnostics.ProcessStartInfo:get_StandardOutputEncoding() emitted at 0x42061780 to 0x42061794 (code length 20) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_UseShellExecute() 
Method System.Diagnostics.ProcessStartInfo:get_UseShellExecute() emitted at 0x420617a0 to 0x420617b4 (code length 20) [MyApp.exe] 
converting method System.Diagnostics.Process:Start_noshell (System.Diagnostics.ProcessStartInfo,System.Diagnostics.Process) 
Method System.Diagnostics.Process:Start_noshell (System.Diagnostics.ProcessStartInfo,System.Diagnostics.Process) emitted at 0x420617c0 to 0x420630d8 (code length 6424) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_HaveEnvVars() 
Method System.Diagnostics.ProcessStartInfo:get_HaveEnvVars() emitted at 0x420631c0 to 0x420631e9 (code length 41) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_RedirectStandardInput() 
Method System.Diagnostics.ProcessStartInfo:get_RedirectStandardInput() emitted at 0x420631f0 to 0x42063204 (code length 20) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_RedirectStandardOutput() 
Method System.Diagnostics.ProcessStartInfo:get_RedirectStandardOutput() emitted at 0xto 0x42063224 (code length 20) [MyApp.exe] 
converting method System.Diagnostics.Process:get_IsWindows() 
Method System.Diagnostics.Process:get_IsWindows() emitted at 0x42063230 to 0x4206327a (code length 74) [MyApp.exe] 
converting method (wrapper managed-to-native) System.IO.MonoIO:CreatePipe (intptr&,intptr&) 
Method (wrapper managed-to-native) System.IO.MonoIO:CreatePipe (intptr&,intptr&) emitted at 0x42063280 to 0x4206330d (code length 141) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_RedirectStandardError() 
Method System.Diagnostics.ProcessStartInfo:get_RedirectStandardError() emitted at 0x42063310 to 0x42063324 (code length 20) [MyApp.exe] 
converting method System.Diagnostics.Process:FillUserInfo (System.Diagnostics.ProcessStartInfo,System.Diagnostics.Process/ProcInfo&) 
Method System.Diagnostics.Process:FillUserInfo (System.Diagnostics.ProcessStartInfo,System.Diagnostics.Process/ProcInfo&) emitted at 0x42063330 to 0x42063468 (code length 312) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_UserName() 
Method System.Diagnostics.ProcessStartInfo:get_UserName() emitted at 0x42063490 to 0x420634be (code length 46) [MyApp.exe] 
converting method (wrapper managed-to-native) System.Diagnostics.Process:CreateProcess_internal (System.Diagnostics.ProcessStartInfo,intptr,intptr,intptr,System.Diagnostics.Process/ProcInfo&) 
Method (wrapper managed-to-native) System.Diagnostics.Process:CreateProcess_internal (System.Diagnostics.ProcessStartInfo,intptr,intptr,intptr,System.Diagnostics.Process/ProcInfo&) emitted at 0x420634c0 to 0x42063570 (code at System.Diagnostics.Process.get_ExitCode() [0x00000] in <filename unknown>:0 
    at (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ExitCode() 
    at System.CodeDom.Compiler.Executor.InternalExecWaitWithCapture (System.String cmd, System.String currentDir, System.CodeDom.Compiler.TempFileCollection tempFiles, System.String& outputName, System.String& errorName) [0x00000] in <filename unknown>:0 
    at System.CodeDom.Compiler.Executor.ExecWaitWithCapture (System.String cmd, System.CodeDom.Compiler.TempFileCollection tempFiles, System.String& outputName, System.String& errorName) [0x00000] in <filename unknown>:0 
    at System.CodeDom.Compiler.CodeCompiler.Compile (System.CodeDom.Compiler.CompilerParameters options, System.String[] fileNames, Boolean keepFiles) [0x00000] in <filename unknown>:0 
    at System.CodeDom.Compiler.CodeCompiler.FromSourceBatch (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x00000] in <filename unknown>:0 
    at System.CodeDom.Compiler.CodeCompiler.System.CodeDom.Compiler.ICodeCompiler.CompileAssemblyFromSourceBatch (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x00000] in <filename unknown>:0 
    at System.CodeDom.Compiler.CodeDomProvider.CompileAssemblyFromSource (System.CodeDom.Compiler.CompilerParameters options, System.String[] sources) [0x00000] in <filename unknown>:0 
    at com.example.myapp.ScriptEngine.compile() [0x00000] in <filename unknown>:0 
length 176) [MyApp.exe] 
converting method (wrapper managed-to-native) object:__icall_wrapper_mono_helper_ldstr (intptr,intptr) 
Method (wrapper managed-to-native) object:__icall_wrapper_mono_helper_ldstr (intptr,intptr) emitted at 0x42063570 to 0x420635f9 (code length 137) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_Arguments() 
Method System.Diagnostics.ProcessStartInfo:get_Arguments() emitted at 0x42063600 to 0x4206362e (code length 46) [MyApp.exe] 
converting method System.Diagnostics.ProcessStartInfo:get_WorkingDirectory() 
Method System.Diagnostics.ProcessStartInfo:get_WorkingDirectory() emitted at 0x42063630 to 0x4206365e (code length 46) [MyApp.exe] 
converting method (wrapper managed-to-native) System.ComponentModel.Win32Exception:W32ErrorMessage (int) 
Method (wrapper managed-to-native) System.ComponentModel.Win32Exception:W32ErrorMessage (int) emitted at 0x42063660 to 0x420636e1 (code length 129) [MyApp.exe] 
converting method System.ComponentModel.Win32Exception:.ctor (int,string) 
Method System.ComponentModel.Win32Exception:.ctor (int,string) emitted at 0x420636f0 to 0x42063727 (code length 55) [MyApp.exe] 
converting method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ExitCode() 
Method (wrapper remoting-invoke-with-check) System.Diagnostics.Process:get_ExitCode() emitted at 0x42063740 to 0x420637a2 (code length 98) [MyApp.exe] 
converting method System.Diagnostics.Process:get_ExitCode() 
Method System.Diagnostics.Process:get_ExitCode() emitted at 0x420637c0 to 0x42063864 (code length 164) [MyApp.exe] 
converting method (wrapper managed-to-native) System.Diagnostics.StackTrace:get_trace (System.Exception,int,bool) 
Method (wrapper managed-to-native) System.Diagnostics.StackTrace:get_trace (System.Exception,int,bool) emitted at 0x42063890 to 0x42063924 (code length 148) [MyApp.exe] 

Мне казалось, что пришло время попробовать что-то новое. Затем я изменил свой код, как показано ниже:

#if LINUX 
bool writeOk = true; 
string tmpScriptName = String.Format("/tmp/com.myapp.script-{0}.js", Environment.TickCount); 
try { 
    File.WriteAllText(tmpScriptName, scriptCode); 
} catch (Exception) { 
    writeOk = false; 
} finally { 
    if (writeOk) { 
     result = compiler.CompileAssemblyFromFile(parameters, tmpScriptName); 
     try { 
      File.Delete(tmpScriptName); 
     } catch (Exception) { } 
    } 
} 

#else 
result = compiler.CompileAssemblyFromSource(parameters, scriptCode); 
#endif 

К счастью, он снова работает.

1

Codedom является немного странным в Linux. Он не реализован так же, как в Windows, и это, если его реализовать вообще. Если вы намереваетесь сделать кросс-платформенное приложение, я бы предложил либо Mono's compiler as a service, либо CS-Script's более дружественную реализацию. Компилятор как служба плохо документирован и не работает так же, как компилятор времени выполнения Microsoft. CS-Script - это оболочка для компиляторов Microsoft и Mono, и она хорошо документирована и прямолинейна.