我有一个控制台应用程序,它可以手动运行,但是当它由SQL Server Agent执行时,它根本无法运行并且还会发出一条奇怪的错误消息,如下所示: -
Executed as user: I01SVTD21\SYSTEM.
Unhandled Exception: System.IO.IOException: The handle is invalid.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded)
at System.Console.Clear()
at ActiveDirectoryImport.Program.SendReports()
at ActiveDirectoryImport.Program.GetUserInfo()
at ActiveDirectoryImport.Program.Main(String[] args).
Process Exit Code 255. The step failed.
现在这可能看起来不像是一个奇怪的错误消息,直到你意识到ActiveDirectoryImport.Program.SendReports()是ActiveDirectoryImport.Program.GetUserInfo()调用的最后一个方法,所以好像大多数代码都运行了。然而事实并非如此,因为代码所做的第一件事就是更新数据库表中的记录,而这种情况还没有发生......
所以我有两个问题。当手动从同一位置正常运行时,为什么作业完全失败?并且,为什么它告诉我它在代码中很晚才失败,显然还没有那么远?
控制台应用程序确实写入控制台屏幕但不接受用户输入。它基本上将应用程序的状态写入屏幕,这似乎是错误的....
感谢任何帮助。
答案 0 :(得分:2)
也许这应该是一个评论,但从异常(以及一些心理调试)来看,这是非常“明显的”:
当进程的标准输出未附加到控制台的输出时,System.Console.Clear()
将导致您看到的异常。从命令行调用应用程序并重定向其输出时,最容易重现:
MyConsoleApplication.exe > NUL
检查您的SQL代理命令行是否包含这样的重定向 - 实际上,我不确定它,但SQL代理可能会自动重定向您的进程'输出以在其日志中显示它。最好的办法是完全删除System.Console.Clear()
调用,可以说无论如何它在这种情况下都没有多大意义。或者,简单地将其包裹起来
try
{
System.Console.Clear();
}
catch (IOException)
{
}
忽略此特定错误。请注意,其他控制台功能/属性(如CursorVisible
)在这种情况下也可能会抛出IOException
。
CursorVisible
实际上是编写这样一个辅助函数的“好”候选者:
bool ConsoleInputIsRedirected
{
get
{
try
{
bool f = System.Console.CursorVisible;
return false;
}
catch (IOException)
{
return true;
}
}
}
如果需要,您可以使用此函数有条件地执行仅在输出未重定向时才起作用的代码(如Clear()
)。