从 SQL Server 代理(作业)运行 C# 控制台应用程序?
Posted
技术标签:
【中文标题】从 SQL Server 代理(作业)运行 C# 控制台应用程序?【英文标题】:Run a C# Console Application from SQL Server Agent (Job)? 【发布时间】:2012-05-28 07:36:29 【问题描述】:这可能是一个非常简单的问题,但过去 4-5 小时我一直在尝试,但没有成功。 :(
我有一个 C# 控制台应用程序,它只打开一个 excel 文件。这个 excel 文件有 Workbook_Open() 事件,它运行我的宏。我的宏只是在活动工作表中将 sheet1 重命名为 RenameSheet1。
我可以从 IDE 运行我的 C# 项目。我想从 SQL 作业(SQL server 2008)运行这个项目。我该怎么做?请帮我完成这项工作。谢谢。
根据 SilverNinnjas 的建议创建代理帐户:
-- 创建包含域帐户 CORP\PowerUser1 及其密码的凭据
CREATE CREDENTIAL PowerUser1 WITH IDENTITY = N'CORP\shress2', SECRET = N'P@ssw0rd'
GO
USE [msdb]
GO
-- 创建一个名为 ExcelProxy 的新代理并为其分配 PowerUser 凭据
EXEC msdb.dbo.sp_add_proxy
@proxy_name=N'ExcelProxy',
@credential_name=N'PowerUser1',
@enabled=1
-- 授予 ExcelProxy 访问“CmdExec”子系统的权限
EXEC msdb.dbo.sp_grant_proxy_to_subsystem
@proxy_name=N'ExcelProxy',
@subsystem_name =N'CmdExec'
-- 授予登录testUser使用ExcelProxy的权限
EXEC msdb.dbo.sp_grant_login_to_proxy
@login_name = N'shress2',
@proxy_name=N'ExcelProxy'
GO
我仍然遇到同样的错误 以用户身份执行:CORP\shress2。
未处理的异常:System.Runtime.InteropServices.COMException:Microsoft Excel 无法访问该文件 'E:\data_extracts\RenameSheets.xlsm'。 有几个可能的原因: 文件名或路径不存在。 该文件正被另一个程序使用。 您尝试保存的工作簿与当前打开的工作簿同名。在 Microsoft.Office.Interop.Excel.Workbooks.Open(字符串文件名、对象 UpdateLinks、对象只读、对象格式、对象密码、对象 WriteResPassword、对象 IgnoreReadOnlyRecommended、对象来源、对象分隔符、对象可编辑、对象通知、对象转换器、对象AddToMru, Object Local, Object CorruptLoad) at T_OpenExcel.Program.Main(String[] args) in C:\Users\shress2\documents\visual studio 2010\projects\T_OpenExcel\T_OpenExcel\Program.cs:line 24. 进程退出代码-532462766。步骤失败。
有什么原因吗?我急切地等待任何反馈。非常感谢。
@SilverNinja, 这是我的 C# 代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel;
using System.Threading;
namespace T_OpenExcel
class Program
static void Main(string[] args)
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
//Excel.Worksheet xlWorkSheet;
object misValue = System.Reflection.Missing.Value;
xlApp = new Excel.Application();
xlApp.Visible = true;
xlWorkBook = xlApp.Workbooks.Open("\\\\myserver\\data_extracts\\RenameSheets.xlsm", 0, false, 5, "", "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlApp.DisplayAlerts = false;
xlWorkBook.SaveAs("\\\\myserver\\data_extracts\\RenameSheets.xlsm", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
xlWorkBook.Close(true, misValue, misValue);
xlApp.DisplayAlerts = true;
xlApp.Quit();
private static void RunMacro(Excel.Workbook xlWorkBook, object[] p)
//throw new NotImplementedException();
【问题讨论】:
我认为默认情况下用于运行 SQL Server 代理作业的用户帐户没有足够的权限与具有 Excel 所具有的交互式 GUI 的东西进行交互。在控制台应用程序中使用 Aspose.Cells 可能是一种解决方案。 你的项目使用 SQL 吗?如果没有,您最好使用计划任务。 我尝试使用任务计划程序。它在那里运行得很好。问题是我们正在使用 SQL JOB 来自动化将 excel 文件(在我的情况下是我的 C# 应用程序生成)提供给第三方报告工具的过程。这是让它从 SQL 作业运行的唯一原因。谢谢。 我猜E:
驱动器是一个映射的网络驱动器。您可能将其映射到您的用户下,但该作业在 CORP\shress2
或其他任何名称下运行。尝试指定文件的 UNC 路径,例如“\\server\path\to\file\”。
嗨 Chris Shain,我在 C# 控制台应用程序中将 UNC 路径指定为“\\\\myserver\\data_extracts\\RenameSheets.xlsm”并成功编译/运行代码。现在我的问题是关于 SQL 作业。在命令区域下,它指向我编译的 exe 的路径,如下所示: C:\Users\shress2\Documents\visual studio 2010\projects\T_OpenExcel\T_OpenExcel\bin\Debug\T_OpenExcel.exe 我还是一样错误。 :(
【参考方案1】:
您只需在New Job Step 编辑器中选择适当的Job Type。您可以使用 Powershell 或 CmdExec。
在命令区域中,单击打开按钮以找到您的控制台应用程序编译的可执行文件 (exe)。
如果您有任何参数,请在此处添加 - 否则请配置时间表。
您可能必须使用提升的权限。要使用提升的权限,只需导航到 SSMS 中的 Security->Credentials 并右键单击 New Credential。接下来,在 Sql Server Agent->Proxies 下配置 Proxy Account 并右键单击 New Proxy。为 CmdExec 配置代理并使用您之前设置的 Credentials。在您的 SQL 代理作业步骤中,您可以选择在运行命令时使用此凭据。
在 SQL 作业步骤命令区域中,您应该键入如下内容:
excel E:\data_extracts\RenameSheets.xlsm
【讨论】:
@SilverNinja,感谢您的及时回复。我这样做了。但它失败了。我使用了 CmdExec。在命令下:我指向了 VS 2010 为我的 C# 控制台应用程序生成的 exe 文件。那是对的吗?我在执行作业时失败了。它说未处理的异常:System.Runtime.InteropServices.COMException:Microsoft Excel 无法访问文件“E:\data_extracts\RenameSheets.xlsm”。有几个可能的原因: 文件名或路径不存在。该文件正被另一个程序使用。您尝试保存的工作簿与当前打开的工作簿同名。 您是否添加了您的自定义凭据 - 默认情况下,SQL 代理服务帐户 无法访问文件系统。你需要一个proxy account configured。 @SilverNinja,在命令区域中,我可以将路径粘贴到我编译的 exe 中,或者如您所说,浏览到我的项目的 .exe 文件。当我粘贴路径时,它看起来很好,尽管它最终失败了。当我浏览到路径时,它给了我乱码。 (复制粘贴在这里-)MZ�这是导致访问文件问题的原因吗?请告诉我。谢谢。 查看上面的编辑...您需要告诉 CmdExec 使用 Excel 打开文件。 CmdExec 无法打开 XLSM 文件。 @SilverNinja- 我知道我无法使用 CmdExec 打开 XLSM 文件。这是否意味着我无法提供 .exe 文件的路径(从我的 c# 控制台应用程序编译)?这是我粘贴在命令区域 C:\Users\shress2\Documents\visual studio 2010\projects\T_OpenExcel\T_OpenExcel\bin\Debug\T_OpenExcel.exe 下的 .exe 文件的路径【参考方案2】:新工作
CmdExec
现在运行exe文件
它会给出异常。
更改 exe 代码。
您不能将远程服务器路径设为本地到同一个 sql 服务器 \\myserver\data_extracts\RenameSheets.xlsm 到 d:\data_extracts\RenameSheets.xlsm 或使用复制 bin exe 文件路径的文件路径。 Path.GetDirectoryName(Application.ExecutablePath) 例如。价值: C:\Projects\ConsoleApplication1\bin\Debug\RenameSheets.xlsm
确保只有一个exe在运行,否则会出现错误文件已打开
运行exe代码 它会起作用的。 命令提示符无法访问网络路径。
xlApp = new Excel.Application(); xlApp.Visible = true; xlWorkBook = xlApp.Workbooks.Open("C:\Projects\ConsoleApplication1\bin\Debug\RenameSheets.xlsm
", 0, false, 5, "", "", false, Microsoft.Office.Interop.Excel.XlPlatform.xlWindows, "\t", false, false, 0, true, 1, 0);
xlApp.DisplayAlerts = false;
xlWorkBook.SaveAs("C:\Projects\ConsoleApplication1\bin\Debug\RenameSheets.xlsm", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
xlWorkBook.Close(true, misValue, misValue);
xlApp.DisplayAlerts = true;
【讨论】:
【参考方案3】:只需在新工作步骤编辑器中选择适当的工作类型。您可以使用 Powershell 或 CmdExec。
在“命令”区域中,单击“打开”按钮以找到您的控制台应用程序编译的可执行文件 (exe)。
如果您有任何参数,请在此处添加 - 否则请配置计划。
您可能必须使用提升的权限。要使用提升的权限,只需导航到 SSMS 中的“安全”->“凭据”,然后右键单击“新凭据”。接下来,在 Sql Server Agent->Proxies 下配置代理帐户,然后右键单击 New Proxy。为 CmdExec 配置代理并使用您之前设置的凭据。在您的 SQL 代理作业步骤中,您可以选择在运行命令时使用此凭据。
在 SQL 作业步骤命令区域中,您应该键入如下内容:
excel E:\data_extracts\RenameSheets.xlsm
【讨论】:
以上是关于从 SQL Server 代理(作业)运行 C# 控制台应用程序?的主要内容,如果未能解决你的问题,请参考以下文章
vb.net 运行 gpg.exe 作业步骤从 PC 运行正常,但不能从 SQL Server 代理计划运行