[Mono] Компиляция DLL в рантайме
От: Albeoris  
Дата: 01.09.16 10:44
Оценка:
Доброго времени суток!

Есть клиентский процесс (Mono), который динамически подгружает внешнюю библиотеку и порождает экземпляры классов, описанных в ней.
Исходники библиотеки поставляются вместе с ней.
Если дата модификации исходников больше, чем дата модификации DLL, необходимо скомпилировать её заново из этих самых исходников.
Как это правильно сделать?
Насколько актуален System.CodeDom.Compiler?

Нельзя использовать внешние зависимости, которые требуют отдельной установки в систему.
Можно описать процесс компиляции во внешнем приложении .NET Core / .NET Framework и вызывать его из клиентского приложения.
Семейство платформ — Windows 7+.
Совместимость с Linux приветствуется, но строгой необходимости на данный момент нет.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Отредактировано 01.09.2016 10:48 Albeoris . Предыдущая версия . Еще …
Отредактировано 01.09.2016 10:46 Albeoris . Предыдущая версия .
Отредактировано 01.09.2016 10:45 Albeoris . Предыдущая версия .
mono compilation emit cecil il code generation reflection assembly
Re: [Mono] Компиляция DLL в рантайме
От: Sinix  
Дата: 01.09.16 11:04
Оценка: 10 (3)
Здравствуйте, Albeoris, Вы писали:

A>Насколько актуален System.CodeDom.Compiler?

Уже всё.

A>Как это правильно сделать?

Основные кросплатформенные варианты описаны тут.

P.S. рослин в теории работает под mono, но с документацией ой. Надо у них на форумах детали спрашивать. Или сразу на SO, быстрее будет.
Отредактировано 01.09.2016 11:14 Sinix . Предыдущая версия .
Re[2]: [Mono] Компиляция DLL в рантайме
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 01.09.16 12:21
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Albeoris, Вы писали:


A>>Насколько актуален System.CodeDom.Compiler?

S>Уже всё.

A>>Как это правильно сделать?

S>Основные кросплатформенные варианты описаны тут.

Где же ты раньше http://rsdn.org/forum/dotnet/6521650.flat
Автор: Serginio1
Дата: 11.08.16
и солнце б утром не вставало, когда бы не было меня
Re[2]: [Mono] Компиляция DLL в рантайме
От: Venom  
Дата: 01.09.16 12:21
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Форумы Mono

S>http://mono.1490590.n4.nabble.com/

Вот это домен! Уровень -- пятый.
Случайно в адресной строке такое не наберешь!
Re[3]: [Mono] Компиляция DLL в рантайме
От: Sinix  
Дата: 01.09.16 12:47
Оценка: 2 (1) :)
Здравствуйте, Venom, Вы писали:

V>Вот это домен! Уровень -- пятый.

V>Случайно в адресной строке такое не наберешь!

А это вообще не основной способ. Основной у них — привет, девяностые! — мэйллист и irc Пруф.
Re: [Mono] Компиляция DLL в рантайме
От: VladCore  
Дата: 02.09.16 04:54
Оценка:
Здравствуйте, Albeoris, Вы писали:

A>Доброго времени суток!


A>Есть клиентский процесс (Mono), который динамически подгружает внешнюю библиотеку и порождает экземпляры классов, описанных в ней.

A>....
A>Можно описать процесс компиляции во внешнем приложении .NET Core / .NET Framework и вызывать его из клиентского приложения.
A>Семейство платформ — Windows 7+.
A>Совместимость с Linux приветствуется, но строгой необходимости на данный момент нет.

Вопрос про core или mono?

CompilerServices в mono и .net framework никуда не делся

В core всё по другому
Re[2]: [Mono] Компиляция DLL в рантайме
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.09.16 10:42
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Albeoris, Вы писали:


A>>Насколько актуален System.CodeDom.Compiler?

S>Уже всё.

A>>Как это правильно сделать?

S>Основные кросплатформенные варианты описаны тут.

S>P.S. рослин в теории работает под mono, но с документацией ой. Надо у них на форумах детали спрашивать. Или сразу на SO, быстрее будет.

А вот с компиляцией возникли проблемы. Если создаю приложение то все нормально. Но если вызываю через 1С и копирую сборки

Microsoft.CodeAnalysis.dll
Microsoft.CodeAnalysis.CSharp.dll
System.Runtime.Loader.dll

То получаю ошибку

NetObjectToNative : Ошибка в методе DynamicCompile Exception has been thrown by the target of an invocation. System.Private.CoreLib
System.IO.FileLoadException: Could not load file or assembly 'Microsoft.CodeAnalysis, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Microsoft.CodeAnalysis, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
at NetObjectToNative.NetObjectToNative.DynamicCompile().


Если просто загрузить Сборку через

