& Ldquo; Инъекционное & Rdquo; Данные MySQL в приложение [дубликат]

Вопрос был:

Как вернуть ответ от асинхронного вызова?

, который может быть интерпретирован как:

Как сделать синхронный асинхронный код синхронным?

Решение будет состоять в том, чтобы избежать обратных вызовов и использовать комбинацию Promises и async / await.

Я хотел бы привести пример для запроса Ajax.

(Хотя он может быть записан в Javascript, я предпочитаю писать его на Python и компилировать его в Javascript, используя Transcrypt . Это будет достаточно ясно.)

Позволяет сначала включить использование JQuery, чтобы $ был доступен как S:

__pragma__ ('alias', 'S', '$')

Определить функцию, которая возвращает Promise, в этом случае вызов Ajax:

def read(url: str):
    deferred = S.Deferred()
    S.ajax({'type': "POST", 'url': url, 'data': { },
        'success': lambda d: deferred.resolve(d),
        'error': lambda e: deferred.reject(e)
    })
    return deferred.promise()

Использовать асинхронный код, как если бы он был синхронным:

async def readALot():
    try:
        result1 = await read("url_1")
        result2 = await read("url_2")
    except Exception:
        console.warn("Reading a lot failed")

480
задан Matthias 11 July 2014 в 14:16
поделиться

19 ответов

Я настоятельно рекомендую использовать Costura.Fody - безусловно лучший и самый простой способ встраивания ресурсов в вашу сборку. Он доступен как пакет NuGet.

Install-Package Costura.Fody

После добавления его в проект он автоматически вставляет все ссылки, скопированные в выходной каталог, в вашу главную сборку . Возможно, вы захотите очистить встроенные файлы, добавив цель в свой проект:

Install-CleanReferencesTarget

Вы также сможете указать, включать ли pdb, исключать определенные сборки или извлекать сборки на летать. Насколько мне известно, поддерживаются также неуправляемые сборки.

Обновление

В настоящее время некоторые люди пытаются добавить поддержку для DNX .

617
ответ дан Matthias 24 August 2018 в 20:24
поделиться

Ни подход ILMerge, ни Lars Holm Jensen, обрабатывающий событие AssemblyResolve, не будут работать для хоста плагина. Скажем, исполняемый файл H динамически загружает сборку P и обращается к ней через интерфейс IP , определенный в отдельной сборке. Чтобы вставить IP в H , потребуется небольшая модификация кода Ларса:

Dictionary<string, Assembly> loaded = new Dictionary<string,Assembly>();
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{   Assembly resAssembly;
    string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");
    dllName = dllName.Replace(".", "_");
    if ( !loaded.ContainsKey( dllName ) )
    {   if (dllName.EndsWith("_resources")) return null;
        System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
        byte[] bytes = (byte[])rm.GetObject(dllName);
        resAssembly = System.Reflection.Assembly.Load(bytes);
        loaded.Add(dllName, resAssembly);
    }
    else
    {   resAssembly = loaded[dllName];  }
    return resAssembly;
};  

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

РЕДАКТИРОВАТЬ: чтобы он не испортил сериализацию .NET, обязательно верните значение null для всех сборок, не встроенных в ваш, тем самым не соблюдая стандартное поведение. Вы можете получить список этих библиотек:

static HashSet<string> IncludedAssemblies = new HashSet<string>();
string[] resources = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames();
for(int i = 0; i < resources.Length; i++)
{   IncludedAssemblies.Add(resources[i]);  }

и просто вернуть значение null, если переданная сборка не принадлежит IncludedAssemblies.

6
ответ дан Ant_222 24 August 2018 в 20:24
поделиться

Да, возможно объединить исполняемые файлы .NET с библиотеками. Для выполнения этой задачи доступны несколько инструментов:

  • ILMerge - это утилита, которая может использоваться для объединения нескольких сборок .NET в одну сборку.
  • Mono mkbundle , упаковывает exe и все сборки с libmono в один бинарный пакет.
  • IL-Repack является альтернативой FLOSS для ILMerge, с некоторыми дополнительными функциями.

Кроме того, это можно объединить с Mono Linker , который удаляет неиспользуемый код и, следовательно, уменьшает итоговую компоновку

Другая возможность заключается в использовании .NETZ , который не только позволяет сжимать сборку, но также может упаковывать DLL прямо в exe. Разница с вышеупомянутыми решениями заключается в том, что .NETZ не объединяет их, они остаются отдельными сборками, но упаковываются в один пакет.

.NETZ - это инструмент с открытым исходным кодом, который сжимает и упаковывает Microsoft Исполняемые файлы .NET Framework (EXE, DLL), чтобы сделать их меньше.

24
ответ дан Bobby 24 August 2018 в 20:24
поделиться

