繁体   English   中英

由于脚本任务,从任务计划程序通过批处理文件调用 SSIS 包失败

[英]SSIS Package fails when called from task scheduler via a batch file because of a script task

我有一个从批处理文件中调用的 SSIS 包,我正在尝试通过任务调度程序对其进行调度。 该包在 Visual Studio 中运行良好,当我执行批处理文件时它可以工作,但是当我通过调度程序运行包时它会失败。 我已经阅读了关于这个主题的所有其他帖子,但我没有看到任何与我相关的内容,问题不在于任务调度程序属性的配置(即它使用的帐户、以最高权限运行、在目录中启动等)。 )。

我通过任务调度程序成功运行了多个包,没有任何问题,这个只是碰巧使用了我必须添加程序集引用的 ac# 脚本任务,我认为这就是包通过调度程序运行时导致问题的原因其他包使用 c# 脚本任务没有问题,但我没有添加任何程序集。

这是 C# 脚本,用于在填充数据后格式化 Excel 电子表格。

using System;
using System.Runtime.InteropServices;
using Excel = Microsoft.Office.Interop.Excel;

#endregion

namespace ST_2bdf93d5542441248076f053703d32c9
{

    [Microsoft.SqlServer.Dts.Tasks.ScriptTask.SSISScriptTaskEntryPointAttribute]
    public partial class ScriptMain : Microsoft.SqlServer.Dts.Tasks.ScriptTask.VSTARTScriptObjectModelBase
    {

        public void Main()
        {
            int lastUsedColumn = 0;

            string inputFile = (string)Dts.Variables["RecommendationFileName"].Value;
            string RecommendationName = (string)Dts.Variables["RecommendationName"].Value;

            Excel.Application ExcelApp = new Excel.Application();
            Excel.Workbook ExcelWorkbook = ExcelApp.Workbooks.Open(inputFile);

            //ExcelApp.Visible = true;  //Use this to show the excel application/spreadsheet while the package is running.  Not good for prod, just testing.
            ExcelApp.Visible = false;

            Excel.Worksheet xlWorkSheetFocus = (Excel.Worksheet)ExcelWorkbook.Worksheets.get_Item(3);
            xlWorkSheetFocus.Activate();
            xlWorkSheetFocus.Select(Type.Missing);
            Excel.Range usedRange = xlWorkSheetFocus.UsedRange;

            foreach (Excel.Worksheet ExcelWorksheet in ExcelWorkbook.Sheets)
            {
 
                ExcelWorksheet.Columns.AutoFit(); //Autofit the column to width for each worksheet, we adjust some column widths manually later.

                if (ExcelWorksheet.Name == "Recommendations")
                {
                    ExcelWorksheet.Cells[1, 4].EntireColumn.ColumnWidth = 125;
                    ExcelWorksheet.Cells[1, 4].EntireColumn.WrapText = true;
                }

                if (ExcelWorksheet.Name == "Passed")
                {
                    ExcelWorksheet.Cells[1, 4].EntireColumn.ColumnWidth = 125;
                    ExcelWorksheet.Cells[1, 4].EntireColumn.WrapText = true;
                }

                if ((ExcelWorksheet.Name != "Recommendations") & (ExcelWorksheet.Name != "Passed"))
                {

                    // Find the last real column in each worksheet 
                    lastUsedColumn = ExcelWorksheet.Cells.Find("*", System.Reflection.Missing.Value,
                    System.Reflection.Missing.Value, System.Reflection.Missing.Value,
                    Excel.XlSearchOrder.xlByColumns, Excel.XlSearchDirection.xlPrevious,
                    false, System.Reflection.Missing.Value, System.Reflection.Missing.Value).Column;

                    ExcelWorksheet.Rows["1"].Insert(); //insert empty top row
                    ExcelWorksheet.Rows["2"].Insert(); //insert empty second row
                    ExcelWorksheet.Rows["3"].Insert(); //insert empty second row

                    ExcelWorksheet.Cells[1, 1].Interior.Color = 0x565656; //Row 1 = Dark Gray
                    ExcelWorksheet.Cells[2, 1].Interior.Color = 0x565656; //Row 2 = Dark Gray
                    ExcelWorksheet.Cells[3, 1].Interior.Color = 0x3ad7bd; //Row 3 = Green
                    ExcelWorksheet.Range[ExcelWorksheet.Cells[4, 1], ExcelWorksheet.Cells[4, lastUsedColumn]].Interior.Color = 0xCECECE; //Row 4 = Light Gray

                    //Bold the Fourth row of each spreadsheet (column headers are here)
                    ExcelWorksheet.Range["A4"].EntireRow.Font.Bold = true;

                    //Add a link back to the Recommendations page in row 2
                    ExcelWorksheet.Hyperlinks.Add(ExcelWorksheet.Cells[2, 1], "#Recommendations!A2", Type.Missing, "Return to Recommendations", "Return to Recommendations");

                    //Change row 1 to White, Bold, and 12pt font Arial, this is the report Title
                    ExcelWorksheet.Cells[1, 1].Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.White);
                    ExcelWorksheet.Cells[1, 1].Font.Bold = true;
                    ExcelWorksheet.Cells[1, 1].Font.size = 12;
                    ExcelWorksheet.Cells[1, 1].Font.Name = "Arial";

                    Excel.Range formatRange;
                    formatRange = ExcelWorksheet.get_Range("c1", "c1");
                }

            }
            ExcelWorkbook.Save();

