从SQL Server代理(作业)运行C#控制台应用程序?

7
这可能是一个非常简单的问题,但我已经尝试了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(String Filename, Object UpdateLinks, Object ReadOnly, Object Format, Object Password, Object WriteResPassword, Object IgnoreReadOnlyRecommended, Object Origin, Object Delimiter, Object Editable, Object Notify, Object Converter, Object AddToMru, Object Local, Object CorruptLoad)中。在C:\Users\shress2\documents\visual studio 2010\projects\T_OpenExcel\T_OpenExcel\Program.cs的T_OpenExcel.Program.Main(String[] args)的第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();
    }
}
}

2
我想象一下,默认用于运行SQL Server代理作业的用户帐户可能没有足够的权限与具有交互式GUI的东西(如Excel)进行交互。在控制台应用程序中使用Aspose.Cells可能是一个解决方案。 - Uwe Keim
1
你的项目使用SQL吗?如果不是的话,最好使用定时任务。 - jrummell
我尝试使用任务计划程序,它在那里运行得非常完美。问题是我们正在使用SQL JOB自动化喂送Excel文件的过程(在我的情况下,是我的C#应用程序生成的),以供第三方报告工具使用。这就是让它从SQL job中运行的唯一原因。谢谢。 - Nemo
1
我的猜测是E:驱动器是一个映射的网络驱动器。你可能在你的用户下映射了它,但是任务正在CORP\shress2或其他账户下运行。尝试指定文件的UNC路径-例如"\server\path\to\file"。 - Chris Shain
嗨,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 我仍然得到相同的错误。 :( - Nemo
显示剩余3条评论
3个回答

1

您只需要在新作业步骤编辑器中选择适当的作业类型。您可以使用PowershellCmdExec

在命令区域,单击打开按钮以定位您编译的控制台应用程序可执行文件(exe)。

如果有任何参数,请在此处添加 - 否则配置计划。

您可能需要使用提升的权限。要使用提升的权限,只需导航到SSMS中的安全性->凭据,右键单击新凭据。接下来,在Sql Server Agent->代理下配置代理帐户,右键单击新代理。为CmdExec配置代理并使用先前设置的凭据。在SQL代理作业步骤中,您可以选择此凭据以在运行命令时使用。

在SQL作业步骤命令区域中,您应该输入类似以下内容的内容:

excel E:\data_extracts\RenameSheets.xlsm

您是否添加了自定义凭据 - 默认情况下,SQL代理服务帐户无法访问文件系统。您需要配置代理帐户。具体操作可参见:http://www.sqlservercentral.com/Forums/Topic1088319-391-6.aspx#bm1099165。 - SliverNinja - MSFT
1
@SilverNinja,在命令区域,我可以粘贴我的已编译exe文件的路径,或者像你说的那样浏览到我的项目的.exe文件。当我粘贴路径时,它看起来很正常,但最终失败了。当我浏览到路径时,它给我一些乱码。(在此复制粘贴)MZ� 这是导致访问文件出现问题的原因吗?请告诉我。谢谢。 - Nemo
请参见上面的编辑...您需要告诉CmdExec使用Excel打开文件。CmdExec无法打开XLSM文件。 - SliverNinja - MSFT
要配置代理帐户,请参见上面的编辑。 - SliverNinja - MSFT
你是否可能已经打开了工作簿并需要将其关闭?也许你应该在“Program.cs”中分享代码。 - SliverNinja - MSFT
显示剩余7条评论

0

新工作

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->代理”下配置“代理帐户”,右键单击“新代理”。为CmdExec配置代理并使用您之前设置的凭据。在SQL代理作业步骤中,您可以选择此凭据在运行命令时使用。

在SQL作业步骤命令区域中,您应该输入类似以下内容:

excel E:\data_extracts\RenameSheets.xlsm


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接