Страницы

Поиск по вопросам

четверг, 23 января 2020 г.

Распаковка deb-пакета С#

#c_sharp #ar #deb


Нужно распаковать deb-пакет на С#. Deb-файл является архивов ar. 

Есть ли какие-то библиотеки для распаковки архива ar под С#?

Зачем мне это нужно. Из deb-пакета я хочу получить версию пакета. То есть я хочу
добраться до файла control, где я смогу версию пакета прочитать. Может быть есть библиотеки
для чтения deb-пакета?
    


Ответы

Ответ 1



Под Windows deb файлы может открыть архиватор 7zip. Данная задача весьма специфическая Поэтому, сомневаюсь, что существует готовая "обёртка" под C# предназначенная специально для её решения. Вероятнее всего придётся писать её самому используя 7zip API. В принципе, есть ещё SevenZipSharp. Это "обёртка" для 7zip API под .NET. Хотя эта библиотека официально предназначена в основном для архивов в формате 7z и zip она также может распаковать и deb.

Ответ 2



С помощью библиотеки libarchive написал функцию на С++ #include "archive.h" #include "archive_entry.h" #include /** Примеры работы с библиотекой libarchive https://github.com/libarchive/libarchive/wiki/Examples */ /** * @brief Копирование данных из одного архива в другой * @param ar * @param aw * @return */ static int CopyData(struct archive *ar, struct archive *aw) { int r; const void *buff; size_t size; off_t offset; for (;;) { r = archive_read_data_block(ar, &buff, &size, &offset); if (r == ARCHIVE_EOF) { return (ARCHIVE_OK); } if (r < ARCHIVE_OK) { return (r); } r = archive_write_data_block(aw, buff, size, offset); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(aw)); return (r); } } } /** * @brief ExtractArchive Извечение архива на диск * @param filename - входной архив * @param outputDir - выходные данные * @return */ bool ExtractArchive(const char *filename, const char* dest) { struct archive *a; struct archive *ext; struct archive_entry *entry; int flags; int r; /* Select which attributes we want to restore. */ flags = ARCHIVE_EXTRACT_TIME; flags |= ARCHIVE_EXTRACT_PERM; flags |= ARCHIVE_EXTRACT_ACL; flags |= ARCHIVE_EXTRACT_FFLAGS; a = archive_read_new(); archive_read_support_format_all(a); archive_read_support_compression_all(a); ext = archive_write_disk_new(); archive_write_disk_set_options(ext, flags); archive_write_disk_set_standard_lookup(ext); if ((r = archive_read_open_filename(a, filename, 10240))) { fprintf(stderr, "file not found"); return false; } for (;;) { r = archive_read_next_header(a, &entry); if (r == ARCHIVE_EOF) { break; } if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(a)); } if (r < ARCHIVE_WARN) { return false; } const char* currentFile = archive_entry_pathname(entry); const std::string fullOutputPath = std::string(dest) + currentFile; archive_entry_set_pathname(entry, fullOutputPath.c_str()); r = archive_write_header(ext, entry); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(ext)); } else if (archive_entry_size(entry) > 0) { r = CopyData(a, ext); if (r < ARCHIVE_OK) fprintf(stderr, "%s\n", archive_error_string(ext)); if (r < ARCHIVE_WARN) { return false; } } r = archive_write_finish_entry(ext); if (r < ARCHIVE_OK) { fprintf(stderr, "%s\n", archive_error_string(ext)); } if (r < ARCHIVE_WARN) { return -1; } } archive_read_close(a); archive_read_free(a); archive_write_close(ext); archive_write_free(ext); return true; } int main() { ExtractArchive(pathToDeb, destFolder); return 0; } Функции ExtractArchive передаю deb-файл, который он удачно распаковывает в папку destFolder. На выходе получаю 3 файла control.tar.gz data.tar.gz. dedian-binary. Теперь имея архив control.tar.gz, я его распакую(библиотек для работы с архивом tar.gz много, в том числе и для С#) и вытащу из него нужный мне файл control. Теперь сделаю сборку нативной библиотеки и буду дергать функцию ExtractArchive из С#. Это мое быстрое решение проблемы распаковки ar-архива под С#.

Комментариев нет:

Отправить комментарий