            GC.Collect();
            GC.WaitForPendingFinalizers();

            ExcelWorkbook.Close(Type.Missing, Type.Missing, Type.Missing);
            Marshal.FinalReleaseComObject(ExcelWorkbook);

            ExcelApp.Quit();
            Marshal.FinalReleaseComObject(ExcelApp);
        }
        enum ScriptResults
        {
            Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
            Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
        };
    }
}

以下是我添加到此脚本任务的参考:

在此处输入图像描述

我的问题是,知道它与这些引用有关,有谁明白为什么会发生这种情况? 我正在使用本地管理员帐户运行任务,并且批处理文件位于本地文件系统上,在使用任务调度程序时,包中的所有其他内容都可以工作,直到此脚本任务。 我尝试将 Excel 互操作 DLL 文件复制到与批处理文件相同的文件夹中,并重新添加了引用以查看这是否可能是无济于事的问题。 我的另一个脚本任务,我不必添加任何程序集引用即可以这种方式正常工作。

叮叮叮_ _

我必须添加一个程序集引用,我认为这就是导致问题的原因

正确的。 您正在通过 Microsoft.Office.Interop.Excel 使用 Excel 对象模型来构建/修改 Excel 工作簿。 调度程序服务器未安装 Office,因此包因找不到所需的库而失败。 正确的解决方法是在服务器上安装 Office。

我尝试(原文如此)将 Excel 互操作 DLL 文件复制到与批处理文件相同的文件夹中

您不想通过将所需程序集复制到调度程序来“解决”问题。 即使您安装了所有必需的文件,您现在已经让您的公司面临审核失败的风险。

Office 不是免费的,Redmond 的优秀人员建造了它,您的组织会愿意为此付费,因为预付费用比审计发现故意违规要便宜得多。 比较和对比这些对话

“哦,是的,我们在这个盒子上安装了 XYZ 却忘了它” 审计员:好的,好的,验证你的许可并为你使用的东西付费。 $

“哦,是的,我们在那边的库上进行了镜像,将它们安装到 GAC 等” 审计员:所以这不仅仅是一个意外,这是故意的,无知不是一种防御。 您欠我们的许可费和以下罚款。 $$$

我开始意识到 Interop 不会通过代理或任务调度程序无头工作,所以我切换到 ClosedXML,构建了一个控制台应用程序,并以这种方式执行它并且它可以工作。

暂无
暂无

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

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