Как отправить команду на com.sun.star.frame.DispatchHelper из C # - PullRequest
0 голосов
/ 02 июля 2019

Я использую .NET Framework 3.5 и пытаюсь открыть документ на диске и записать в него текст с помощью DispatchHelper:

internal static void open_office_test(string fn)
{
   object open_office_app = Activator.CreateInstance(Type.GetTypeFromProgID("com.sun.star.ServiceManager"));
   object obj_desktop = open_office_app.GetType().InvokeMember("createInstance",
                                     BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
                                     null, open_office_app, new object[] { "com.sun.star.frame.Desktop" });

   //open file by fn
   object w_doc = obj_desktop.GetType().InvokeMember("loadComponentFromURL",
                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
                               null, obj_desktop, new object[] { new Uri(fn, UriKind.Absolute).AbsoluteUri, "_blank", 0, new object[]{ create_property(obj_desktop, "Hidden", false) } });

   /*get CurrentController.Frame*/
   object w_doc_cc = w_doc.GetType().InvokeMember("CurrentController",
                                  BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
                                  null, w_doc, null);
   object w_doc_frame = w_doc_cc.GetType().InvokeMember("Frame",
                                     BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty,
                                     null, w_doc_cc, null);
   /*****************************/

   /*create dispatcher and send InsertText command*/
   object dispatcher = open_office_app.GetType().InvokeMember("createInstance",
                                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
                                    null, open_office_app, new object[] { "com.sun.star.frame.DispatchHelper" });

   dispatcher.GetType().InvokeMember("executeDispatch",
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
                null, w_doc_frame, new object[] { ".uno:InsertText", "", 0, create_property(obj_desktop, "Text", "aaa") });
   /***********************************************/

}

private static object create_property<T>(object obj_desktop, string name, T value)
{
   object w_prop = obj_desktop.GetType().InvokeMember("Bridge_GetStruct",
                                BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
                                null, obj_desktop, new object[] { "com.sun.star.beans.PropertyValue" });
   Type w_prop_type = w_prop.GetType();
            w_prop_type.InvokeMember("Name",
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty,
                null, w_prop, new object[] { name });
   w_prop_type.InvokeMember("Value",
                BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty,
                null, w_prop, new object[] { value });
   return w_prop;
}

но при выполнении executeDispatch это вызывает

System.Runtime.InteropServices.COMException HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))

P.S. Я могу использовать только отражение


Решение состоит в том, что строка кода

dispatcher.GetType().InvokeMember("executeDispatch",
                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
                    null, w_doc_frame, new object[] { ".uno:InsertText", "", 0, create_property(obj_desktop, "Text", "aaa") });

должно выглядеть как

dispatcher.GetType().InvokeMember("executeDispatch",
                    BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod,
                    null, dispatcher, new object[] { w_doc_frame, ".uno:InsertText", "", 0, new object[] { create_property(obj_desktop, "Text", "aaa") } });
...