Существует вероятность того, что вы потеряли свою область данных, потому что ваш модал удаления имеет значение *ngIf
и удаляется при нажатии кнопки get. Итак, в основном компонент умирает (он удален из DOM), все его this
не определены, пока вы пытаетесь обратиться к этим данным из другого компонента через генератор событий. Подумайте об использовании общего сервиса для прохождения этого сообщения об удалении через компоненты:
Укажите общий предмет в сервисе, выделите этот предмет в модале удаления и подпишитесь на него в клиентском компоненте.
У меня нет кода для вручения, но я действительно сталкивался с подобной проблемой. Если я вспоминаю правильно, я закончил тем, что получил идентификатор процесса экземпляра Excel и уничтожил его (после того, как подходящий период ожидания, и когда другой метод перестал работать).
Я думаю, что использовал:
GetWindowThreadProcessId
(через P/Invoke) на Excel возражают hwnd свойству для получения идентификатора процесса, и затем используемый Process.GetProcessById
получить объект процесса. После того как я сделал это, я буду звонить Kill
на процессе.
Править: Я должен признать, это не идеальное решение, но если Вы не можете найти интерфейс жулика, который не выпускается, затем это зафиксирует его истинным способом яичной скорлупы/кувалды. ;)
EDIT2: Вы не должны звонить Kill
на процессе сразу возражают... Вы могли сначала попытаться звонить Close
прежде, чем обратиться к Kill
.
Я сделал подобную вещь. Я создаю файл Excel или открываю существующее. Я удаляю все листы и добавляю мое собственное. вот код, который я использую, чтобы гарантировать, что все ссылки закрываются:
workbook.Close(true, null, null);
excelApp.Quit();
if (newSheet != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(newSheet);
}
if (rangeSelection != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(rangeSelection);
}
if (sheets != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);
}
if (workbook != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(workbook);
}
if (excelApp != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(excelApp);
}
newSheet = null;
rangeSelection = null;
sheets = null;
workbook = null;
excelApp = null;
GC.Collect();
Я протестировал это со многими различными вариантами и не имел его сбой на мне все же.
Не очень конструктивный я знаю, но я протестировал код точно как показано выше и мои выходы процесса Excel как ожидалось, мой C:\addtest.xls находится с 8 новыми листами, и никакой процесс Excel не работает.
interop версия могла быть причиной, интересно? Я протестировал с 11 и 12.
Я использую VB.NET, 3,5 SP1 и следующий код ВСЕ ЕЩЕ оставляют EXCEL.EXE открытым:
xlWorkbook.Close(SaveChanges:=False)
xlApplication.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlRange)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorksheet)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlSheets)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlWorkbook)
System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApplication)
xlRange = Nothing
xlWorksheet = Nothing
xlSheets = Nothing
xlWorkbook = Nothing
xlApplication = Nothing
GC.GetTotalMemory(False)
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.WaitForPendingFinalizers()
GC.Collect()
GC.GetTotalMemory(True)
Andrew, вот код, я нашел что работы. Я думал, что отправляю, отправляют его здесь для других, которые сталкиваются:
namespace WindowHandler
{
using System;
using System.Text;
using System.Collections;
using System.Runtime.InteropServices;
/// <summary>
/// Window class for handling window stuff.
/// This is really a hack and taken from Code Project and mutilated to this small thing.
/// </summary>
public class Window
{
/// <summary>
/// Win32 API import for getting the process Id.
/// The out param is the param we are after. I have no idea what the return value is.
/// </summary>
[DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out IntPtr ProcessId);
/// <summary>
/// Gets a Window's process Id.
/// </summary>
/// <param name="hWnd">Handle Id.</param>
/// <returns>ID of the process.</returns>
public static IntPtr GetWindowThreadProcessId(IntPtr hWnd)
{
IntPtr processId;
IntPtr returnResult = GetWindowThreadProcessId(hWnd, out processId);
return processId;
}
}
}
вот мой полный код, чтобы убить Excel, который вы создали с помощью библиотеки взаимодействия Office12 .Net: {{1 }} Наслаждайтесь, - Алан.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Microsoft.Office.Interop.Excel;
class Program
{
/// <summary>
/// Win32 API import for getting the process Id.
/// The out param is the param we are after. I have no idea what the return value is.
/// </summary>
[DllImport("user32.dll")]
private static extern IntPtr GetWindowThreadProcessId(IntPtr hWnd, out IntPtr ProcessId);
static void Main(string[] args)
{
var app = new Application();
IntPtr hwnd = new IntPtr(app.Hwnd);
IntPtr processId;
IntPtr foo = GetWindowThreadProcessId(hwnd, out processId);
Process proc = Process.GetProcessById(processId.ToInt32());
proc.Kill(); // set breakpoint here and watch the Windows Task Manager kill this exact EXCEL.EXE
app.Quit(); // should give you a "Sorry, I can't find this Excel session since you killed it" Exception.
}
}