我正在准备编写一个在线评判核心,
一个可以编译用户代码并运行程序来检查答案的程序,如uva在线评判.
而我在捕获如下提交程序的例外方面遇到了问题.
int main()
{
while(~scanf("%d %d",n,&m))
{
printf("%d\n",n+m);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它在第一行被拒绝访问,因为它将整数扫描到错误位置.
如何捕获进程的运行时错误?
我曾经使用"try catch"来捕获异常,
但它没有回复有关运行时错误的任何内容.
所以我只检查提交程序的退出代码,虽然它不是一个好的方法来检查除了一个进程..
它显示像照片
我必须手动关闭错误消息框,
并找到一个解决方案,即使用SEH Handler DLL进行处理.
SetErrorMode(SEM_NOGPFAULTERRORBOX);
Run Code Online (Sandbox Code Playgroud)
但我不知道如何在C#进程中使用它.
以下是我的判断代码
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;
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助,也很抱歉我的英语不好.
==================================
ps
问题是如何在C#中为子进程设置错误模式.
我的英语不足以解释这个问题,很抱歉.<(_ _)>
Ric*_*ard 10
如果你的意思是Win32 API函数,SetErrorMode那么你需要使用P/Invoke,这很简单:
[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
}
Run Code Online (Sandbox Code Playgroud)
(网站http://www.pinvoike.net/始终是开始获得正确声明的好地方.)
如果不将代码注入该进程,则无法在另一个进程中设置错误模式.在C#中不可能轻松做到这一点.它在C/C++中也不会很好用,这些程序的活动时间不够长,无法给你时间注入.
无论如何它都无法解决您的问题,您还必须防止程序在无限循环中遇到后永不退出.简单的解决方案是为每个程序提供有限的执行时间.说10秒.如果它没有完成,那么Process.Kill()它并声明失败.这也将照顾用消息框炸弹的程序.
使用Process.WaitForExit(毫秒)重载实现很简单.
| 归档时间: |
|
| 查看次数: |
4338 次 |
| 最近记录: |