I'm using Closure Compiler running on my local machine to generate client files. I'm also using the online closure tool at http://closure-compiler.appspot.com/home to check my work: I paste my JavaScript code, press compile and if there's a warning the compiler shows me the warnings with the actual lines and line numbers.
I'm wondering if it's possible to get the same output using the local version of Closure Compiler. This is the code I use to compile the files and get the compiled JavaScript but this time, I want the warnings:
System.IO.File.WriteAllText(FileNameInput, TheJS);
string JavaArgument = "-jar ClosureCompiler/compiler.jar --js ClosureCompiler/initial" + FileNameSuffix + ".js --js_output_file ClosureCompiler/compiled" + FileNameSuffix + ".js --compilation_level ADVANCED_OPTIMIZATIONS --externs ExternalFiles/JqueryExtern.js";
System.Diagnostics.Process clientProcess = new System.Diagnostics.Process();
clientProcess.StartInfo.FileName = "java.exe";
clientProcess.StartInfo.Arguments = JavaArgument;
clientProcess.StartInfo.CreateNoWindow = true;
clientProcess.StartInfo.UseShellExecute = false;
clientProcess.StartInfo.WorkingDirectory = HttpRuntime.AppDomainAppPath;
clientProcess.Start();
clientProcess.WaitForExit();
string TheOutputScript = System.IO.File.ReadAllText(FileNameOutput);
What do I need to change?
The compiler writes the warnings and errors to standard error which isn't going to show in your output file.
Option 1 - Redirect Standard Error to a File
Add 2> errorfile.txt to the end of your execution command to redirect standard error to a file. You'll then need to read that file.
Option 2 - Read the Standard Error Property of the Process
This should be as simple as:
clientProcess.StandardError
Chad's answer was great in that in pointed me towards the code. For those who need the actual code, this is what I have:
clientProcess.StartInfo.FileName = "java.exe";
clientProcess.StartInfo.Arguments = JavaArgument;
clientProcess.StartInfo.CreateNoWindow = true;
clientProcess.StartInfo.UseShellExecute = false;
clientProcess.StartInfo.WorkingDirectory = HttpRuntime.AppDomainAppPath;
clientProcess.StartInfo.RedirectStandardError = true; //add this line
clientProcess.Start();
string CompilerErrors = clientProcess.StandardError.ReadToEnd(); //add this line
clientProcess.WaitForExit();
return System.IO.File.ReadAllText(FileNameOutput); //add breakpoint here
Now all you have to do is add a break point at the end and watch the variable CompilerErrors.
Related
I am attempting to get the metadata from a few music files and failing miserably. Online, there seems to be absolutely NO HOPE in finding an answer; no matter what I google. I thought it would be a great time to come and ask here because of this.
The specific error I got was: Error HRESULT E_FAIL has been returned from a call to a COM component. I really wish I could elaborate on this issue, but I'm simply getting nothing back from the COMException object. The error code was -2147467259, and it in hex is -0x7FFFBFFB, and Microsoft have not documented this specific error.
I 70% sure that its not the file's fault. My code will run through a directory full of music and convert the file into a song, hence the ConvertFileToSong name. The function would not be running if the file were to not exist is what I'm trying to say.
The only thing I can really say is that I'm using Dotnet 6, and have a massive headache.
Well, I guess I could also share another problem I had before this error showed up. Dotnet6 has top level code or whatever its called, this means that I can't add the [STAThread] attribute. To solve this, I simply added the code bellow to the top. Not sure why I have to set it to unknown, but that's what I (someone else on Stack Overflow) have to do. That solved that previous problem that the Shell32 could not start, but could that be causing my current problem? Who knows... definitely not me.
Thread.CurrentThread.SetApartmentState(ApartmentState.Unknown);
Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
Here is the code:
// Help from: https://stackoverflow.com/questions/37869388/how-to-read-extended-file-properties-file-metadata
public static Song ConvertFileToSong(FileInfo file)
{
Song song = new Song();
List<string> headers = new List<string>();
// initialise the windows shell to parse attributes from
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder objFolder = null;
try
{
objFolder = shell.NameSpace(file.FullName);
}
catch (COMException e)
{
int code = e.ErrorCode;
string hex = code.ToString();
Console.WriteLine("MESSAGE: " + e.Message + ", CODE: " + hex);
return null;
}
Shell32.FolderItem folderItem = objFolder.ParseName(file.Name);
// the rest of the code is not important, but I'll leave it there anyway
// pretty much loop infinetly with a counter better than
// while loop because we don't have to declare an int on a new
// line
for (int i = 0; i < short.MaxValue; i++)
{
string header = objFolder.GetDetailsOf(null, i);
// the header does not exist, so we must exit
if (String.IsNullOrEmpty(header)) break;
headers.Add(header);
}
// Once the code works, I'll try and get this to work
song.Title = objFolder.GetDetailsOf(folderItem, 0);
return song;
}
Good night,
Diseased Finger
Ok, so the solution isn't that hard. I used file.FullName which includes the file's name, but Shell32.NameSpace ONLY requires the directory name (discluding the file name).
This is the code that fixed it:
public static Song ConvertFileToSong(FileInfo file)
{
// .....
Shell32.Shell shell = new Shell32.Shell();
Shell32.Folder objFolder = file.DirectoryName;
Shell32.FolderItem folderItem = objFolder.ParseName(file.Name);
// .....
return something;
}
I'm writing a C# console app (.NET 6) running on a Windows machine that processes XSLT transformations as a batch: It reads parameter sets (which are then passed as params to the respective stylesheet) from an XML file and performs transformations using SaxonCS. (The params always contain the initial template and a path to the source file which is being read into a variable via doc($path-to-source) in said initial template).
For each transformation, an object is instantiated that represents an XSL transformation. Among other things like Console output etc., regarding the transformation, it does this:
// Instantiate SaxonCS Processor processor = new();
XsltCompiler compiler = processor.NewXsltCompiler();
compiler.BaseUri = new Uri(pathToXsl);
XsltTransformer transformer = compiler.Compile(File.OpenRead(pathToXsl)).Load();
// Set params used by the stylesheet, using ExternalParams (a Dictionary populated earlier
// with values read from the configuration file).
foreach (var parameter in ExternalParams) { transformer.SetParameter(parameter.Key, parameter.Value); }
transformer.InitialTemplate = new QName(parametrizedInitialTemplate);
// perform transformation
XdmDestination result = new(); // effectively unused
transformer.Run(result);
transformer.Close();
result = null; // result is not needed: The processor already serialized it because of xsl:result-document()
This works great - until I try to use a file which is the result of an earlier transformation, having been written using xsl:result-document href="{filepath}" in the stylesheet, as the input for another transformation later on. This then gives me a
System.IO.IOException: 'The process cannot access the file '..(some file path)..' because it is being used by another process.'
In other words:
This works: <transform_1: A --> B>; <transform_2: J --> K>; <transform_3: X --> Y>.
This fails: <transform_1: A --> B>; <transform_2: B --> C> (because B can't be accessed).
So I somehow fail to release resources / to close the resulting output file once the transformation is finished.
Running the exact same configuration file and console app, but calling Saxon 9-HE (Java) in its own Process works perfectly fine (but very slowly); there are no file access problems then:
Process proc = new();
ProcessStartInfo startInfo = new()
{
Arguments = #$"-cp {saxonJarPath} net.sf.saxon.Transform {string.Join(" ", XslParams)} -xsl:{XslPath} -it:{InitialTemplate}",
FileName = "java",
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true
};
proc.StartInfo = startInfo;
proc.Start();
proc.WaitForExit();
This is obviously not an ideal solution, and I would really like to speed the whole thing up and get rid of the Java dependency - that's why I'm trying to make it work with SaxonCS.
Unfortunately, I can't do "real pipelining" (as shown in one of the code examples that come with Saxon), thus directly using the result as input for the next, because the whole thing has to be configured externally (and not every result is input for the next transformation).
(Because of the explanations regarding ResultDocumentHandler, I tried processor.SetProperty(Saxon.Api.Feature.ALLOW_MULTITHREADING, false);, but it didn't help.)
So: How do I prevent a file which has been produced via xsl:result-document from being locked even when the transformation has finished?
I think explicitly setting up
transformer.BaseOutputUri = new Uri(pathToXsl);
transformer.ResultDocumentHandler = (href, baseUri) => {
var serializer = processor.NewSerializer();
var fs = File.Open(new Uri(baseUri, href).LocalPath, FileMode.Create, FileAccess.Write);
serializer.OutputStream = fs;
serializer.OnClose(() => { fs.Close(); });
return serializer;
};
avoids the problem.
I have been using the documentation here https://support.microsoft.com/en-gb/help/304655/how-to-programmatically-compile-code-using-c-compiler
I am trying to learn about compilers a bit more I want to host on my own site a simple text editor that I can use to run the code of a script say something simple like
The program is required to Print out Console.WriteLine("Hello World");
If anything other than Hello World is printed out the program would be in error.
I have been looking at Microsoft code on running .net code at runtime but both these force it to create an exe I want the result to be like .net fiddle in a text box.
I presume what I have to do some how is run the exe and use the process to return the result bare in mind this is inside a mvc applicaiton.
Or is their any cool nugets that can save me the time here.
private void Compiler(string code)
{
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
ICodeCompiler icc = codeProvider.CreateCompiler();
string Output = "Out.exe";
System.CodeDom.Compiler.CompilerParameters parameters = new
CompilerParameters();
//Make sure we generate an EXE, not a DLL
parameters.GenerateExecutable = true;
parameters.OutputAssembly = Output;
CompilerResults results = icc.CompileAssemblyFromSource(parameters, code);
if (results.Errors.Count > 0)
{
foreach (CompilerError CompErr in results.Errors)
{
CompilerError error = new CompilerError();
error.Line = CompErr.Line;
error.ErrorNumber = CompErr.ErrorNumber;
error.ErrorText = CompErr.ErrorText;
}
}
else
{
//Successful Compile
CodeResult result = new CodeResult();
result.Message = "Success";
}
}
So how would one capture the above and return and also how does one add support for other languages like python or vb.net
Is this something that blazor could perhaps be good at doing for me ?
I am wanting to provide an experience like .net fiddle https://dotnetfiddle.net
Suchiman / Robin Sue is has integrated the Monaco editor as well as an in-browser C# compiler in this nifty blazor project (live demo)
I run the following code but nothing shows up in ALM:
AttachmentFactory attachmentFactory = (AttachmentFactory)tsTest.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem("test");
attachment.Post();
The AddItem method on the second line keeps asking for "object ItemData" but I have no idea what that is exactly. HP has such poor documentation that there is really nothing explaining it. Does anyone know how to programatically using c# add a file attachment to a test run in HP ALM?
After much pain and research I have found an answer. I'm sure there are other ways of accomplishing this that are more efficient but since HP's documentation is the worst on the planet this is the best I could come up with. If anyone has a better way I would LOVE to see it so please post it!
I hope this helps!
try
{
if (qcConn.Connected)
{
string testFolder = #"Root\YourFolder";
TestSetTreeManager tsTreeMgr = (TestSetTreeManager)qcConn.TestSetTreeManager;
TestSetFolder tsFolder = (TestSetFolder)tsTreeMgr.get_NodeByPath(testFolder);
AttachmentFactory attchFactory = (AttachmentFactory)tsFolder.Attachments;
List tsList = tsFolder.FindTestSets("YourTestNameHere", false, null);
foreach (TestSet ts in tsList)
{
TestSetFolder tstFolder = (TestSetFolder)ts.TestSetFolder;
TSTestFactory tsTestFactory = (TSTestFactory)ts.TSTestFactory;
List mylist = tsTestFactory.NewList("");
foreach (TSTest tsTest in mylist)
{
RunFactory runFactory = (RunFactory)tsTest.RunFactory;
Run run = (Run)runFactory.AddItem("NameYouWantDisplayedInALMRuns");
run.CopyDesignSteps();
//runResult just tells me if overall my test run passes or fails - it's not built in. It was my way of tracking things though the code.
if(runResult)
run.Status = "Failed";
else
run.Status = "Passed";
run.Post();
//Code to attach an actual file to the test run.
AttachmentFactory attachmentFactory = (AttachmentFactory)run.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem(System.DBNull.Value);
attachment.Description = "Attach via c#";
attachment.Type = 1;
attachment.FileName = "C:\\Program Files\\ApplicationName\\demoAttach.txt";
attachment.Post();
//Code to attach a URL to the test run
AttachmentFactory attachmentFactory = (AttachmentFactory)run.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem(System.DBNull.Value);
//Yes, set the description and FileName to the URL.
attachment.Description = "http://www.google.com";
attachment.Type = 2;
attachment.FileName = "http://www.google.com";
attachment.Post();
//If your testset has multiple steps and you want to update
//them to pass or fail
StepFactory rsFactory = (StepFactory)run.StepFactory;
dynamic rdata_stepList = rsFactory.NewList("");
var rstepList = (TDAPIOLELib.List)rdata_stepList;
foreach (dynamic rstep in rstepList)
{
if (SomeConditionFailed)
rstep.Status = "Failed";
else
rstep.Status = "Passed";
rstep.Post();
}
else
{
rstep.Status = "No Run";
rstep.Post();
}
}
}
}
}
}
I have done something similar, but in Python and against Test Steps, so even if I don't have code you can copy & paste it, this might point you to the right direction.
Instead of calling:
attachmentFactory.AddItem( filename )
Call the function with no parameters (or a null paramer, can't tell since I never used the OTA API with C#):
file = attachmentFactory.AddItem()
Now assign the file to the attachment item, and the rest of its properties:
file.Filename = "C:\\Users\\myUser\\just\\an\\example\\path" + fileName
file.Description = "File description"
file.Type=1
file.Post()
The type specifies it's a local file, and not an URL.
If anyone is wondering how to do that on the requirement-module, here is the code:
Req req = Globals.Connection.ReqFactory.Item(*ID*));
VersionControl versionControl = ((IVersionedEntity)req).VC as VersionControl;
versionControl.CheckOut(string.Empty);
AttachmentFactory attFac = req.Attachments;
Attachment att = (Attachment)attFac.AddItem(System.DBNull.Value);
att.Description = "*Your description here";
att.Type = (int)TDAPI_ATTACH_TYPE.TDATT_FILE; //for URL, change here
att.FileName = "*Your path including filename here*";
att.Post();
versionControl.CheckIn("*Your check-in comment here*");
No valuable information on Internet!
After some digging on OTA documentation I have found this:
AttachmentFactory attachmentFactory = (AttachmentFactory)TstTest.Attachments;
TDAPIOLELib.Attachment attachment = (TDAPIOLELib.Attachment)attachmentFactory.AddItem("demoAttach.txt");
attachment.Description = "Bug Sample Attachment";
attachment.Post();
IExtendedStorage exStrg = attachment.AttachmentStorage;
exStrg.ClientPath = "E:\\TestData";
exStrg.Save("demoAttach.txt", true);
actually, was in VB script form but I managed to transform in C#.
OTA reference:
'-----------------------------------------
'Use Bug.Attachments to
' get the bug attachment factory.
Set attachFact = bugObj.Attachments
'Add a new extended storage object,an attachment
' named SampleAttachment.txt.
Set attachObj = attachFact.AddItem("SampleAttachment.txt")
' Modify the attachment description.
attachObj.Description = "Bug Sample Attachment"
' Update the attachment record in the project database.
attachObj.Post
' Get the bug attachment extended storage object.
Set ExStrg = attachObj.AttachmentStorage
'Specify the location of the file to upload.
ExStrg.ClientPath = "D:\temp\A"
'-----------------------------------------
'Use IExtendedStorage.Save to
' upload the file.
ExStrg.Save "SampleAttachment.txt", True
I'm preparing for writing an online judge core,
A program that can compile user's code and run the program to check the answer like uva online judge.
And I'm having problem in catching the exception of submit program like below.
int main()
{
while(~scanf("%d %d",n,&m))
{
printf("%d\n",n+m);
}
return 0;
}
it's access denied at first line because it scan an integer to error position.
how can I catch runtime error for my process?
I used to use "try catch" to catch the exception,
but it didn't reply anything about runtime error.
so I only check the exit code of the submit program although it's not a good method to check except for a process..
and it shows like photo
I have to close the error message box manually,
and I find a solution that is to use a SEH Handler DLL for the process.
SetErrorMode(SEM_NOGPFAULTERRORBOX);
but I don't know how to use it in C# process.
and below is my code of judger
timer = new Stopwatch();
timer.Reset();
submitProg = new Process();
submitProg.StartInfo.FileName = outputFile;
submitProg.StartInfo.UseShellExecute = false;
submitProg.StartInfo.CreateNoWindow = true;
submitProg.StartInfo.RedirectStandardInput = true;
submitProg.StartInfo.RedirectStandardOutput = true;
submitProg.StartInfo.RedirectStandardError = true;
submitProg.StartInfo.ErrorDialog = false;
submitProg.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
submitProg.EnableRaisingEvents = true;
submitProg.Start();
timer.Start();
progInput = submitProg.StandardInput;
progOutput = submitProg.StandardOutput;
progInput.Write(inputStream.ReadToEnd());
submitProg.StandardInput.Close();
while (!submitProg.HasExited)
{
peakPagedMem = submitProg.PeakPagedMemorySize64;
peakVirtualMem = submitProg.PeakVirtualMemorySize64;
peakWorkingSet = submitProg.PeakWorkingSet64;
if (peakPagedMem > memLimit)
{
submitProg.Kill();
}
if (timer.ElapsedMilliseconds > timeLimit)
{
timeLimitExceed = true;
submitProg.Kill();
}
}
timeUsed = timer.ElapsedMilliseconds;
timer.Stop();
if(submitProg.ExitCode!=0)systemRuntimeError = true;
Thanks for helping, and so sorry for my poor English.
==================================
p.s.
the question is how can I set error mode for the child process in C#.
My English is not good enough to explain the problem, so sorry.<(_ _)>
If you mean the Win32 API function SetErrorMode then you'll need to use P/Invoke, which is easy with such a simple signature:
[DllImport("kernel32.dll")]
static extern ErrorModes SetErrorMode(ErrorModes uMode);
[Flags]
public enum ErrorModes : uint {
SYSTEM_DEFAULT = 0x0,
SEM_FAILCRITICALERRORS = 0x0001,
SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
SEM_NOGPFAULTERRORBOX = 0x0002,
SEM_NOOPENFILEERRORBOX = 0x8000
}
(The Site http://www.pinvoike.net/ is always a good place to start to get the right declaration.)
You cannot set the error mode in another process without injecting code into that process. Which is impossible to do easily in C#. It isn't going to work well in C/C++ either, these kind of programs don't live long enough to give you time to inject.
It doesn't solve your problem anyway, you also have to protect against programs that never exit after they got stuck in an endless loop. The simple solution is to give every program a limited amount of time to execute. Say 10 seconds. If it doesn't complete then Process.Kill() it and declare a failure. This will also take care of the programs that bomb with a message box.
Trivial to implement with the Process.WaitForExit(milliseconds) overload.