Я опробовал это решение в коде-проекте, в который встроена DLL: http://www.codeproject.com/Articles/528178/Load-DLL-From-Embedded-Resource

И все получилось отлично.

0
ответ дан Chagbert 24 August 2018 в 20:24
поделиться

Возможно, но не все так просто, создать гибридную сборку / управляемую сборку в C #. Если бы вы использовали C ++, это было бы намного проще, так как компилятор Visual C ++ может создавать гибридные сборки так же легко, как и все остальное.

Если у вас нет строгого требования о создании гибридной сборки, я бы согласитесь с MusiGenesis, что это не стоит того, чтобы делать с C #. Если вам нужно это сделать, возможно, посмотрите на переход на C ++ / CLI.

0
ответ дан Chris Charabaruk 24 August 2018 в 20:24
поделиться

Чтобы увеличить @ Bobby's asnwer выше. Вы можете отредактировать свой .csproj, чтобы использовать IL-Repack , чтобы автоматически упаковывать все файлы в одну сборку при сборке.

  1. Установить пакет ILRepack.MSBuild.Task nuget с Install-Package ILRepack.MSBuild.Task
  2. Отредактируйте секцию AfterBuild вашего .csproj

Вот простой пример, который объединяет ExampleAssemblyToMerge.dll в ваш проект.

<!-- ILRepack -->
<Target Name="AfterBuild" Condition="'$(Configuration)' == 'Release'">

   <ItemGroup>
    <InputAssemblies Include="$(OutputPath)\$(AssemblyName).exe" />
    <InputAssemblies Include="$(OutputPath)\ExampleAssemblyToMerge.dll" />
   </ItemGroup>

   <ILRepack 
    Parallel="true"
    Internalize="true"
    InputAssemblies="@(InputAssemblies)"
    TargetKind="Exe"
    OutputFile="$(OutputPath)\$(AssemblyName).exe"
   />
</Target>
16
ответ дан Community 24 August 2018 в 20:24
поделиться

Это может показаться упрощенным, но WinRar предоставляет возможность сжимать кучу файлов в самораспаковывающийся исполняемый файл. Он имеет множество настраиваемых параметров: финальный значок, извлечение файлов в заданный путь, файл для выполнения после извлечения, пользовательский логотип / тексты для всплывающего окна, отображаемого во время извлечения, всплывающее окно вообще, текст лицензионного соглашения и т. Д. Может быть полезным в некоторых случаях .

2
ответ дан Ivan Ferrer Villa 24 August 2018 в 20:24
поделиться

Просто щелкните свой проект правой кнопкой мыши в Visual Studio, выберите «Свойства проекта» -> «Ресурсы» -> «Добавить ресурс» - «Добавить существующий файл»). И добавьте код ниже в ваш App.xaml.cs или его эквивалент.

public App()
{
    AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    string dllName = args.Name.Contains(',') ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll","");

    dllName = dllName.Replace(".", "_");

    if (dllName.EndsWith("_resources")) return null;

    System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());

    byte[] bytes = (byte[])rm.GetObject(dllName);

    return System.Reflection.Assembly.Load(bytes);
}

Вот мой оригинальный пост в блоге: http://codeblog.larsholm.net/2011/06/embed-dlls-easily-in-a-net-assembly/

72
ответ дан M. Wiśnicki 24 August 2018 в 20:24
поделиться

Я использую компилятор csc.exe, вызванный из сценария .vbs.

В вашем скрипте xyz.cs добавьте следующие строки после директив (мой пример для SSH Renci):

using System;
using Renci;//FOR THE SSH
using System.Net;//FOR THE ADDRESS TRANSLATION
using System.Reflection;//FOR THE Assembly

//+ref>"C:\Program Files (x86)\Microsoft\ILMerge\Renci.SshNet.dll"
//+res>"C:\Program Files (x86)\Microsoft\ILMerge\Renci.SshNet.dll"
//+ico>"C:\Program Files (x86)\Microsoft CAPICOM 2.1.0.2 SDK\Samples\c_sharp\xmldsig\resources\Traffic.ico"

Теги ref, res и ico будут подхвачены скриптом .vbs ниже, чтобы сформировать команду csc.

Затем добавьте вызывающего абонента для сборки в Main:

public static void Main(string[] args)
{
    AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
    .

... и добавить сам резольвер где-то в классе:

    static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        String resourceName = new AssemblyName(args.Name).Name + ".dll";

        using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
        {
            Byte[] assemblyData = new Byte[stream.Length];
            stream.Read(assemblyData, 0, assemblyData.Length);
            return Assembly.Load(assemblyData);
        }

    }

