2009-07-20 44 views
6

Tôi có một AddIn mà tôi muốn gọi thông qua Excel interop từ một ứng dụng C# winforms.Làm thế nào để tải một Excel Addin bằng cách sử dụng Interop

Tôi không thể tải phần bổ trợ, trừ khi tôi gỡ cài đặt và cài đặt lại mỗi lần (điều này có thể làm điều gì đó với Excel not loading addins when you use interop - btw, không thể lấy ví dụ của chúng để làm việc trong C#). Thật không may điều này là chậm và gây phiền nhiễu cho người dùng vì vậy tôi cần phải sắp xếp nó.

Tôi muốn có một phiên bản Excel nhưng tải một addin đã được cài đặt mà không cần phải cài đặt/cài đặt lại vấn đề này.

Tôi đã tìm kiếm và tìm kiếm nhưng mọi thứ tôi tìm thấy trên google đều cung cấp giải pháp để cài đặt/cài đặt lại. Còn cách nào khác không? Add-in được cài đặt, tôi chỉ muốn excel để tải nó.

Đây là những gì tôi đang làm vào lúc này (lấy từ lời khuyên 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

Ông có thể giải thích là tại sao bạn cần phải làm Install/Uninstall? Tôi đang cố gắng để hiểu cách thức mà Excel tải addin, một khi bạn đặt nó để tải mỗi lần. Tại sao nó yêu cầu cài đặt/bỏ cài đặt? – shahkalpesh

+0

mã này được gọi từ đâu? tôi giả sử một AddIn Excel? hoặc chỉ là một ứng dụng C# winform? –

+0

Tôi đã cập nhật câu hỏi với các điểm mà bạn nêu ra nhưng nhanh chóng: Excel không tải bổ sung thông qua interop, mọi thứ tôi đã tìm thấy trên mạng cho biết gỡ cài đặt/cài đặt là giải pháp. Mã đang được gọi từ ứng dụng C# winforms – user35149

Trả lời

7

Sau một thời gian tôi thấy câu trả lời ẩn ở những nơi lạ trong MS help: và this blog post.

Đó không phải là tất cả thông tin bạn cần. Những điều cần lưu ý: bạn phải có ít nhất một sổ làm việc mở hoặc bằng cách khác là Excel barfs. Dưới đây là một số mã rudementry để bắt đầu:

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

Nếu bạn muốn, bạn có thể đóng cửa sổ làm việc tạm thời (nếu bạn đã chạy một số macro vv) và nhớ để dọn dẹp mọi thứ lên với rất nhiều cuộc gọi đến Marshal.ReleaseComObject!

0

Dường như bạn phải làm đúng quy trình Excel để làm việc. Sử dụng lớp này để mở tài liệu 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; 
    } 
} 

Sử dụng các lớp trong ứng dụng của bạn như thế này:

static void Main(string[] args) 
{ 
    Microsoft.Office.Interop.Excel.Application oExcel = ExcelInteropService.GetExcelInterop(); 
    foreach (AddIn addIn in oExcel.AddIns) 
     { 
      addIn.Installed = true; 
     } 
} 
Các vấn đề liên quan