Как подключить открытое приложение Excel в net .core 3.1? - PullRequest
1 голос
/ 10 апреля 2020

В Net. Рамки Я могу использовать следующую функцию для работы с открытым экземпляром приложения Excel:

using Excel = Microsoft.Office.Interop.Excel;
public static Excel.Workbook GetOpenedExcelWorkbook(string workBookName)
{
    Excel.Application xlsApp = null;
    try { xlsApp = (Excel.Application)Marshal.GetActiveObject("Excel.Application"); }
    catch { return null; }

    foreach (Excel.Workbook wb in xlsApp.Workbooks)
    {
        if (wb.Name == workBookName)
            return wb;
    }
    return null;
}

Это удобно, потому что пользователь может просто нажимать кнопки на листе Excel и вызывать все необходимые процедуры. И я могу написать код для работы с Excel на C#, который является более полезным и мощным, чем VBA. Следующий код в VBA используется для вызова C# консольного приложения при нажатии на кнопки в Excel. Он находит соответствующий exe-файл рядом с активным файлом Excel и вызывает его через команду Shell в VBA с необходимыми аргументами.

Sub Button1_Click()
    Call ExeCaller("ConsoleApp.exe", "Button1_action_arg")
End Sub


Sub ExeCaller(ExeName As String, Optional cmd As String = "")
    Dim arg As String
    If Not Dir(ExeName) = "" Then
        arg = ExeName & " " & ActiveWorkbook.Name & IIf(cmd = "", "", " " & cmd)
    Else
        Dim pathToWB As String: pathToWB = ThisWorkbook.Path
        Dim pathToExe_Release As String: pathToExe_Release = pathToWB + "\bin\Release\" + ExeName
        Dim pathToExe_Debug As String:   pathToExe_Debug = pathToWB + "\bin\Debug\" + ExeName

        Dim dr As Double, dd As Double
        If Not Dir(pathToExe_Release) = "" Then dr = FileDateTime(pathToExe_Release)
        If Not Dir(pathToExe_Debug) = "" Then dd = FileDateTime(pathToExe_Debug)
        Dim dmax As Double: dmax = IIf(dr > dd, dr, dd)

        If (dmax = 0) Then
            If Not Dir(ExeName) = "" Then
                pathToExe = ExeName
            Else
                MsgBox "File " + ExeName + "not found!", vbCritical, Error
                Exit Sub
            End If
        ElseIf dmax = dr Then
            pathToExe = pathToExe_Release
        ElseIf dmax = dd Then
            pathToExe = pathToExe_Debug
        Else

            MsgBox "File " + ExeName + "not found!", vbCritical, Error
            Exit Sub
        End If

        arg = pathToExe & " " & ActiveWorkbook.Name & IIf(cmd = "", "", " " & cmd)
    End If

    Shell arg, vbNormalFocus
End Sub

Ключевая функциональность, которая делает это возможным, - Marshal.GetActiveObject(string ProgID) в C#, то есть доступно в Net.

Теперь я пытаюсь перейти на Net .Core 3.1. Можно использовать объектную модель Excel в Net .Core следующим образом: https://github.com/dotnet/samples/tree/master/core/extensions/ExcelDemo, чтобы я мог создать новый экземпляр Excel.Application и через него создать новую или открыть существующую книгу Excel и работать с ним со всеми функциями. НО я не могу подключиться к открытой книге Excel, потому что в Net .Core нет функции Marshal.GetActiveObject (string ProgID). Предварительный просмотр Net .Core 5 также не имеет. И нет аналогичной функции.

Я пытался сделать это с Marshal.GetObjectForIUnknown (IntPtr pUnk), который доступен в Net .Core. Как я знаю, Excel.Application является COM-объектом и поэтому имеет интерфейс IUnknown. Я попытался получить этот указатель в процессе открытого приложения Excel, которое можно найти по имени. Я использовал этот наивный код:

public static Excel.Application GetOpenedExcelApplication()
{
    Process[] aP = Process.GetProcesses();
    foreach (Process p in aP)
    {
        string pn = p.ProcessName.ToLower();

        if (Regex.IsMatch(pn, "excel*"))
        {
            object o = Marshal.GetObjectForIUnknown(p.Handle);
            Excel.Application app = (Excel.Application)o;
            return app;
        }
    }

    return null;
}

Возникла исключительная ситуация System.ExecutionEngineException в линии вызова Marshall.GetObjectForIUnknown ().

Есть ли в Net .Core способ получить доступ к открыть книгу Excel?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...