简体   繁体   English

我可以在C#进程中使用SetErrorMode吗?

[英]Can I use SetErrorMode in C# process?

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. 一个可以编译用户代码并运行该程序以检查答案的程序,例如uva在线判断器。

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. 并且我找到了一种解决方案,该解决方案将SEH处理程序DLL用于该过程。

SetErrorMode(SEM_NOGPFAULTERRORBOX);

but I don't know how to use it in C# process. 但是我不知道如何在C#流程中使用它。

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. 感谢您的帮助,对于我的英语不好,我们深表歉意。

================================== =================================
ps ps
the question is how can I set error mode for the child process in C#. 问题是如何在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: 如果您指的是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
}

(The Site http://www.pinvoike.net/ is always a good place to start to get the right declaration.) (站点http://www.pinvoike.net/始终是开始获取正确声明的好地方。)

You cannot set the error mode in another process without injecting code into that process. 如果不向该进程中注入代码,则无法在另一个进程中设置错误模式。 Which is impossible to do easily in C#. 在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. 它也不能在C / C ++中很好地工作,这类程序的生存时间不足以给您注入时间。

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. 说10秒。 If it doesn't complete then Process.Kill() it and declare a failure. 如果尚未完成,则将Process.Kill()声明为失败。 This will also take care of the programs that bomb with a message box. 这还将处理用消息框轰炸的程序。

Trivial to implement with the Process.WaitForExit(milliseconds) overload. 用Process.WaitForExit(毫秒)重载来实现很简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM