Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вызов внешней сборки в коде C# / 20 сообщений из 20, страница 1 из 1
21.09.2012, 15:54
    #37967565
Derbaser
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Приветствую всех.

Есть приложение, в котором для основных манипуляций нужно произвести конвертацию doc/docx в html.
Для конвертации используется либа Converter.dll написанная ранее коллегами.
Эта либа определяет какой файл ей пришел - doc или docx, если doc, то сама конвертирует, для docx вызывается другая либа ConverterDocx.dll.

В своем приложении я использую следующий код:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
var assembly = Assembly.LoadFrom(_reg.InstallPath +
                                            "Program\\Converter.dll");
var typeConverter = assembly.GetType("ConverterLib.Converter");
var converter = Activator.CreateInstance(typeConverter);
var convertToHtml = typeConverter.GetMethod("ConvertToHtml");
var getResult = typeConverter.GetMethod("GetResult");
var dispose = typeConverter.GetMethod("Dispose");
convertToHtml.Invoke(converter, new object[] { strPath }); // Выполняю конвертацию, strPath - путь к doc/docx файлу
strHtml = (string)getResult.Invoke(converter, null); // Получаю результат в виде html текста
dispose.Invoke(converter, null);



Если на вход поступает doc, то все отрабатывает отлично, если docx, то выдается исключение:

Ошибка при инициализации COM: Изменение режима для потока после его установки невозможно.

У меня подозрение, что это оттого, что вызывается еще либа ConverterDocx.dll при подаче на вход docx. Из-за этих подозрений я решил подключать вторую либу аналогичным способом, чтобы не вызывать ее из первой, но столкнулся с проблемой.
Как видно из кода метод конвертации в либе Converter.dll имеет вид void ConvertToHtml(string filePath), то есть с его вызовом и передачей параметра через new object[] у меня проблем не возникло.
А вот в либе ConverterDocx.dll метод Convert имеет вид bool Convert(string filePath, out string htmlText).

Собственно сам вопрос:
Как мне воспользоваться методом в моем случае или (более глобально) как избавиться от ошибки?

Заранее благодарю.
...
Рейтинг: 0 / 0
21.09.2012, 16:09
    #37967594
pation
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
DerbaserПриветствую всех.

Есть приложение, в котором для основных манипуляций нужно произвести конвертацию doc/docx в html.
Для конвертации используется либа Converter.dll написанная ранее коллегами.
Эта либа определяет какой файл ей пришел - doc или docx, если doc, то сама конвертирует, для docx вызывается другая либа ConverterDocx.dll.

В своем приложении я использую следующий код:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
var assembly = Assembly.LoadFrom(_reg.InstallPath +
                                            "Program\\Converter.dll");
var typeConverter = assembly.GetType("ConverterLib.Converter");
var converter = Activator.CreateInstance(typeConverter);
var convertToHtml = typeConverter.GetMethod("ConvertToHtml");
var getResult = typeConverter.GetMethod("GetResult");
var dispose = typeConverter.GetMethod("Dispose");
convertToHtml.Invoke(converter, new object[] { strPath }); // Выполняю конвертацию, strPath - путь к doc/docx файлу
strHtml = (string)getResult.Invoke(converter, null); // Получаю результат в виде html текста
dispose.Invoke(converter, null);




Если на вход поступает doc, то все отрабатывает отлично, если docx, то выдается исключение:

Ошибка при инициализации COM: Изменение режима для потока после его установки невозможно.

У меня подозрение, что это оттого, что вызывается еще либа ConverterDocx.dll при подаче на вход docx. Из-за этих подозрений я решил подключать вторую либу аналогичным способом, чтобы не вызывать ее из первой, но столкнулся с проблемой.
Как видно из кода метод конвертации в либе Converter.dll имеет вид void ConvertToHtml(string filePath), то есть с его вызовом и передачей параметра через new object[] у меня проблем не возникло.
А вот в либе ConverterDocx.dll метод Convert имеет вид bool Convert(string filePath, out string htmlText).

Собственно сам вопрос:
Как мне воспользоваться методом в моем случае или (более глобально) как избавиться от ошибки?

Заранее благодарю.

а зачем ты делаешь позднее связывание, не проще ли добавить референс?
...
Рейтинг: 0 / 0
21.09.2012, 16:15
    #37967622
beg-in-er
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
convertToHtml.Invoke(converter, new object[] { strPath });
попробуй так.
Код: c#
1.
2.
3.
4.
//bool Convert(string filePath, out string htmlText).
object[] obj= new object[] { strPath,""};
convertToHtml.Invoke(converter, obj);
string htmlText=obj[1].ToString();



если можешь ту сборку разобрать, разбери , и сделай string вместо bool
...
Рейтинг: 0 / 0
21.09.2012, 17:17
    #37967729
Derbaser
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Ни референс добавить, ни, тем более, разобрать не могу, есть причины.
Beg-in-er, спасибо, попробую твой способ в пн, отпишу.
...
Рейтинг: 0 / 0
21.09.2012, 19:26
    #37967879
skole
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Эти либы ведь вызывают word.exe, им же прочитать содержимое файла надо перед конвертацией, смотри диспетчер задач, увидишь. Файлы *.doc можно открыть, а *.docx нельзя, смотри установленную версию офиса. Обрати внимание на ошибку - word.exe не понимает расширения *.docx, следовательно не может запуститься.
...
Рейтинг: 0 / 0
21.09.2012, 21:20
    #37967953
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
DerbaserНи референс добавить, ни, тем более, разобрать не могу, есть причины
Озвучить причины не позволяет религия?
...
Рейтинг: 0 / 0
22.09.2012, 00:14
    #37968051
Derbaser
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Долго и бессмысленно рассказывать о причинах, сказали так, значит надо выкручиваться на данном этапе.
Word.exe не используется, либы конвертации написаны с использованием OpenOffice библиотек.
...
Рейтинг: 0 / 0
22.09.2012, 03:34
    #37968091
skole
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Derbaser, надеюсь мысль понятна, не надо искать причину там где ее нет, сходи по цепочке, если либы поднимают COM и он валится на инициализации, ну, значит найти этот компонент и протестировать его на кошках. Кстати, хороший вопрос, он у тебя зарегистрирован? COM компоненту на запуск нужны права, проверяй.
...
Рейтинг: 0 / 0
22.09.2012, 10:30
    #37968150
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
...
Рейтинг: 0 / 0
24.09.2012, 09:31
    #37969353
Derbaser
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
beg-in-er,

спасибо, сработало!
...
Рейтинг: 0 / 0
18.04.2013, 13:54
    #38230857
olb
olb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
подключаю произвольную dll
исходный код dll
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MyDll
{
    public class ResultRec
    {
        int line;
        string message;
        public ResultRec(int line, string message)
        {
            this.line = line;
            this.message = message;
        }
    }

    public class MyDllClass
    {
        public IEnumerable<ResultRec> MyDllMethod(int count)
        {
            List<ResultRec> rr = new List<ResultRec>();
            for (int i = 0; i < count; i++)
            {
                rr.Add(new ResultRec(i, string.Format("строка {0}", i)));
            }
            return rr;
        }
    }

}



код, где используется dll

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;


namespace MyExe
{

    public class Program
    {
        public static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFile(@"C:\ClassLibrary1.dll");
            Type ResultRec = assembly.GetType("MyDll.ResultRec");
            Type MyDllClass = assembly.GetType("MyDll.MyDllClass");
            Object obj = assembly.CreateInstance("MyDll.MyDllClass");
            MethodInfo method = MyDllClass.GetMethod("MyDllMethod");

            Object ret = method.Invoke(obj, new Object[] {3});

            Console.WriteLine(ret);
            Console.ReadLine();

        }
    }
}


данный код работает, но как мне теперь добраться до элементов коллекции, которую возвращает метод из dll ?
...
Рейтинг: 0 / 0
18.04.2013, 14:34
    #38230930
cooldeveloper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Код: c#
1.
2.
3.
4.
5.
6.
var ret = method.Invoke(obj, new Object[] {3}) as IEnumerable;
foreach (var item in ret)
{
    int line = (int)item.GetType().GetField("line", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(item);
    string message = (string)item.GetType().GetField("message", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(item);
}
...
Рейтинг: 0 / 0
18.04.2013, 15:54
    #38231097
olb
olb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Код: c#
1.
var ret = method.Invoke(obj, new Object[] { 3 }) as IEnumerable;


не компилируется, Using the generic type 'System.Collections.Generic.IEnumerable<T>' requires '1' type arguments
Код: c#
1.
var ret = method.Invoke(obj, new Object[] { 3 }) as IEnumerable<Object>;


так компилируется, но ret получается равным null и все что ниже не работает
...
Рейтинг: 0 / 0
18.04.2013, 16:03
    #38231114
Lelouch
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
olb,

добавьте using System.Collections
...
Рейтинг: 0 / 0
18.04.2013, 16:22
    #38231184
cooldeveloper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
olb
Код: c#
1.
var ret = method.Invoke(obj, new Object[] { 3 }) as IEnumerable<Object>;


так компилируется, но ret получается равным null и все что ниже не работает

В FW > 4.0 это будет работать, т.к. поддерживается ковариантность и контравариантность в обобщениях. По поводу просто IEnumerable ответ уже дали.
...
Рейтинг: 0 / 0
18.04.2013, 16:23
    #38231190
cooldeveloper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
cooldeveloperFW => 4.0
...
Рейтинг: 0 / 0
19.04.2013, 11:22
    #38232267
olb
olb
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
этот вариант работает.
А если в качестве пареметра необходимо передать коллекцию типов, описанных во внешней сборке
Dll
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MyDll
{
    public class InfoRec
    {
        public int info1;
        public string info2;
        public InfoRec(int info1, string info2)
        {
            this.info1 = info1;
            this.info2 = info2;
        }
    }
    public class MyDllClass
    {
        public void MyDllMethod(List<InfoRec> info)
        {
            info.Add(new InfoRec(1,"инфо1"));
            info.Add(new InfoRec(2,"инфо2"));
        }
    }
}



вызов
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;

namespace MyExe
{
    public class Program
    {
        public static void Main(string[] args)
        {
            Assembly assembly = Assembly.LoadFile(@"C:\ClassLibrary1.dll");
            Type InfoRec = assembly.GetType("MyDll.InfoRec");
            Type MyDllClass = assembly.GetType("MyDll.MyDllClass");
            Object obj = assembly.CreateInstance("MyDll.MyDllClass");
            MethodInfo method = MyDllClass.GetMethod("MyDllMethod");
            List<Object> info = new List<Object>() ;
            method.Invoke(obj, new Object[] {info});
            Console.ReadLine();
        }
    }
}


при вызове происходит исключение Невозможно преобразовать объект типа "System.Collections.Generic.List`1[System.Object]" к типу "System.Collections.Generic.List`1[MyDll.InfoRec]"
Как описать этот параметр?
...
Рейтинг: 0 / 0
19.04.2013, 11:27
    #38232280
cooldeveloper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
Передавай как IEnumerable, а на стороне сборке получай элемент и намапливай на экземпляр нужного типа.
...
Рейтинг: 0 / 0
19.04.2013, 13:16
    #38232562
cooldeveloper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
cooldeveloperПередавай как IEnumerable, а на стороне сборке получай элемент и намапливай на экземпляр нужного типа.
Хотя, если уж очень хочется общаться с типизированным объектом, то делай так:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
var assembly = Assembly.LoadFile(path);
var rec = assembly.GetType("MyDLL.InfoRec");
var cls = assembly.GetType("MyDLL.MyDllClass");
var method = cls.GetMethod("MyDllMethod");

var obj = Activator.CreateInstance(cls);

var list = Activator.CreateInstance(typeof(List<>).MakeGenericType(rec)) as IList;
list.Add(Activator.CreateInstance(rec, 1, "data 1"));
list.Add(Activator.CreateInstance(rec, 2, "data 2"));
list.Add(Activator.CreateInstance(rec, 3, "data 3"));

method.Invoke(obj, new[] { list });
...
Рейтинг: 0 / 0
19.04.2013, 13:56
    #38232661
cooldeveloper
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Вызов внешней сборки в коде C#
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Вызов внешней сборки в коде C# / 20 сообщений из 20, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]