使用c#application中的addins启动excel应用程序

时间:2016-01-29 16:11:58

标签: c# .net office-interop excel-interop

我有一个c#app,它需要创建一个excel应用程序&然后打开一本工作簿。问题是我需要在excel打开时加载Bloomberg addinn。我发现的唯一方法是在这篇文章working example中。

这确实启动了excel并且能够使用Bloomberg功能。但是我想知道是否有办法将myXl转换为xlApp,其中xlApp的类型为Microsoft.Office.Interop.Excel.Application?

CreateProcessAsUser

原因是我有一个库,它有一些我希望使用的有用功能,但它需要一个类型为Microsoft.Office.Interop.Excel.Application的参数。我该怎么做?

3 个答案:

答案 0 :(得分:3)

您可以从外部应用程序自动化Excel。有关详细信息,请参阅https://github.com/atom/electron/blob/v0.36.6/docs/faq/electron-faq.md#requireelectronxxx-is-undefinedHow to automate Microsoft Excel from Microsoft Visual C#.NET

Application类提供了以下用于访问加载项的属性:

  • C# app automates Excel (CSAutomateExcel) - 返回一个AddIns集合,表示“加载项”对话框中列出的所有加载项(“开发人员”选项卡上的“加载项”命令); XLL加载项。
  • AddIns - 返回Microsoft Excel的COMAddIns集合,代表当前安装的COM插件。

因此,如果您需要确保启用了COM加载项,则需要使用Application类的ComAddins属性。

答案 1 :(得分:1)

您可以使用以下代码:

这将启动Excel,然后浏览在运行对象表中注册的所有工作簿,以查找刚刚启动的进程中运行的工作簿。为此,它获取工作簿的窗口句柄的进程ID,并将其与刚刚启动的进程的id进行比较。

查看运行对象表会重复几次,其间会有等待时间,因为Excel在启动后可能需要一些时间来注册ROT。您可能需要在较慢的计算机上增加maxAttemptswaitTimeMS

如果找到了正确的工作簿,则返回该工作簿。在样本中,我将编写" hello world"进入Excel应用程序实例的第一个单元格。

private void button1_Click(object sender, EventArgs e)
{
     Microsoft.Office.Interop.Excel.Application excelApplication = StartExcel();

    if (excelApplication != null)
    {
        excelApplication.ActiveCell.Value = "Hello World";
    }
}

[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);

[DllImport("ole32.dll")]
private static extern int GetRunningObjectTable(int reserved, out IRunningObjectTable prot);

private Microsoft.Office.Interop.Excel.Application StartExcel()
{
    // Maximum number of attempts to look for started Excel Application
    const int maxAttempts = 3;
    // Number of milliseconds to wait between attempts to look for started Excel Application
    const int waitTimeMS = 200;

    Microsoft.Office.Interop.Excel.Application result = null;

    // Start Excel
    var process = Process.Start("Excel.exe");
    process.WaitForInputIdle();

    // Try to find started Excel Application

    int currentAttempt = 1;

    while ((result == null) && (currentAttempt <= maxAttempts))
    {
        // Wait between attempts 
        if(currentAttempt != 1)
        {
            Thread.Sleep(waitTimeMS);
        }

        // List all running Excel automation objects and find the one with the same process id
        IRunningObjectTable lRunningObjectTable = null;
        IEnumMoniker lMonikerList = null;

        try
        {
            // Query Running Object Table 
            if (GetRunningObjectTable(0, out lRunningObjectTable) == 0 && lRunningObjectTable != null)
            {

                // List Monikers
                lRunningObjectTable.EnumRunning(out lMonikerList);

                // Start Enumeration
                lMonikerList.Reset();

                // Array used for enumerating Monikers
                IMoniker[] lMonikerContainer = new IMoniker[1];

                IntPtr lPointerFetchedMonikers = IntPtr.Zero;

                // foreach Moniker
                while (lMonikerList.Next(1, lMonikerContainer, lPointerFetchedMonikers) == 0)
                {
                    object lComObject;
                    lRunningObjectTable.GetObject(lMonikerContainer[0], out lComObject);

                    // Check the object is an Excel workbook
                    if (lComObject is Microsoft.Office.Interop.Excel.Workbook)
                    {
                        Microsoft.Office.Interop.Excel.Workbook lExcelWorkbook = (Microsoft.Office.Interop.Excel.Workbook)lComObject;

                        // Get the Process ID for the Window Handle 
                        uint processId;
                        GetWindowThreadProcessId(new IntPtr(lExcelWorkbook.Application.Hwnd), out processId);

                        if (processId == process.Id)
                        {
                            // Correct automation object found, return Application
                            result = lExcelWorkbook.Application;
                            break;
                        }
                    }
                }
            }
        }
        finally
        {
            // Release ressources
            if (lRunningObjectTable != null) Marshal.ReleaseComObject(lRunningObjectTable);
            if (lMonikerList != null) Marshal.ReleaseComObject(lMonikerList);
        }

        currentAttempt++;
    }


    return result;
}

答案 2 :(得分:0)

添加对Excel库的引用,而不是var myXL,您可以实例化工作簿对象

Excel.Application myXl = New Excel.Application();  

然后您只需手动加载加载项。

        foreach (Excel.AddIn item in myXl.AddIns)
        {
            if (item.Name.Equals("BLOOMBERG ADDIN NAME"))
            {
                item.Installed = true;
            }
        }