2009-07-20 76 views
6

我有一个AddIn,我想通过Excel Interop从C#winforms应用程序调用。如何使用Interop加载Excel加载项

我不能得到插件等加载,除非我每次卸载和resinstall它(这是显然是Excel not loading addins when you use interop - 顺便说一句,无法让他们的例子在C#中工作)。不幸的是,这对用户来说很慢并且很烦人,所以我需要简化它。

我想有一个Excel实例,但加载已安装的插件而不强制安装/重新安装问题。

我搜索和搜索,但我发现在谷歌上的一切都给出了安装/重新安装的解决方案。有没有其他方法?加载项已安装,我只是想要加载它。

这就是我目前做的(从google'd建议采取):

// loop over the add-ins and if you find it uninstall it. 
foreach (AddIn addIn in excel.AddIns) 
    if (addIn.Name.Contains("My Addin")) 
     addin.Installed = false; 

    // install the addin 
    var addin = excel.AddIns.Add("my_addin.xll", false); 
     addin.Installed = true; 
+0

你能,为什么你需要做的安装/卸载解释一下吗?我试图了解Excel加载插件的方式,一旦您将其设置为每次加载。为什么需要安装/卸载? – shahkalpesh 2009-07-20 16:48:59

回答

7

过了一会儿,我发现隐藏在陌生的地方在MS help了答案:和this blog post

这不是你需要的所有信息。注意事项:您必须至少打开一个工作簿或Excel barfs。这里的一些rudementry代码开始:

var excel = new Application(); 
var workbook = excel.workbooks.Add(Type.Missing); 
excel.RegisterXLL(pathToXll); 
excel.ShowExcel(); 

如果你愿意,你可以关闭该工作簿临时(如果你运行一些宏等),并记住一切都收拾起来,用大量调用Marshal.ReleaseComObject的了!

0

看来你必须得到正确的Excel过程才能使用。使用此类打开Excel文档:

class ExcelInteropService 
{ 
    private const string EXCEL_CLASS_NAME = "EXCEL7"; 

    private const uint DW_OBJECTID = 0xFFFFFFF0; 

    private static Guid rrid = new Guid("{00020400-0000-0000-C000-000000000046}"); 

    public delegate bool EnumChildCallback(int hwnd, ref int lParam); 

    [DllImport("Oleacc.dll")] 
    public static extern int AccessibleObjectFromWindow(int hwnd, uint dwObjectID, byte[] riid, ref Window ptr); 

    [DllImport("User32.dll")] 
    public static extern bool EnumChildWindows(int hWndParent, EnumChildCallback lpEnumFunc, ref int lParam); 

    [DllImport("User32.dll")] 
    public static extern int GetClassName(int hWnd, StringBuilder lpClassName, int nMaxCount); 

    public static Application GetExcelInterop(int? processId = null) 
    { 
     var p = processId.HasValue ? Process.GetProcessById(processId.Value) : Process.Start("excel.exe"); 
     try 
     { 
      Thread.Sleep(5000); 
      return new ExcelInteropService().SearchExcelInterop(p); 
     } 
     catch (Exception) 
     { 
      Debug.Assert(p != null, "p != null"); 
      return GetExcelInterop(p.Id); 
     } 
    } 

    private bool EnumChildFunc(int hwndChild, ref int lParam) 
    { 
     var buf = new StringBuilder(128); 
     GetClassName(hwndChild, buf, 128); 
     if (buf.ToString() == EXCEL_CLASS_NAME) { lParam = hwndChild; return false; } 
     return true; 
    } 

    private Application SearchExcelInterop(Process p) 
    { 
     Window ptr = null; 
     int hwnd = 0; 

     int hWndParent = (int)p.MainWindowHandle; 
     if (hWndParent == 0) throw new Exception(); 

     EnumChildWindows(hWndParent, EnumChildFunc, ref hwnd); 
     if (hwnd == 0) throw new Exception(); 

     int hr = AccessibleObjectFromWindow(hwnd, DW_OBJECTID, rrid.ToByteArray(), ref ptr); 
     if (hr < 0) throw new Exception(); 

     return ptr.Application; 
    } 
} 

使用类应用程序是这样的:

static void Main(string[] args) 
{ 
    Microsoft.Office.Interop.Excel.Application oExcel = ExcelInteropService.GetExcelInterop(); 
    foreach (AddIn addIn in oExcel.AddIns) 
     { 
      addIn.Installed = true; 
     } 
} 
相关问题