Я называю скрипт vbs в соответствии с именем .cs filename (например, ssh.vbs ищет ssh .cs); это делает запуск скрипта несколько раз намного проще, но если вы не идиот, как я, тогда общий сценарий может получить целевой файл .cs из перетаскивания:

    Dim name_,oShell,fso
    Set oShell = CreateObject("Shell.Application")
    Set fso = CreateObject("Scripting.fileSystemObject")

    'TAKE THE VBS SCRIPT NAME AS THE TARGET FILE NAME
    '################################################
    name_ = Split(wscript.ScriptName, ".")(0)

    'GET THE EXTERNAL DLL's AND ICON NAMES FROM THE .CS FILE
    '#######################################################
    Const OPEN_FILE_FOR_READING = 1
    Set objInputFile = fso.OpenTextFile(name_ & ".cs", 1)

    'READ EVERYTHING INTO AN ARRAY
    '#############################
    inputData = Split(objInputFile.ReadAll, vbNewline)

    For each strData In inputData

        if left(strData,7)="//+ref>" then 
            csc_references = csc_references & " /reference:" &         trim(replace(strData,"//+ref>","")) & " "
        end if

        if left(strData,7)="//+res>" then 
            csc_resources = csc_resources & " /resource:" & trim(replace(strData,"//+res>","")) & " "
        end if

        if left(strData,7)="//+ico>" then 
            csc_icon = " /win32icon:" & trim(replace(strData,"//+ico>","")) & " "
        end if
    Next

    objInputFile.Close


    'COMPILE THE FILE
    '################
    oShell.ShellExecute "c:\windows\microsoft.net\framework\v3.5\csc.exe", "/warn:1 /target:exe " & csc_references & csc_resources & csc_icon & " " & name_ & ".cs", "", "runas", 2


    WScript.Quit(0)
1
ответ дан Mark Llewellyn 24 August 2018 в 20:24
поделиться

Вы можете добавить библиотеки DLL в качестве встроенных ресурсов, а затем распаковать их в каталог приложения при запуске (после проверки, есть ли у них там уже).

Файлы настроек настолько просты чтобы, тем не менее, я не думаю, что это того стоило.

EDIT: Этот метод был бы легким в сборках .NET. С не-.NET DLL было бы намного больше работы (вам нужно было бы выяснить, где распаковать файлы и зарегистрировать их и т. Д.).

6
ответ дан MusiGenesis 24 August 2018 в 20:24
поделиться

Другим продуктом, который может с этим справиться, является SmartAssembly, на SmartAssembly.com . Этот продукт в дополнение к объединению всех зависимостей в одну DLL (необязательно) обфускает ваш код, удаляет дополнительные метаданные, чтобы уменьшить результирующий размер файла, а также может фактически оптимизировать IL для повышения производительности во время выполнения. Существует также какая-то глобальная функция обработки / обработки исключений, которая добавляется к вашему программному обеспечению (если это необходимо), что я не нашел времени, чтобы понять, но может быть полезным. Я считаю, что у него также есть API командной строки, поэтому вы можете сделать его частью своего процесса сборки.

5
ответ дан Nathan 24 August 2018 в 20:24
поделиться

Я бы порекомендовал вам проверить утилиту .NETZ, которая также сжимает сборку со схемой по вашему выбору:

http://madebits.com/netz/help.php# одиночный

7
ответ дан Nathan Baulch 24 August 2018 в 20:24
поделиться

ILMerge делает именно то, что вы хотите.

4
ответ дан plinth 24 August 2018 в 20:24
поделиться

Выдержка Джеффри Рихтера очень хороша. Короче говоря, добавьте библиотеку в качестве встроенных ресурсов и добавьте обратный вызов перед чем-либо еще. Вот версия кода (найденная в комментариях его страницы), которую я поставил в начале метода Main для консольного приложения (просто убедитесь, что любые вызовы, которые используют библиотеку, находятся в другом методе Main).

AppDomain.CurrentDomain.AssemblyResolve += (sender, bargs) =>
        {
            String dllName = new AssemblyName(bargs.Name).Name + ".dll";
            var assem = Assembly.GetExecutingAssembly();
            String resourceName = assem.GetManifestResourceNames().FirstOrDefault(rn => rn.EndsWith(dllName));
            if (resourceName == null) return null; // Not found, maybe another handler will find it
            using (var stream = assem.GetManifestResourceStream(resourceName))
            {
                Byte[] assemblyData = new Byte[stream.Length];
                stream.Read(assemblyData, 0, assemblyData.Length);
                return Assembly.Load(assemblyData);
            }
        };
11
ответ дан Steve 24 August 2018 в 20:24
поделиться

Если они действительно управляются сбоями, вы можете использовать ILMerge . Для родных DLL-файлов вам потребуется немного больше работы.

См. также: Как можно слить dll C ++ в приложение C # exe?

