我编写了一个应用程序,设置为命中我们的服务器,检查是否有任何挂起的作业,如果有可用的话,处理这些作业,创建带有结果的excel文档,然后通过电子邮件发送给我们的用户。它使用microsoft excel 2010在c#.net v3.5中编写,并通过任务调度程序每30分钟启动一次。我们的任务调度程序在运行2008 r2的服务器上运行。任务调度程序成功运行,数据库成功更新,就像处理作业一样,但是,它从不创建excel文件,我无法弄清楚原因。如果我在我们的服务器机器上手动运行应用程序,它运行顺利,但在任务调度程序调用它时甚至还没有工作。没有权限问题,因为我是管理员,我甚至试图在我们的IT主管凭据下运行它无济于事。还检查该文件夹是否具有创建/删除/编辑/等的完全访问权限。还尝试提供文件的绝对路径来代替相对路径。可以在下面找到用于创建excel文件的代码以及调用它的代码。提前谢谢。
Excel代码:
public static void Export(System.Data.DataTable dt,
string FileName,
string EmailTo)
{
Application xls = new Application();
xls.SheetsInNewWorkbook = 1;
// Create our new excel application and add our workbooks/worksheets
Workbooks workbooks = xls.Workbooks;
Workbook workbook = workbooks.Add();
Worksheet CompPartsWorksheet = (Worksheet)xls.Worksheets[1];
// Hide our excel object if it's visible.
xls.Visible = false;
// Turn off screen updating so our export will process more quickly.
xls.ScreenUpdating = false;
// Turn off calculations if set to automatic; this can help prevent memory leaks.
xls.Calculation = xls.Calculation == XlCalculation.xlCalculationAutomatic ? XlCalculation.xlCalculationManual : XlCalculation.xlCalculationManual;
// Create an excel table and fill it will our query table.
CompPartsWorksheet.Name = "Comp Request";
CompPartsWorksheet.Select();
{
// Create a row with our column headers.
for (int column = 0; column < dt.Columns.Count; column++)
{
CompPartsWorksheet.Cells[1, column + 1] = dt.Columns[column].ColumnName;
}
// Export our datatable information to excel.
for (int row = 0; row < dt.Rows.Count; row++)
{
for (int column = 0; column < dt.Columns.Count; column++)
{
CompPartsWorksheet.Cells[row + 2, column + 1] = (dt.Rows[row][column].ToString());
}
}
}
// Freeze our column headers.
xls.Application.Range["2:2"].Select();
xls.ActiveWindow.FreezePanes = true;
xls.ActiveWindow.DisplayGridlines = false;
// Autofit our rows and columns.
xls.Application.Cells.EntireColumn.AutoFit();
xls.Application.Cells.EntireRow.AutoFit();
// Select the first cell in the worksheet.
xls.Application.Range["$A$2"].Select();
// Turn off alerts to prevent asking for 'overwrite existing' and 'save changes' messages.
xls.DisplayAlerts = false;
// ******************************************************************************************************************
// This section is commented out for now but can be enabled later to have excel sheets show on screen after creation.
// ******************************************************************************************************************
// Make our excel application visible
//xls.Visible = true;
//// Turn screen updating back on
//xls.ScreenUpdating = true;
//// Turn automatic calulation back on
//xls.Calculation = XlCalculation.xlCalculationAutomatic;
string SaveFilePath = string.Format(@"{0}\Jobs\{1}.xlsx", Directory.GetCurrentDirectory(), FileName);
// string SaveFilePath = @"\\netapp02\Batch_Processes\Comp_Wisp\Comp_Wisp\bin\Debug\Jobs";
workbook.SaveAs(SaveFilePath, XlFileFormat.xlWorkbookNormal, Type.Missing, Type.Missing, Type.Missing, Type.Missing, XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);
workbook.Close();
// Release our resources.
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(workbooks);
Marshal.ReleaseComObject(CompPartsWorksheet);
Marshal.ReleaseComObject(xls);
Marshal.FinalReleaseComObject(xls);
Send(Subject: FileName,
AttachmentPath: SaveFilePath,
EmailTo: EmailTo);
}
代码调用Excel创建方法:
public static void ProcessJob(System.Data.DataTable Job)
{
try
{
for (int j = 0; j < Job.Rows.Count; j++)
{
// Temporary datatable to store our excel data.
System.Data.DataTable dt = new System.Data.DataTable();
// Output the current job name and split out our parts.
Console.Write(string.Format("JOB: {0}\r\n", Job.Rows[j]["JobID"]));
string[] searchlines = Job.Rows[j]["PartsList"].ToString().Replace("\n", "|").Split('|');
if (searchlines.Count() > MAX_TO_PROCESS)
{
// If our search is going to be above the desired processing maximum start the next job as well.
Thread RecursiveJob = new Thread(GetJob);
RecursiveJob.Start();
}
for (int i = 0; i < searchlines.Count(); i++)
{
// Determine if data reporting is turned on or off.
Boolean isReporting = DataCollection();
if (searchlines[i].Trim() != string.Empty)
{
Console.WriteLine(string.Format("Processing: {0}", searchlines[i]));
using (SqlConnection con = new SqlConnection(dbComp))
{
using (SqlDataAdapter da = Connect.ExecuteAdapter("[CompDatabase_SelectPartsFromComp]", con,
new SqlParameter("@PartNumber", searchlines[i].Trim()),
new SqlParameter("@CurrentMember", Job.Rows[j]["Email"].ToString()),
new SqlParameter("@DataCollection", isReporting)))
{
da.Fill(dt);
}
}
}
}
// Export our datatable to an excel sheet and save it.
try
{
Export(dt: dt,
FileName: string.Format("Comp Scheduled Job {0}", Job.Rows[j]["JobID"].ToString()),
EmailTo: Job.Rows[j]["Email"].ToString().Trim());
}
catch (Exception ex)
{
ErrorLog.Write(SourceName: "Comp Wisp",
ErrorMessage: ex.ToString(),
MethodOrFunction: "ProcessJob",
MemberName: Environment.UserName,
ErrorDescription: string.Format("Failed to create excel file on Job {0}.", Job.Rows[j]["JobID"].ToString()));
}
// Update the job to Complete in our database.
using (SqlConnection con = new SqlConnection(dbComp))
{
Console.WriteLine("Updating Job Status");
using (SqlDataReader dr = Connect.ExecuteReader("[CompWisp_UpdateJobStatus]", con,
new SqlParameter("@JobID", Job.Rows[j]["JobID"].ToString()))) { }
}
Console.Write("Complete\r\n\r\n");
}
GetJob();
}
catch (Exception ex)
{
ErrorLog.Write(SourceName: "CompWisp",
ErrorMessage: ex.ToString(),
MethodOrFunction: "ProcessJob");
}
}
答案 0 :(得分:1)
当任务计划程序运行作业时,与Directory.GetCurrentDirectory()
的调用可能会返回不同的值,而不是手动运行应用程序时。
要对此进行测试,您可以尝试在服务器上搜索缺少的Excel文件。
答案 1 :(得分:0)
您可能会尝试以下几种方法:
确保运行任务的用户没有启用UAC。这可能会导致执行问题。
同样,请查看以下文章是否有帮助。答案(可能)是第一个列出的回复:MSDN forum question。
答案 2 :(得分:0)
我无法让Task Scheduler运行创建Excel电子表格的应用程序。我需要创建此文件夹才能使其正常工作。 C:\ Windows \ SysWow64资料\配置\ systemprofile \桌面
这是我从
获取信息的地方