【问题标题】:Redirect C# process output重定向 C# 进程输出
【发布时间】:2011-05-24 19:45:49
【问题描述】:

我正在开展一个项目,该项目将查询在其他系统上运行的计划任务。我编写了一个运行 schtasks 并将输出重定向到文本文件的控制台应用程序。但是,我想知道是否可以将此输出重定向到 SQL 数据库?

我正在考虑编写一个存储过程来处理所有插入,但我不知道如何处理控制台应用程序中的数据。我已经有一个存储过程,可以将 XML 和文本数据重定向到我过去创建的数据库,但我试图不让文件到处乱放。

任何输入都会很棒。这是我的代码,以防有人想看:

Process process = new Process();
process.StartInfo.FileName = "C:\\Windows\\System32\\schtasks.exe";
process.StartInfo.Arguments = "/query /s 192.168.0.124";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.Start();

string procOutput = process.StandardOutput.ReadToEnd();

这里只是使用文本编写器重定向到文本文件。

【问题讨论】:

    标签: c# sql stored-procedures windows-task-scheduler


    【解决方案1】:

    是的,利用forsqlcmd variables 可以在一行中:

    for /F "skip=1 delims=, tokens=1,2,3*" %i in ('schtasks.exe /query /FO CSV /s <server>') do sqlcmd -E -S <dbserver> -d <db> -Q "insert into <table> (TaskName, NextRun, Status) values ('$(TaskName)', '$(NextRun)', '$(Status)');" /v TaskName=%i /v NextRun=%j /v Status=%k

    【讨论】:

    • 不错。我想我可以将其作为批处理文件运行?
    • 是的,请注意,在批处理(.cmd、.bat)中,您需要使用%%i%%j%%k
    • 虽然如果你已经有一个应用程序,也许你应该去掉中间人,自己枚举任务。使用 TaskScheduler COM 类,参见msdn.microsoft.com/en-us/library/aa446881%28v=vs.85%29.aspx
    • 我查看了 COM 类,但我需要更多地使用它。输出不是我想要的。我确信我可以获得与 schtasks 相同类型的输出,但我只需要花一些时间来处理它。
    【解决方案2】:

    我会编写一个 web 服务,这个小程序调用它来发布它的信息。让该 Web 服务将结果写入数据库并公开该服务的方法以检索信息。使用一组大多数程序员都熟悉的技术使其更易于维护。 唯一的问题是,您的控制台应用程序将如何执行? 将控制台应用程序转换为 Windows 服务值得付出努力吗?让它监听传入的请求来做它的事情。 WCF 对于处理这些类型的任务非常方便。 你怎么看?

    WCF Landing Page

    How to: Host a WCF Service in a Managed Windows Service

    您需要与您的网络人员交谈,以确保您的网络服务器可以打开与安装 wcf 服务的目标计算机的连接。

    【讨论】:

    • 我的计划(注意我已经走上了 web 和 windows 窗体的路径,但他们不会做我需要的)是有一个 web 前端,它将从数据库中检索数据。然后,我可以使用 schtasks 添加更多功能,以允许它们根据存储在另一个表中的权限启动和停止任务。我曾考虑过 WCF,但不知道它是否会带来更多的安全风险,因为它作为服务运行并且我们正在通过 schtasks 访问操作系统。我从来没有写过服务,所以也许你可以告诉我。
    • 您的描述听起来像 Windows 服务将是完美的。您的服务应该在“network_service”用户上下文下运行。它应该能够执行 schtasks,但我不是 100% 的。你研究过WMI吗?它可能能够在不执行外部程序的情况下为您提供所需的信息。在顶部添加了一些资源以帮助您入门。
    • 到目前为止,我只查看了 COM 对象,但并不关心输出选项。再说一次,我也从来没有玩过它。我只是快速查看了 WMI 类,据我所见,它有几个有用的属性。我会检查一下,看看它的外观。感谢您的意见。
    • 只是想添加 WMI 可以被远程机器访问,因此您可以从一个部署中连接多台机器。
    【解决方案3】:

    如果程序很小,将在受信任的机器上运行,只需使用 SqlConnection(或与您的 rdmbs 等效的连接)创建命令,并通过 procOutput 作为参数执行它)。像这样的:

    var connection = new System.Data.SqlClient.SqlConnection(connection);
                var command = connection.CreateCommand();
                command.CommandText = "procedureName";
                command.Parameters.Add(new System.Data.SqlClient.SqlParameter("paramName", "output"));
                command.CommandType = System.Data.CommandType.StoredProcedure;
                command.ExecuteNonQuery();
    

    【讨论】:

    • 它将在受信任的机器上运行。重定向的输出会作为参数工作吗?这意味着我需要为每条输出设置多个参数(即任务名称、状态等)吗?
    【解决方案4】:

    当然。这样做的懒惰方法是:

    • 像现在一样重定向它。
    • 从标准输出和标准错误中读取,而不是直接写入文本文件,请使用 log4net。
    • 使用 SQL appender 配置 log4net 以捕获您编写的日志消息。
    • 如果您愿意,还可以配置滚动文件附加程序,以便将日志消息也写入日志文件。
    • 您可以考虑并添加一个事件日志附加程序,以便将标准错误写入事件日志,以便操作人员可以连接警报。

    我喜欢以这种方式使用 log4net,因为它使批量生产变得简单。我可以获得正常的控制台输出,同时在文本文件、sql 数据库或 Windows 事件日志中捕获它。让运营人员开心(更)。

    【讨论】:

    • 我对此了解不多。它会处理诸如写入控制台的命令之类的事情,还是我仍需要将数据写入某种介质?
    • 有关 log4.net 的详细信息,请参见 logging.apache.org/log4net/index.html。这是一个记录到日志文件和电子邮件的配置文件:weblogs.asp.net/tgraham/archive/2007/03/15/…。可以在logging.apache.org/log4net/release/config-examples.html 找到 log4net 附加程序的示例。 log4net 接受通过 ILog 实例写入的任何内容。
    • 如果您想捕获写入控制台的任何内容,您需要将控制台的 TextWriters 替换为标准输出和标准错误,并将输出运行到 log4net 的自定义 TextWriters。然后您需要小心 log4net 配置(如果您配置了 ConsoleAppender,您可能会将输出通过管道传输到 log4net,然后将其发送到将其发送到 log4net 的控制台……您会明白的.
    猜你喜欢
    • 2013-09-06
    • 2012-01-24
    • 1970-01-01
    • 2010-11-20
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2021-03-25
    相关资源
    最近更新 更多