Вопрос по interop, c#, excel – Как загрузить надстройку Excel с помощью Interop

6

У меня есть AddIn, который я хочу вызвать через Excel взаимодействия из приложения C # winforms.

Я не могу загрузить надстройку и т. Д., Если не удаляю и не устанавливаю ее каждый раз (это явно связано сExcel не загружает надстройки при использовании взаимодействия - Кстати, не могу заставить их пример работать в C #). К сожалению, это медленно и раздражает пользователя, поэтому мне нужно упростить его.

Я хочу иметь один экземпляр Excel, но загрузить уже установленную надстройку, не вызывая этой проблемы установки / переустановки.

Я искал и искал, но все, что я нашел в Google, дает решение для установки / переустановки. Есть ли другой путь? Надстройка установлена, я просто хочу, чтобы Excel загрузил ее.

Вот что я делаю в данный момент (взято из совета Google):

// 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;
Я обновил вопрос с учетом вопросов, которые вы подняли, но быстро: Excel не загружает надстройки через взаимодействие, все, что я обнаружил в сети, говорит, что удаление / установка - это решение. Код вызывается из приложения c # winforms user35149
откуда этот код вызывается? я предполагаю другой Excel AddIn? или просто приложение winform C #? Stan R.
@shahkalpesh Обратите внимание, чтоInstalled означает что-то более похожее на «включено». Если для свойства Installed установлено значение false, а затем true, «не установить» и «удалить», но просто включает и выключает надстройку. jwg
Не могли бы вы объяснить, почему вам нужно сделать установку / удаление? Я пытаюсь понять, каким образом Excel загружает надстройку, как только вы установите его для загрузки каждый раз. Почему он требует установки / удаления? shahkalpesh

Ваш Ответ

2   ответа
7

Помощь MS: а такжеэтот блог.

Это не вся информация, которая вам нужна. На что следует обратить внимание: у вас должна быть открыта хотя бы одна рабочая книга или все остальное в Excel. Вот некоторый рудиментарный код для начала:

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;
        }
}

Похожие вопросы