2016-01-29 81 views
5

我有一个c#应用程序,它需要创建一个Excel应用程序&然后打开一个工作簿。问题是我需要在Excel打开时加载一个彭博插件。我发现的唯一方法是在这篇文章working example从c#应用程序的插件开始excel应用程序

这确实开始excel并能够使用彭博功能。然而,我想知道是否有办法将myXl强制转换为xlApp,其中xlApp的类型为Microsoft.Office.Interop.Excel.Application?

var myXl = Process.Start("excel.exe"); 

之所以存在是我有有一些有用的功能,我想使用的库,但它需要类型Microsoft.Office.Interop.Excel.Application的一个参数。我该怎么做呢?

+2

添加对Excel库的引用,而不是var myXL,您可以实例化工作簿对象Excel.Application myXl = New Excel.Application(); – Sorceri

+0

虽然问题是bloomberg addinn不使用该方法加载 – mHelpMe

+0

你见过这篇文章:http:// stackoverflow。com/questions/213375/loading-addins-when-excel-is-instantiated-programmatically –

回答

0

添加引用到Excel的图书馆,而是变种myXL可以实例化一个工作簿对象

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

然后你只需要手动加载加载项。

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

您可以从外部应用程序自动执行Excel。有关更多信息,请参阅How to automate Microsoft Excel from Microsoft Visual C#.NETC# app automates Excel (CSAutomateExcel)

Application类提供了访问插件以下属性:

  • AddIns - 返回AddIns集合,表示所有加载项对话框中列出的加载项(在加载项命令开发人员选项卡); XLL加载项。
  • COMAddIns - 返回代表当前安装的COM加载项的Microsoft Excel的COMAddIns集合。

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

1

您可以使用下面的代码:

这将启动Excel,然后通过在运行对象表中注册的所有工作簿的发现,在刚开始进程中运行的一个。为此,它会获取Workbook的窗口句柄的进程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; 
}