Есть одна графическая программа на .net. Очень бы хотелось ей немного поменять интерфейс.
Можно ли это сделать имея только скомпилированный бинарник этой программы? Поменять там надо совсем чутьчуть. Если проводить аналогии с Java, то все что мне нужно – это открыть jar архив программы, получить оттуда пару классов, превратить их в Java файлы декомпилятором, поменять там то что нужно, скомпилить, запаковать в архив и пользоваться.
Какие есть тулзы которые позволят решить эту задачу? Декомпилировать вс. программу, а потом ее собирать назад очень проблематично, так как декомпилятор все таки делает ошибки, а править их по паре десятков тысяч строк кода очень проблематично.
Можно ли этот бинарник использовать как библиотеку для другого проекта на .net? то есть слинковать классы и файлы оттуда в другой проект?
Вопрос хакерский, но мало ли кто что подскажет.
Заранее спасибо!
Борис
22 августа 2008 в 23:00
Александр!
Огромное спасибо! Ваши комментарии оказались крайне к месту!
Просто с аналогом reflections для C# не работал еще.
22 августа 2008 в 17:00
Бл*, запарился. Последняя строка кода должна иметь вид:
double val = (double)mi[2].Invoke(reflectOb, args);
В последней строке кода вызываем третий метод (случайно написал вызов четвертого).
22 августа 2008 в 16:04
Пример на C#:
//Загружаем компоновочный файл File.exe
Assembly asm = Assembly.LoadFrom("File.exe");
//Узнаем какие типы содержит файл File.exe
Type[] alltypes = asm.GetTypes();
//Используем первый из полученных типов (предположим класс A)
Type t = alltypes[0];
//Получаем список конструкторов класса A
ConstructorInfo[] ci = t.GetConstructors();
//Получаем список параметров для первого конструктора
ParameterInfo[] pi = ci[0].GetParameters();
//Предположим, первый конструктор принимает два параметра типа int
//Создаем объект класса A
object[] consargs = new object[2];
consargs[0] = 10;
consargs[1] = 25;
object reflectOb = ci[0].Invoke(consargs);
//Получаем список методов класса A (предположим, в классе определено
//пять методов)
MethodInfo[] mi = t.GetMethods();
//Получам список параметров, скажем, для третьего метода,
//определенного в классе A
ParameterInfo[] mpi = mi[2].GetParameters();
//Для простоты предположим, что метод принимат три параметра типа
//double и возвращат значение типа double
//Вызывам третий метод объекта класса A
object[] args = new object[3];
args[0] = 0.5;
args[1] = 3.8;
args[2] = -9.7;
double val = (double)mi[3].Invoke(reflectOb, args);
Вообще, используя свойства, методы упомянутых выше классов, можно узнать практически любую информацию о типах (кроме программной реализации), упоминающихся в *.exe, *.dll.
В книге Г. Шилдта "Полный справочник по C#" можно найти более подробное описание.
22 августа 2008 в 16:03
Спасибо, Евгений!
Сейчас попробуем!
22 августа 2008 в 16:01
"Add assembly reference"
22 августа 2008 в 15:03
В том то и дело, что мне менять не нужно – мне просто нужно использовать пару классов, которые есть в этой программе.
Меня чисто технический момент интересует – как можно использовать? В частности в Visual Studio?
22 августа 2008 в 9:04
Напишите авторам запрос, я думаю, они его рассмотрят. (Я так делал несколько раз, авторы^Wпрограммисты — народ чуткий, внимание к своему проекту их интересует )
Если проект с открытым исходным кодом, то все очень упрощается.
22 августа 2008 в 8:02
Lutz Reflector декомпилирует очень хорошо, по-моему.
Касаемо того чтобы использовать в качестве библиотеки – конечно, можно, никаких проблем – но изменить таким образом поведение какого-то библиотечного класса не получится.
Можно от него унаследоваться, может прокатить, но может и не прокатить, если многие другие библиотечные классы завязаны на него.