Can someone help me with this issue?
I currently working on my project for final year of my honors degree. And we are developing a application to evaluate programming assignments of student ( for 1st year student level)
I just want to know how to integrate C++ compiler using C# code to compile C++ code.
In our case we are loading a student C++ code into text area, then with a click on button we want to compile the code. And if there any compilation errors it will be displayed on text area nearby. (Interface is attached herewith.)
And finally it able to execute the code if there aren't any compilation errors. And results will be displayed in console.
We were able to do this with a C#(C# code will be loaded to text area intead of C++ code) code using inbuilt compiler. But still not able to do for C# code.
Can anyone suggest a method to do this? It is possible to integrate external compiler to VS C# code? If possible how to achieve it?
Very grateful if anyone will contributing to solve this matter?
This is code for Build button which we proceed with C# code compiling
CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("csharp");
string Output = "Out.exe";
Button ButtonObject = (Button)sender;
rtbresult.Text = "";
System.CodeDom.Compiler.CompilerParameters parameters = new CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, rtbcode.Text);
if (results.Errors.Count > 0)
{
rtbresult.ForeColor = Color.Red;
foreach (CompilerError CompErr in results.Errors)
{
rtbresult.Text = rtbresult.Text +
"Line number " + CompErr.Line +
", Error Number: " + CompErr.ErrorNumber +
", '" + CompErr.ErrorText + ";" +
Environment.NewLine + Environment.NewLine;
}
}
else
{
//Successful Compile
rtbresult.ForeColor = Color.Blue;
rtbresult.Text = "Success!";
//If we clicked run then launch our EXE
if (ButtonObject.Text == "Run") Process.Start(Output); // Run button
}
there is unfortunately no default implementation for CodeDom for C++, you can always define your own if you want to use the same code as the above to compile C++.
Or you can call cl.exe directly, In both cases you would have to manually invoke cl.exe
http://msdn.microsoft.com/en-us/library/19z1t1wy(v=VS.71).aspx
It shouldn't that hard. write the code to a temporary file, call cl.exe pipe any output to a window you want (or not) and the end, check if a exe has been produced, if it has compilation succeeded and you can run the exe, if not it failed and the error should be in the log you created earlier.
It's less structured than above but it's by far the easiest way.
-- more detailed
the following code assumes your environment vars are properly set. http://msdn.microsoft.com/en-us/library/f2ccy3wt(VS.80).aspx
class CL
{
private const string clexe = #"cl.exe";
private const string exe = "Test.exe", file = "test.cpp";
private string args;
public CL(String[] args)
{
this.args = String.Join(" ", args);
this.args += (args.Length > 0 ? " " : "") + "/Fe" + exe + " " + file;
}
public Boolean Compile(String content, ref string errors)
{
//remove any old copies
if (File.Exists(exe))
File.Delete(exe);
if(File.Exists(file))
File.Delete(file);
File.WriteAllText(file, content);
Process proc = new Process();
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.StartInfo.FileName = clexe;
proc.StartInfo.Arguments = this.args;
proc.StartInfo.CreateNoWindow = true;
proc.Start();
//errors += proc.StandardError.ReadToEnd();
errors += proc.StandardOutput.ReadToEnd();
proc.WaitForExit();
bool success = File.Exists(exe);
return success;
}
}
this will compile the code given to it, but it's just a sample, everytime compilation succeeds there will be a file "Test.exe" which you can run. when it fails the "errors" variable will contain the error message.
hope this helps,
for more information on running processes, take a look at http://www.codeproject.com/KB/cs/ProcessStartDemo.aspx
Related
1-) I create a Python .exe which includes this code:
def main():
args = parse_arguments()
result = []
paths = args.files
regions = args.regions
oddplate = args.oddplate
result = []
#print ("Input args ")
#print (args)
#print ("\n")
if not args.sdk_url and not args.api_key:
raise Exception('api-key is required')
if len(paths) == 0:
print('File {} does not exist.'.format(args.FILE))
return
elif args.blur_dir and not os.path.exists(args.blur_dir):
print('{} does not exist'.format(args.blur_dir))
return
....
print(result)
return result
2-) Then, i create a c# function from .net (lets call it ProcessFunc), which includes this code
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo();
// make sure we can read the output from stdout and that window is not shown
myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardOutput = true;
myProcessStartInfo.CreateNoWindow = true;
myProcessStartInfo.FileName = dir_app;
// start python app with 9 arguments
myProcessStartInfo.Arguments = " " + Iapi_key + " " + Isdk_url + " " + Iregions + " " + Iblur_amount + " " + Ioddplate + " " + Iblur_dir;
Process myProcess = new Process();
// assign start information to the process
myProcess.StartInfo = myProcessStartInfo;
// start the process
myProcess.Start();
// Read the standard output of the app we called.
// in order to avoid deadlock we will read output first
// and then wait for process terminate:
StreamReader myStreamReader = myProcess.StandardOutput;
string myString = myStreamReader.ReadLine();
/*if you need to read multiple lines, you might use:
string myString = myStreamReader.ReadToEnd() */
// wait exit signal from the app we called and then close it.
myProcess.WaitForExit();
myProcess.Close();
// write the output we got from python app
//Console.WriteLine("Value received from script: " + myString);
return myString;
3-) I have 3 drives, C,N(local machine) and Z (net shared drive)
Having c# code compiled (which generates a .exe) i called the python generated .exe 2 ways:
Double clicking the c# .exe after introducing that code in a main program (lets call it MyCProgramMain)
static void Main()
{
ProcessFunc();
}
This works correctly (Iblur_dir parameter path is accepted)
Generating a service:
static void Main()
{
System.Threading.Thread.CurrentThread.CurrentCulture = new
System.Globalization.CultureInfo("es-ES");
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
}
Which will create a Thead:
public MyService()
{
InitializeComponent();
HEjecucion = new Thread(classEjecucion.ProcessFunc);
HEjecucion.Start();
Afterwards i will start the generated Service.
When doing it this way, i will get this message in my log (for example):
Z:\2021-08-18\14 does not exist
This will only happen with paths in Z:\ drive, N:\ and C:\ will be accepted.
So, when calling the Python.exe through a Main program focused generated c# .exe
*os.path.exists(args.blur_dir)* understands the path exists
but if i call that same Python.exe through a Service generated with C#, it is unable to access args.blur_dir path
I have tried:
Creating a app.manifest in c#project which includes
(perhaps it was related to priviliges)
Playing around with myProcessStartInfo parameters to see if something could make
I have spent lot of time trying multiple things related to C# Process() parameters, but nothing seems to work in order to make the Service 'reach' the dir_blur path. ¿What else could i try?
You are alright guys! Problem was i was working on a remote desktop in where i was login with an specific user.
Service was automatically installed as 'Local system', and all i had to do was go to Services, in my service "properties" and in 'login' tab introduce credentials i use for remote desktop access.
I have an audio converter .exe that i want to wrap in a C# program, for UI and inputs etc.
To use the AudioConverter.exe, it is ran from the console with the suffix " < inputFile > ouputFile".
So the full line reads something like
C:\\User\Audioconverter.exe < song.wav > song.ogg
So far i have been able to start the converter succesfully outside of C#, I have managed to have the converter run via create process in C# in a hang state (without input and output files).
My code in C# thus far is pretty similar to the answers given on this site:
using System;
using System.Diagnostics;
namespace ConverterWrapper2
{
class Program
{
static void Main()
{
LaunchCommandLineApp();
}
static void LaunchCommandLineApp()
{
// For the example
const string ex1 = "C:\\Users\\AudioConverter.exe";
const string ex2 = "C:\\Users\\res\\song.wav";
const string ex3 = "C:\\Users\\out\\song.ogg";
// Use ProcessStartInfo class
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = false;
startInfo.UseShellExecute = false;
startInfo.FileName = "AudioConverter2.exe";
startInfo.WindowStyle = ProcessWindowStyle.Normal;
startInfo.Arguments = ex1 + " < " + ex2 + " > " + ex3; \\Process is ran successfully without the addition of input and output files, but hangs waiting for files.
try
{
using (Process exeProcess = Process.Start(startInfo))
{
exeProcess.WaitForExit();
}
}
catch
{
// Log error.
}
}
}
}
So far the converter exe hasnt been able to start up correctly, this leads me to ask the question are inputs for stdin different from arguments?
Regardless i need to mimic this style of input and would appreciate any information. I had assumed that i could just pass the input and output files as arguments but i havent had much luck.
startInfo.Arguments = ex1 + " < " + ex2 + " > " + ex3; \\Process is ran successfully without the addition of input and output files, but hangs waiting for files.
That won't work.
A.exe < B > C is not process A.exe called with arguments < B > C. It's rather a shell instruction to:
start A.exe without arguments,
read file B and redirect its contents to the new process' stdin and
write the new process' stdout to file C.
You have two options to do that in C#:
You can use the help of the shell, i.e., you can start cmd.exe with arguments /c C:\User\Audioconverter.exe < song.wav > song.ogg or
you can re-implement what the shell is doing in C#. A code example for that can be found in this related question:
redirecting output to the text file c#
I'm having a little bit of a problem with communication between C# and Python.
I'm passing some arguments to Python from C# using the following hacky code:
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase).Substring(6);
string pyUnintelligibilityPath = "\\unintelligibility.py";
string pyNeuralPredictorPath = "\\predict.py";
string clf = "\\clf.pkl";
public double unintelligibleProbability(string pyLocation, string msg)
{
FileStream tempMessage = new FileStream(path + "\\tempMessage.txt", FileMode.Create);
StreamWriter writer = new StreamWriter(tempMessage);
writer.WriteLine(msg);
writer.Close();
string args = path + pyUnintelligibilityPath + " " + path + clf + " " + path + "\\tempMessage.txt" + " " + path + "\\tempCoefficient.txt";
ProcessStartInfo start = new ProcessStartInfo();
start.FileName = pyLocation;
start.Arguments = args;
start.UseShellExecute = false;
start.RedirectStandardOutput = false;
start.RedirectStandardError = false;
Process process = Process.Start(start);
Thread.Sleep(5000);
double unintelligibility = Convert.ToDouble(File.ReadAllText(path + "\\tempCoefficient.txt").Replace('.', ','));
return unintelligibility;
}
Unfortunately, this solution is very inefficient in my situation (not even due to the fact that I don't have any code that checks if the file changes as that will be added later and it's not really the problem I'm having).
The thing is, the Python code takes a very long time to load the .pkl file before it can actually do anything useful (don't mind the unnecessary imports, I just reused this thing from some other file):
from sklearn.feature_extraction.text import TfidfTransformer, CountVectorizer, TfidfVectorizer
from sklearn.linear_model import LogisticRegression, SGDClassifier
from sklearn.svm import LinearSVC
from sklearn.cross_validation import cross_val_score
from sklearn.pipeline import Pipeline
from sklearn.decomposition import NMF, TruncatedSVD
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.pipeline import FeatureUnion
from sklearn.externals import joblib
import numpy as np
import pandas as pd
import codecs
import sys
clf = joblib.load(sys.argv[1])
data = codecs.open(sys.argv[2], encoding='utf-8', mode='r')
text = data.readlines()
data.close()
text = [x.strip() for x in text]
f = open(sys.argv[3], mode='w')
proba = clf.predict_proba(text)
for i in range(0, len(text)):
meme = proba[i,:]
memeNum = meme[1]/(meme[0]+meme[1])
f.write(str(memeNum.round(4)) + "\n")
f.close()
My question is, is it possible to re-write the code in a way that allows me to keep a Python script running in the background and C# just passing commands to it since reinitializing the script every single time I need to process a single message takes way too long.
Keep in mind that I would really like to not to use any network protocol-based solutions as that overcomplicates things to a point where it's not really worth it to me, I really don't care about doing this remotely or anything like that, everything's happenning locally. However, if it's the only option, then I guess I have no choice.
Try IronPython, it's a .Net - Python bridge. Or basicly you can access .net stuff from python or interpret python from c#.
I'm creating a service on VS2010, using .net framework 4.0 Client Profile. The target machine is Windows Server 2003 64 bits. This service move some files and then executes a process with System.Diagnostics.Process. The trouble is that, even if the taskmanager shows a process as starting, the executable never do whats was made for. Example code:
private void imprimir(string nombreImpresora, int copias, string nombreArchivo)
{
try
{
string copiasSumatra = "1,";
for (int i = 1; i < copias; i++)
{
copiasSumatra += "1,";
}
string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string comando = String.Format("-print-to \"{0}\" \"{1}\" -print-settings \"{2}odd,fit\" -silent", nombreImpresora, nombreArchivo, copiasSumatra);
string filename = '"' + Path.Combine(path, "SumatraPDF.exe") + '"';
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.WorkingDirectory = path;
proc.StartInfo.FileName = filename;
proc.StartInfo.Arguments = comando;
proc.StartInfo.RedirectStandardError = false;
proc.StartInfo.RedirectStandardOutput = false;
proc.StartInfo.UseShellExecute = true;
proc.StartInfo.ErrorDialog = false;
proc.Start();
proc.WaitForExit();
lc.writeToLog("Instruction executed. Exit code: " + proc.ExitCode);
}
catch (Exception ex)
{
lc.writeToLog(ex.Message + " " + ex.StackTrace);
}
}
If I execute it on my dev machine (windows 8 pro) or in another test server (Windows Server 2003 32 bits) it makes whats expected. If I run it on the WS2003 64 bit server it does nothing.
I've debugged lots of times to see if it produces some error that I'm missing, but nothing happens. The "lc.writeToLog" method prints text to a file. I've used it to log every single line of the execution, but no error is thrown. Using that method I've concluded that it passes the "proc.WaitForExit()" instruction, so I think it's going to do what I've programmed, but nothing happens.
I have runned the same instruction but passing it a user, password and domain and the result was the same. Also tryed to capture standard error and output but it contained nothing.
What could be the trouble?
It was a server related issue. After deploying the application onto the production server the issue has disapeared.
i'm trying to execute vbscript from c#, the vbscript runs always succesfully despite of the fact that i don't have permissions to run this script.
the code:
//nswp is the User's password
foreach (char c in uspw)
{
password.AppendChar(c);
}
Process scriptProc = new Process();
scriptProc.StartInfo.RedirectStandardOutput = true;
scriptProc.StartInfo.RedirectStandardError = true;
scriptProc.StartInfo.Domain = "moia.gov.il";
scriptProc.StartInfo.ErrorDialog = true;
scriptProc.StartInfo.UserName = Globals.CURRENT_USER.user_name;
scriptProc.StartInfo.Password = password;
scriptProc.StartInfo.UseShellExecute = false;
scriptProc.StartInfo.FileName = #"cscript";
scriptProc.StartInfo.Arguments = "//B //Nologo " + pathSave;
scriptProc.Start();
scriptProc.WaitForExit();
scriptProc.Close();
When i'm executing this vbscript manually (by double click on the file icon) i get a permissions error, as i should.
How can i catch this error in c# and throw exception respectively.
You don't have a lot of options when using a different process like you do here. This is about it:
scriptProc.WaitForExit();
if (scriptProc.ExitCode != 0) throw new Exception("Script failed");
You can get rich error info by executing the script in-process by using the COM scripting host. That could be overkill, hard to tell.