简体   繁体   中英

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

I have an SSIS package being called from a batch file and I am trying to schedule it via the task scheduler. The package works fine in Visual Studio, and it works when I execute the batch file, but it fails when I run the package through the scheduler. I've read all other post on this topic and I don't see anything relevant to mine, the problem is not configuration of the task scheduler properties (ie the account it's using, run at highest privilege, start in directory, etc..).

I run multiple packages successfully through the task scheduler with no issues, this one just happens to use ac# script task that I had to add an assembly reference to and I think that's what is causing the problems when the package runs via the scheduler as the other packages use c# script task without issue but I did not add any assemblies.

This is the C# script which is used to format an excel spreadsheet after it's populated with data.

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
        };
    }
}

And here are the references I added to this script task:

在此处输入图像描述

My question is, knowing that it has something to do with these references, does anyone understand why this happens? I am running the task with a local admin account and the batch file is on the local filesystem, everything else works in the package until this script task when using the task scheduler. I tries to copy the Excel Interop DLL file to the same folder as the batch file and re-added the reference to see if maybe that was the issue to no avail. My other script task which I did not have to add any assembly references to work just fine this way.

ding ding ding

I had to add an assembly reference to and I think that's what is causing the problems

Correct. You are using the Excel object model, via Microsoft.Office.Interop.Excel, to build/modify an Excel Workbook. The scheduler server does not have Office installed so the package fails as it can't find the required libraries. The correct resolution is to install Office on the server.

I tries (sic) to copy the Excel Interop DLL file to the same folder as the batch file

You do not want to "solve" the problem by copying the required assemblies to the scheduler. Even if you get all the required files installed, you've now opened your company up to failing an audit.

Office isn't free, the fine folks in Redmond built it, your organization will want to pay for it because paying upfront is so much cheaper than an audit finding a willful violation. Compare and contrast these conversations

"Oh yeah, we installed XYZ on this box an forgot about it" Auditors: ok, fine, true up your licensing and pay for what you're using. $

"Oh yeah, we mirrored on the libraries over there, installed them to the GAC, etc" Auditors: So it wasn't just an accident, that was deliberate and ignorance is not a defense. You owe us licensing fees and the following penalties. $$$

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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