Как и другие, я борюсь с операцией приложения Excel в C#, в которой я не могу должным образом закрыть фоновый процесс Excel, несмотря на попытку отменить регистрацию всех объектов COM. В моем приложении я извлекаю данные имени тега для историка данных. Приложение ссылается на электронную таблицу Excel для получения имен тегов, используемых в контроллере, который я обрабатываю в нисходящем направлении.
Рассматриваемый метод выглядит следующим образом:
public class StoreGroupTags
{
public static TagGroup StoreDCSTags()
{
// Diagnostic timer
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Console.WriteLine("Storing DCS Tags...");
TagGroup Tags = new TagGroup();
XlObjHandler xlObj = new XlObjHandler();
try
{
Excel.Application xlApp = xlObj.Add(new Excel.Application());
Excel.Workbooks xlWorkbooks = xlObj.Add(xlApp.Workbooks);
Excel.Workbook xlWorkbook = xlObj.Add(xlWorkbooks.Open(@"C:\Temp\Master File.xlsx"));
Excel.Sheets xlWorkSheets = xlObj.Add(xlWorkbook.Sheets);
Excel.Worksheet xlWorkSheet = xlObj.Add(xlWorkSheets[1]);
Excel.Range xlRange = xlObj.Add(xlWorkSheet.Cells);
int colCount = 119; // Column(Indirect((REF)) in excel to get this value
for (int i = 1; i < colCount + 1; i++)
{
string tagName = xlObj.Add(xlRange.Cells[4, i]).Value.ToString();
Tag readData = new Tag($"{tagName}");
readData = CheckTagsForStrings(readData);
Tags.AddTag(readData);
}
xlWorkbook.Close();
xlWorkbooks.Close();
xlApp.Quit();
}
catch (Exception exception)
{
Console.WriteLine("Exception thrown during StoreDCsTags(): " + exception);
}
finally
{
xlObj.Unregister();
// Clean up of anything else...
GC.Collect();
GC.WaitForPendingFinalizers();
}
stopwatch.Stop();
Console.WriteLine("StoreDCSTags() took: " + stopwatch.ElapsedMilliseconds + "ms");
return Tags;
}
Вы можете заметить, что Я "регистрирую" каждый объект Excel в оболочке. Я упомянул метод, представленный: { ссылка }, который был очень полезен для отслеживания того, что я называю, и того, что вынуждено отменить регистрацию с помощью маршала. Используя это (и до того, как я попробовал это, без использования оболочки), я смог определить, что for l oop предотвращает закрытие приложения в фоновом режиме. А именно, если я закомментирую для l oop, приложение успешно закроется. Поэтому я считаю, что проблема изолирована от ссылки xlRange.Cells[4,i].Value
. Внутри Excel больше нет вызовов для этого для l oop, за исключением xlRange.Cells.
Я не уверен, но пока могу обернуть каждый объект xlRange.Cells[4,i]
и сделать попытку закрытия оболочки это, я не могу сказать, если .Value
ТАКЖЕ создает СО-объект (хотя тип - Dynami c, пока я не добавлю .ToString ()), который препятствует закрытию приложения. Я читал, что двойные точки - нет-нет в вызовах Interop, но будет ли это квалифицироваться как ситуация с двумя точками? При попытке деформации xlRange.Cells[4,i].Value
я получаю недопустимую ошибку аргумента из оболочки (что имеет смысл, поскольку это не тип "Excel.Application / Workbooks / Workbook / et c"). Кто-нибудь может уточнить, являются ли типы .Value dynamici c на самом деле объектами COM? Может ли кто-нибудь пролить свет на то, какие COM-объекты все еще могут быть «открыты» в этом классе и, возможно, как успешно захватить и закрыть их?
Большое спасибо!