var asm = System.Runtime.Loader.AssemblyLoadContext.GetAssemblyName(path);
var assembly = Assembly.Load(asm);


NetObjectToNative : Ошибка в методе Сборка Exception has been thrown by the target of an invocation. System.Private.CoreLib
System.IO.FileLoadException: Could not load file or assembly 'Microsoft.CodeAnalysis.CSharp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
File name: 'Microsoft.CodeAnalysis.CSharp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'
at System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, RuntimeAssembly reqAssembly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks)
at System.Reflection.Assembly.Load(AssemblyName assemblyRef)
at NetObjectToNative.NetObjectToNative.НайтиСборку(String Каталог, String ИмяФайла) in D:\MyPrograms\VNCOMP83\TestVK\NetObjectToNative\src\NetObjectToNative\NetObjectToNative.cs:line 390
at NetObjectToNative.NetObjectToNative.Сборка(String ИмяФайла, Boolean ГлобальнаяСборка) in D:\MyPrograms\VNCOMP83\TestVK\NetObjectToNative\src\NetObjectToNative\NetObjectToNative.cs:line 490.


Хотя копирую те же сборки, что и в приложении. Может ей xx.deps.json нужен для приложения?
и солнце б утром не вставало, когда бы не было меня
Отредактировано 02.09.2016 10:55 Serginio1 . Предыдущая версия .
Re[3]: [Mono] Компиляция DLL в рантайме
От: Sinix  
Дата: 02.09.16 12:21
Оценка: 4 (2)
Здравствуйте, Serginio1, Вы писали:

S> Хотя копирую те же сборки, что и в приложении. Может ей xx.deps.json нужен для приложения?


И в сотый раз — я не занимаюсь сейчас нативом, хостингом CLR и уж тем более не работаю с 1с
Так что все мои советы сводятся к погуглить в основном.

Начать можно с следующего:
1. Смотрим
http://www.fancy-development.net/hosting-net-core-clr-in-your-own-process

The values we have to provide are the
◾"APPBASE" — Base path of the application, think of it as the execution directory of the application
◾"TRUSTED_PLATFORM_ASSEMBLIES" — A list of paths to assembly files which will be fully trusted by the runtime. Here we have to list all assemblies which have unsafe .NET Code blocks or use PInvode for interop because those assemblies are only executed if they are fully trusted. Separate the file paths with a semicolon. The file paths need to be absolute.
◾"APP_PATHS" — The paths where the Core Clr looks for referenced assemblies to load. Separate the file paths with a semicolon. The file paths need to be absolute.

Если не оно:

2. Проверяем актуальную реализацию вот тут

3. Читаем документацию, где нет — спрашиваем вот тут.
Re[4]: [Mono] Компиляция DLL в рантайме
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.09.16 13:19
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>> Хотя копирую те же сборки, что и в приложении. Может ей xx.deps.json нужен для приложения?


S>И в сотый раз — я не занимаюсь сейчас нативом, хостингом CLR и уж тем более не работаю с 1с

Ну вместо 1С может быть любой натив.
S>Так что все мои советы сводятся к погуглить в основном.

S>Начать можно с следующего:

S>1. Смотрим
S>http://www.fancy-development.net/hosting-net-core-clr-in-your-own-process
S>

S>The values we have to provide are the
S>◾"APPBASE" — Base path of the application, think of it as the execution directory of the application
S>◾"TRUSTED_PLATFORM_ASSEMBLIES" — A list of paths to assembly files which will be fully trusted by the runtime. Here we have to list all assemblies which have unsafe .NET Code blocks or use PInvode for interop because those assemblies are only executed if they are fully trusted. Separate the file paths with a semicolon. The file paths need to be absolute.
S>◾"APP_PATHS" — The paths where the Core Clr looks for referenced assemblies to load. Separate the file paths with a semicolon. The file paths need to be absolute.

S>Если не оно:

S>2. Проверяем актуальную реализацию вот тут


S>3. Читаем документацию, где нет — спрашиваем вот тут.


Взял подправил пути на скомпилированную сборку через
dotnet publish -c release -r win10-x64
или
dotnet publish -f netcoreapp1.0 -c release

И натравил пути к bin\Release\netcoreapp1.0\win10-x86\publish\

и в эту директиорию обавил свои сборки то все работант
и солнце б утром не вставало, когда бы не было меня
Re[4]: [Mono] Компиляция DLL в рантайме
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.09.16 13:33
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, Serginio1, Вы писали:


S>> Хотя копирую те же сборки, что и в приложении. Может ей xx.deps.json нужен для приложения?


S>И в сотый раз — я не занимаюсь сейчас нативом, хостингом CLR и уж тем более не работаю с 1с

S>Так что все мои советы сводятся к погуглить в основном.

S>Начать можно с следующего:

S>1. Смотрим
S>http://www.fancy-development.net/hosting-net-core-clr-in-your-own-process
S>

