Планировщик заданий не запускает Excel в приложении

Я написал приложение, настроенное на доступ к нашему серверу, проверку наличия каких-либо ожидающих заданий, обработку этих заданий, если они есть, создание документа Excel с результатами, а затем отправку их по электронной почте нашему пользователю. Он написан на c#.net v3.5 с использованием Microsoft Excel 2010 и запускается каждые 30 минут через планировщик задач. Наш планировщик задач работает на сервере под управлением 2008 r2. Планировщик задач работает успешно, база данных успешно обновляется, как будто задание обрабатывается, однако он никогда не создает файл 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");
            }
        }

person Volearix    schedule 02.01.2014    source источник
comment
@GrantWinney Да, я также попробовал абсолютный путь, и это не удалось.   -  person Volearix    schedule 02.01.2014
comment
@GrantWinney Если вы назовете это ответом, я приму его. Это было связано с этим, я тестировал его однажды раньше, но была предыдущая проблема, не позволявшая даже добраться до этой части, и я думаю, что другой разработчик, работающий над этим, изменил его до того, как мы исправили первоначальную проблему... ›. ‹   -  person Volearix    schedule 02.01.2014


Ответы (3)


Вызов Directory.GetCurrentDirectory() может возвращать другое значение, когда планировщик заданий запускает задание, по сравнению с тем, когда вы запускаете приложение вручную.

Чтобы проверить это, вы можете попробовать выполнить поиск отсутствующих файлов Excel на сервере.

person Grant Winney    schedule 02.01.2014

Есть несколько вещей, которые вы можете попробовать:

  1. Убедитесь, что у пользователя, под которым выполняется задача, не включен контроль учетных записей. Это может вызвать проблемы с выполнением.

  2. Кроме того, посмотрите, поможет ли следующая статья. Ответ (возможно) является первым ответом в списке: on-top-of-a-windows-server-2008-x64?forum=innovateonoffice" rel="nofollow">вопрос форума MSDN.

person Javelin    schedule 02.01.2014

У меня возникли проблемы с тем, чтобы планировщик заданий запускал приложения, создающие электронные таблицы Excel. Мне нужно было создать эту папку, чтобы заставить ее работать. C:\windows\syswow64\config\systemprofile\рабочий стол

Вот откуда я взял информацию

Чтение Excel с помощью Microsoft взаимодействие в 64-битной версии

person Keith Aymar    schedule 20.12.2017