[英]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.我有一个从批处理文件中调用的 SSIS 包,我正在尝试通过任务调度程序对其进行调度。 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.
该包在 Visual Studio 中运行良好,当我执行批处理文件时它可以工作,但是当我通过调度程序运行包时它会失败。 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.我通过任务调度程序成功运行了多个包,没有任何问题,这个只是碰巧使用了我必须添加程序集引用的 ac# 脚本任务,我认为这就是包通过调度程序运行时导致问题的原因其他包使用 c# 脚本任务没有问题,但我没有添加任何程序集。
This is the C# script which is used to format an excel spreadsheet after it's populated with data.这是 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
};
}
}
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.
我尝试将 Excel 互操作 DLL 文件复制到与批处理文件相同的文件夹中,并重新添加了引用以查看这是否可能是无济于事的问题。 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.
您正在通过 Microsoft.Office.Interop.Excel 使用 Excel 对象模型来构建/修改 Excel 工作簿。 The scheduler server does not have Office installed so the package fails as it can't find the required libraries.
调度程序服务器未安装 Office,因此包因找不到所需的库而失败。 The correct resolution is to install Office on the server.
正确的解决方法是在服务器上安装 Office。
I tries (sic) to copy the Excel Interop DLL file to the same folder as the batch file
我尝试(原文如此)将 Excel 互操作 DLL 文件复制到与批处理文件相同的文件夹中
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. Office 不是免费的,Redmond 的优秀人员建造了它,您的组织会愿意为此付费,因为预付费用比审计发现故意违规要便宜得多。 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. “哦,是的,我们在这个盒子上安装了 XYZ 却忘了它” 审计员:好的,好的,验证你的许可并为你使用的东西付费。 $
$
"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. “哦,是的,我们在那边的库上进行了镜像,将它们安装到 GAC 等” 审计员:所以这不仅仅是一个意外,这是故意的,无知不是一种防御。 You owe us licensing fees and the following penalties.
您欠我们的许可费和以下罚款。 $$$
$$$
我开始意识到 Interop 不会通过代理或任务调度程序无头工作,所以我切换到 ClosedXML,构建了一个控制台应用程序,并以这种方式执行它并且它可以工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.