74
ответ дан Technoguyfication 24 August 2018 в 20:24
поделиться

Кроме ILMerge , если вы не хотите беспокоиться о переключении командной строки, я действительно рекомендую ILMerge-Gui . Это проект с открытым исходным кодом, очень хороший!

3
ответ дан tyron 24 August 2018 в 20:24
поделиться

Проверить boxedapp

Он может встраивать dll в любое приложение. Написано также на C #:)

Надеюсь, что это поможет.

6
ответ дан user 24 August 2018 в 20:24
поделиться

Как правило, для выполнения слияния сборки, как вы описываете, вам понадобится форма сборки post build. Существует бесплатный инструмент Eazfuscator (eazfuscator.blogspot.com/), который предназначен для обработки байт-кода, который также обрабатывает слияние сборки. Вы можете добавить это в командную строку post build с помощью Visual Studio для объединения ваших сборок, но ваш пробег будет зависеть от проблем, возникающих в любых сценариях слияния неконкурентов.

Вы также можете проверить, чтобы увидеть если сборка делает невозможным, NANT имеет возможность объединять сборки после сборки, но я не достаточно знаком с самим NANT, чтобы сказать, встроена ли функция или нет.

Существует также много плагинов Visual Studio который будет выполнять слияние сборки как часть создания приложения.

Альтернативно, если вам не нужно, чтобы это было сделано автоматически, существует ряд инструментов, таких как ILMerge, которые будут объединять сборки .net в один файл .

Самая большая проблема, с которой я столкнулась при объединении сборок, - это использование каких-либо похожих пространств имен. Или, что еще хуже, ссылаться на разные версии одной и той же DLL (мои проблемы обычно были с файлами DLL NUnit).

0
ответ дан wllmsaccnt 24 August 2018 в 20:24
поделиться

ILMerge может комбинировать сборки с одной сборкой, если сборка имеет только управляемый код. Вы можете использовать приложение командной строки или добавить ссылку на exe и программно объединить. Для версии GUI существует Eazfuscator , а также .Netz , оба из которых являются свободными. Платные приложения включают BoxedApp и SmartAssembly .

Если вам нужно объединить сборки с неуправляемым кодом, я бы предложил SmartAssembly . У меня никогда не было икоты с SmartAssembly , но со всеми остальными. Здесь он может встраивать необходимые зависимости в качестве ресурсов в ваш основной exe.

Вы можете все это вручную не беспокоиться, если сборка управляется или в смешанном режиме, встраивая DLL в ваши ресурсы, а затем полагаясь на Сборка AppDomain ResolveHandler. Это одностановленное решение, приняв наихудший случай, т. Е. Сборки с неуправляемым кодом.

static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
    {
        string assemblyName = new AssemblyName(args.Name).Name;
        if (assemblyName.EndsWith(".resources"))
            return null;

        string dllName = assemblyName + ".dll";
        string dllFullPath = Path.Combine(GetMyApplicationSpecificPath(), dllName);

        using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
        {
            byte[] data = new byte[stream.Length];
            s.Read(data, 0, data.Length);

            //or just byte[] data = new BinaryReader(s).ReadBytes((int)s.Length);

            File.WriteAllBytes(dllFullPath, data);
        }

        return Assembly.LoadFrom(dllFullPath);
    };
}

Ключевым здесь является запись байтов в файл и загрузка из его местоположения. Чтобы избежать проблемы с курицей и яйцом, вы должны убедиться, что вы объявляете обработчик перед доступом к сборке и что вы не получаете доступа к членам сборки (или создаете экземпляр всего, что связано с сборкой) внутри части загрузки (сборки). Также будьте осторожны, чтобы гарантировать, что GetMyApplicationSpecificPath() не является временным каталогом, поскольку временные файлы могут быть удалены другими программами или самим собой (а не то, что он будет удален, пока ваша программа обратится к DLL, но, по крайней мере, это неприятность. AppData - хорошее место). Также обратите внимание, что каждый раз вы должны писать байты, вы не можете загружать из местоположения только «потому что dll уже там существует».

Для управляемых dll вам не нужно писать байты, а непосредственно загружать из местоположения dll или просто прочитать байты и загрузить сборку из памяти. Например:

    using (Stream s = Assembly.GetEntryAssembly().GetManifestResourceStream(typeof(Program).Namespace + ".Resources." + dllName))
    {
        byte[] data = new byte[stream.Length];
        s.Read(data, 0, data.Length);
        return Assembly.Load(data);
    }

    //or just

    return Assembly.LoadFrom(dllFullPath); //if location is known.

Если сборка полностью неуправляема, вы можете увидеть эту ссылку или эту относительно того, как загрузить такие DLL .

16
ответ дан Community 24 August 2018 в 20:24
поделиться
Другие вопросы по тегам:

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