S>The values we have to provide are the
S>◾"APPBASE" — Base path of the application, think of it as the execution directory of the application
S>◾"TRUSTED_PLATFORM_ASSEMBLIES" — A list of paths to assembly files which will be fully trusted by the runtime. Here we have to list all assemblies which have unsafe .NET Code blocks or use PInvode for interop because those assemblies are only executed if they are fully trusted. Separate the file paths with a semicolon. The file paths need to be absolute.
S>◾"APP_PATHS" — The paths where the Core Clr looks for referenced assemblies to load. Separate the file paths with a semicolon. The file paths need to be absolute.

S>Если не оно:

S>2. Проверяем актуальную реализацию вот тут


S>3. Читаем документацию, где нет — спрашиваем вот тут.


Еще раз огромное спасибо!
Проблема оказалось в том, что в основной директории с CoreClr был Microsoft.CodeAnalysis.dll но версии 1.3 поэтому и ругался. Заменил все нормально.
Но пока он бетта надеюсь пока пишу статьи все встанет на свои места.
и солнце б утром не вставало, когда бы не было меня
Re[4]: [Mono] Компиляция DLL в рантайме
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 02.09.16 14:48
Оценка:
Здравствуйте, Sinix, Вы писали:

Кстати работает в .Net Core и Scripting API

public static void TestRoslynScript()
        {
            object result = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync("1 + 2").Result;
            Console.WriteLine(result.ToString());
            Console.ReadLine();

        }
и солнце б утром не вставало, когда бы не было меня
Re[5]: Ошибка Компиляция Scripting API
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 05.09.16 08:25
Оценка: :)
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, Sinix, Вы писали:


S>Кстати работает в .Net Core и Scripting API


S>
S>public static void TestRoslynScript()
S>        {
S>            object result = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync("1 + 2").Result;
S>            Console.WriteLine(result.ToString());
S>            Console.ReadLine();

S>        }
S>


И более сложные работают

 static  String ПолучитьСтрокуДелегата()
        {
            string returnStr = @"return (MatchEvaluator)((match) =>
            {
              string x = match.Value;
            // If the first char is lower case...
        if (char.IsLower(x[0]))
        {
            // Capitalize it.
            return char.ToUpper(x[0]) + x.Substring(1, x.Length - 1);
        }
        return x;

            });";

            return returnStr;

        }


        static MatchEvaluator ПолучитьДелегат()
        {
            return (MatchEvaluator)((match) =>
               {
                   string x = match.Value;
                   // If the first char is lower case...
                   if (char.IsLower(x[0]))
                   {
                       // Capitalize it.
                       return char.ToUpper(x[0]) + x.Substring(1, x.Length - 1);
                   }
                   return x;


               });
               }
        public static void ТестRegex()
        {
           
             string words = "надо заменить все первые буквы в словах на заглавные";
            string pattern = @"\w+";

            
            var scr = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default;

// Добавил ссылку на mscrlib 
 var scr = Microsoft.CodeAnalysis.Scripting.ScriptOptions.Default;
            var mscrlib = Assembly.Load(System.Runtime.Loader.AssemblyLoadContext.GetAssemblyName(@"c:\Users\Smirnov_SA\.nuget\packages\Microsoft.NETCore.Portable.Compatibility\1.0.1\ref\netcore50\mscorlib.dll"));
            scr =scr.WithReferences(mscrlib,typeof(MulticastDelegate).GetTypeInfo().Assembly, typeof(System.Runtime.CompilerServices.IStrongBox).GetTypeInfo().Assembly, typeof(MatchEvaluator).GetTypeInfo().Assembly);
            


            scr = scr.WithImports("System", "System.Text.RegularExpressions");

                   

              var result = Microsoft.CodeAnalysis.CSharp.Scripting.CSharpScript.EvaluateAsync(ПолучитьСтрокуДелегата(), scr).Result;
              MatchEvaluator evaluator = (MatchEvaluator)result;
           // MatchEvaluator evaluator = ПолучитьДелегат();
             Console.WriteLine(Regex.Replace(words, pattern, evaluator));        }


Все работает

То есть кромеосновной сборки нужно еще добавить ссылки на

mscorlib.dll
System.Private.CoreLib.ni.dll
System.Runtime.dll
и солнце б утром не вставало, когда бы не было меня
Отредактировано 05.09.2016 11:32 Serginio1 . Предыдущая версия . Еще …
Отредактировано 05.09.2016 11:20 Serginio1 . Предыдущая версия .
Отредактировано 05.09.2016 11:19 Serginio1 . Предыдущая версия .
Отредактировано 05.09.2016 10:05 Serginio1 . Предыдущая версия .
Отредактировано 05.09.2016 9:14 Serginio1 . Предыдущая версия .
Отредактировано 05.09.2016 9:07 Serginio1 . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.