C# interop: превзойдите процесс, не выходящий после добавления нового рабочего листа в существующий файл [дубликат]

Существует вероятность того, что вы потеряли свою область данных, потому что ваш модал удаления имеет значение *ngIf и удаляется при нажатии кнопки get. Итак, в основном компонент умирает (он удален из DOM), все его this не определены, пока вы пытаетесь обратиться к этим данным из другого компонента через генератор событий. Подумайте об использовании общего сервиса для прохождения этого сообщения об удалении через компоненты:

Укажите общий предмет в сервисе, выделите этот предмет в модале удаления и подпишитесь на него в клиентском компоненте.

8
задан Community 23 May 2017 в 12:23
поделиться

6 ответов

У меня нет кода для вручения, но я действительно сталкивался с подобной проблемой. Если я вспоминаю правильно, я закончил тем, что получил идентификатор процесса экземпляра Excel и уничтожил его (после того, как подходящий период ожидания, и когда другой метод перестал работать).

Я думаю, что использовал:

GetWindowThreadProcessId (через P/Invoke) на Excel возражают hwnd свойству для получения идентификатора процесса, и затем используемый Process.GetProcessById получить объект процесса. После того как я сделал это, я буду звонить Kill на процессе.

Править: Я должен признать, это не идеальное решение, но если Вы не можете найти интерфейс жулика, который не выпускается, затем это зафиксирует его истинным способом яичной скорлупы/кувалды. ;)

EDIT2: Вы не должны звонить Kill на процессе сразу возражают... Вы могли сначала попытаться звонить Close прежде, чем обратиться к Kill.

4
ответ дан 5 December 2019 в 07:37
поделиться

Я сделал подобную вещь. Я создаю файл 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();

Я протестировал это со многими различными вариантами и не имел его сбой на мне все же.

13
ответ дан 5 December 2019 в 07:37
поделиться

Не очень конструктивный я знаю, но я протестировал код точно как показано выше и мои выходы процесса Excel как ожидалось, мой C:\addtest.xls находится с 8 новыми листами, и никакой процесс Excel не работает.
interop версия могла быть причиной, интересно? Я протестировал с 11 и 12.

0
ответ дан 5 December 2019 в 07:37
поделиться

Я использую 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)
0
ответ дан 5 December 2019 в 07:37
поделиться

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;
    }
}
}
0
ответ дан 5 December 2019 в 07:37
поделиться

вот мой полный код, чтобы убить 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.
    }
}
4
ответ дан 5 December 2019 в 07:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: