I use following to compile C# in runtime:
CompilerParameters parameters = new CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = true,
IncludeDebugInformation = true
};
// True - memory generation, false - external file generation
// True - exe file generation, false - dll file generation
var res = pro.CompileAssemblyFromSource(parameters,
code);
Assembly assembly = res.CompiledAssembly;
Type program = assembly.GetType("First.Program");
MethodInfo main = program.GetMethod("Main");
var invoke = main?.Invoke(null, null);
res.Output is an empty list, and If the code has Console.WriteLine(), It gets written to main application's console, however; I wanna grab what is written.
You also should check res.Errors. If there are errors, then they will be there instead. If both Errors and Output are empty, then you may have had a successful compilation without any output. Check: cr.NativeCompilerReturnValue.ToString()
Related
I have the following code taking the input of my input file:
var inputStream = new AntlrInputStream(File.ReadAllText(fileName));
var lexer = new LegitusLexer(inputStream);
var commonTokenStream = new CommonTokenStream(lexer);
var parser = new LegitusParser(commonTokenStream);
parser.AddErrorListener(this);
var context = parser.program();
var visitor = new LegitusVisitor(_io.GetDefaultMethods(), _io.GetDefaultVariables())
{
Logger = _logger
};
visitor.Visit(context);
But when I call parser.program(), my program runs as it should. However, I need a way to validate that the input file is syntactically correct, so that users can verify without having to run the scripts (which run against a special machine).
Does Antlr4csharp support this easily?
The Antlr tool can be used to lint the source.
The only difference from a 'standard' tool run is that no output files are generated -- the warnings/errors will be the same.
For example (Java; string source content w/manually applied file 'name'):
Tool tool = new Tool();
tool.removeListeners();
tool.addListener(new YourLintErrorReporter());
ANTLRStringStream in = new ANTLRStringStream(content);
GrammarRootAST ast = tool.parse(name, in);
Grammar g = tool.createGrammar(ast);
g.fileName = name; // to ensure all err msgs identify the file by name
tool.process(g, false); // false -> lint: don't gencode
The CS implementation is equivalent.
I have a large number of async target wrappers created like this:
var fileTarget = new FileTarget("file_"+unique_id)
{
FileName = $"{unique_id}.log"),
Layout = layout_string,
DeleteOldFileOnStartup = false,
KeepFileOpen = true,
AutoFlush = false
};
var asyncFileTarget =
new NLog.Targets.Wrappers.AsyncTargetWrapper(fileTarget, 10000, NLog.Targets.Wrappers.AsyncTargetWrapperOverflowAction.Block);
asyncFileTarget.Name = unique_id;
m_job_logger_factory.Configuration.AddTarget(asyncFileTarget);
m_job_logger_factory.Configuration.AddRule(TranslateEnum(logLevel), NLog.LogLevel.Fatal, asyncFileTarget, assignedLogger.Name);
m_job_logger_factory.ReconfigExistingLoggers();
Each target has a separate logger assigned to it.
Then I log a couple of lines to each of the created targets through their assigned loggers.
Nothing is logged to the file yet, as they are async, and the queue is not full.
Now, if I do
Target t = m_job_logger_factory.Configuration.FindTargetByName(unique_id);
t.Flush((e) => { });
I'd expect only the unique_id file to have the new logs, instead I find all the files updated (as if I had called flush on the LogManager/LogFactory, and not this specific target).
Is this configuration incorrect or is this a bug with target.Flush(AsyncContinuation)?
Since CompileAssemblyFromSource add custom functions in a smart way was ignored im going to ask this question differently so people will bother to read it.
cutting at the chase,i am making a language by "translating" the new syntax into c# and compiling it in memory in this fashion.
using (Microsoft.CSharp.CSharpCodeProvider CodeProv =
new Microsoft.CSharp.CSharpCodeProvider())
{
CompilerResults results = CodeProv.CompileAssemblyFromSource(
new System.CodeDom.Compiler.CompilerParameters()
{
GenerateInMemory = true
},
code);
var type = results.CompiledAssembly.GetType("MainClass");
var obj = Activator.CreateInstance(type);
var output = type.GetMethod("Execute").Invoke(obj, new object[] { });
Console.WriteLine(output);
}
basically i am executing a "main" function written inside the code variable.
and i am using some functions in the code variable i would like to include without adding it as a string at the bottom like this:
code += #"public void Write(string path, object thevar)
{
if (thevar.GetType() == typeof(string))
{
System.IO.File.WriteAllText(path,(string)thevar);
}
if (thevar.GetType() == typeof(string[]))
{
System.IO.File.WriteAllLines(path,(string[])thevar);
}
}";
Can i somehow add a class from my Actual main project in VS and let the compiled in memory code access it? without adding it as a string.
You can embed your source code file(s) as resources. With this technique you can edit the file in Visual Studio and access the contents of the files as if it was a string during run-time.
This link shows how to do it:
https://stackoverflow.com/a/433182/540832
I am trying to create a DLL file in runtime ,as a matter of fact i need to save an encoded data to DLL .My code is like this :
class DllFile
{
public static void CreateDllFile(string source)
{
var provider = new CSharpCodeProvider();
var options = new CompilerParameters
{
OutputAssembly = "test.dll"
};
var results = provider.CompileAssemblyFromSource(options, new[] { source });
}
}
I expect from this code to create a dll file but it doesn't create
The error is :The pointer for this method was null
Best regards.Any ideas will be appreciated.
Compilation errors are reported via the returned value:
var results = provider.CompileAssemblyFromSource(options, new[] { source });
Now check results, and in particular results.Errors.
You can also check results.NativeCompilerReturnValue - that should be 0 for success, and non-zero for failure.
Any errors would be in the Errors property of the CompilerResults returned from the CompileAssemblyFromSource method. Have you tried printing them out to see if there are errors ?
CompilerResults results = provider.CompileAssemblyFromSource(options, new[] { source });
foreach(CompilerError error in results.Errors)
{
Console.WriteLine(error.ToString());
}
I am converting a minification function from visual basic:
example = Yahoo.Yui.Compressor.JavaScriptCompressor.Compress(someString, False, True, True, True, -1, UTF8Encoding.UTF8, Globalization.CultureInfo.InvariantCulture)
to c#. However, the compress method in c# only takes a string argument and has no overload methods. Is the below code in c# equivalent to the original VB code above?
var compressor = new Yahoo.Yui.Compressor.JavaScriptCompressor();
example = compressor.Compress(someString);
The equivalent in C#, as far as I can tell from the source, would require you to set the respective properties in the JavaScriptCompressor instance yourself instead of passing them to the (seemingly non-existent) static Compress method. For example:
var compressor = new Yahoo.Yui.Compressor.JavaScriptCompressor
{
Encoding = UTF8Encoding.UTF8,
DisableOptimizations = false,
ObfuscateJavascript = true,
PreserveAllSemicolons = true,
IgnoreEval = true,
ThreadCulture = Globalization.CultureInfo.InvariantCulture
};
var example = compressor.Compress(someString);
The Boolean properties may not be in the same order as they were previously, so I just guessed. There's a JavaScriptCompressorConfig class in the library with these properties but I couldn't find how it would get passed to the compressor.
You are calling the static Yahoo.Yui.Compressor.JavaScriptCompressor.Compress method in VB.NET and instanciating a Yahoo.Yui.Compressor.JavaScriptCompressor class in C#.
You can call Yahoo.Yui.Compressor.JavaScriptCompressor.Compress in C# to reproduce the same behavior.