Как сохранить сборку на диск?

Как сохранить сборку в файл? Т.е. Я имею в виду не динамическую сборку, а «нормальные» сборки в памяти.

Assembly[] asslist = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly ass1 in asslist)
{
    // How to save?
}

Такая ситуация может возникнуть, когда приложение загружает некоторые сборки, на которые есть ссылки, из ресурсов. Я хочу сохранить их на диск.

Извлечь сборки из ресурсов невозможно, так как они там зашифрованы.


person ZedZip    schedule 24.06.2012    source источник
comment
+1, если только за использование assList.   -  person Iridium    schedule 24.06.2012
comment
В этом нет никакого смысла. И это невозможно. Конечно, гораздо проще просто прочитать сборку из ресурса и сохранить ее с помощью File.WriteAllBytes (). Или просто не помещать это в ресурс.   -  person Hans Passant    schedule 24.06.2012
comment
Зачем вам сохранять [...] задницы на диск? Вот откуда их загрузили. Разве вы не можете просто вычислить пути, а затем скопировать их?   -  person stakx - no longer contributing    schedule 24.06.2012
comment
Если вы хотите извлекать сборки из ресурсов, используйте что-то вроде reshack   -  person Jim Deville    schedule 24.06.2012
comment
2 stackx: Потому что я хочу проанализировать некоторые функции в этих сборках. Они загружают ресурсы для событий с помощью дешифрования.   -  person ZedZip    schedule 24.06.2012


Ответы (3)


Как насчет попытки сериализовать сборку? Он сериализуемый.

person GregRos    schedule 24.06.2012

На основе идеи Грега Роса я разработал этот небольшой фрагмент. Обратите внимание, что я старался придерживаться соглашения об именах.

public void SaveAllAssemblies()
{   
    Assembly[] asslist = AppDomain.CurrentDomain.GetAssemblies();
    foreach (Assembly ass in asslist)
    {
        FileInfo fi = new FileInfo(ass.Location);

        if (!fi.Extension.Equals(".exe", StringComparison.InvariantCultureIgnoreCase))
        {
            var assName = fi.Name;
            var assConverter = new FormatterConverter(); 
            var assInfo = new SerializationInfo(typeof(Assembly), assConverter);
            var assContext = new StreamingContext();

            using (var assStream = new FileStream(assName, FileMode.Create))
            {
                BinaryFormatter bformatter = new BinaryFormatter();
                ass.GetObjectData(assInfo, assContext);

                bformatter.Serialize(assStream, assInfo);
                assStream.Close();
            }
        }
    }
}   

Но некоторые сборки не помечены как сериализуемые, например mscorlib.dll. Значит, это, наверное, только частичное решение?

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

person Mare Infinitus    schedule 24.06.2012
comment
Я пробовал этот способ в своем тестовом приложении (exe и моя сборка). Пытался сериализовать свою сборку. Ошибка связана с вызовом bformatter.Serialize (): [System.Runtime.Serialization.SerializationException] = {Введите 'System.Runtime.Serialization.SerializationInfo' в сборке mscorlib, Version = 4.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089 'не помечен как сериализуемый.} - person ZedZip; 25.06.2012

Вам нужно найти путь, по которому пришли ваши сборки. Вы можете найти это так:

Assembly ass = ...;
return ass.Location;

Обратите внимание, что as является ключевым словом и не может использоваться в качестве идентификатора. Я рекомендую использовать ass.

person usr    schedule 24.06.2012
comment
Я не могу найти пути, потому что эти сборки зашифрованы и находятся в ресурсах. Приложение загружает их при «событии разрешения». Свойство "Местоположение" невозможно прочитать, так как оно содержит непечатаемые символы. - person ZedZip; 25.06.2012