我有一个从批处理文件调用的 SSIS 包,我正在尝试通过任务计划程序来安排它。该包在 Visual Studio 中工作正常,并且当我执行批处理文件时它可以工作,但当我通过调度程序运行该包时它会失败。我已经阅读了有关此主题的所有其他帖子,但没有看到任何与我的相关的内容,问题不在于任务计划程序属性的配置(即它正在使用的帐户、以最高权限运行、在目录中启动等)。 ).
我通过任务计划程序成功运行多个包,没有出现任何问题,这个任务恰好使用了一个 C# 脚本任务,我必须向该任务添加程序集引用,我认为这就是当包通过计划程序运行时导致问题的原因:其他包使用 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 Interop DLL 文件复制到与批处理文件相同的文件夹中,并重新添加引用以查看是否是问题所在,但无济于事。我的其他脚本任务无需添加任何程序集引用即可以这种方式正常工作。
叮叮叮
我必须添加一个程序集引用,我认为这就是导致问题的原因
正确。您正在通过 Microsoft.Office.Interop.Excel 使用 Excel 对象模型来构建/修改 Excel 工作簿。计划程序服务器未安装 Office,因此包因找不到所需的库而失败。正确的解决方法是在服务器上安装 Office。
我尝试(原文如此)将 Excel Interop DLL 文件复制到与批处理文件相同的文件夹中
您不想通过将所需的程序集复制到调度程序来“解决”问题。即使您安装了所有必需的文件,您的公司现在也可能无法通过审核。
Office 不是免费的,是雷德蒙德的优秀人员建造的,您的组织会愿意为此付费,因为预付款比审计发现故意违规要便宜得多。比较和对比这些对话
“哦,是的,我们在这个盒子上安装了 XYZ,但忘了它” 审核员:好的,好吧,验证您的许可并为您使用的内容付费。 $
“哦,是的,我们镜像了那边的库,将它们安装到了 GAC 等” 审计员:所以这不仅仅是一次意外,这是故意的,无知并不是一种辩护。您欠我们许可费和以下罚款。 $$$
我开始意识到,无论是通过代理还是任务调度程序,Interop 都无法无头工作,因此我切换到 ClosedXML,构建了一个控制台应用程序,并以这种方式执行它,它就可以工作了。
对我来说,当我在批处理文件中给出 dtexec 的完全限定路径时,它就起作用了,而在我只有 dtexec /file 之前,现在我有“c:\program files...\dtexec.exe”/File“c: ...”并且它在我使用 32 位 exe 时有效,或者确保您的 PATH 变量首先具有 32 位 dtexec 路径