简体   繁体   中英

SevenZipSharp doesn't extract archive

I'm trying to use SevenZipSharp from https://github.com/squid-box/SevenZipSharp to extract a zip archive. The dll setup is as follows:

public class Paths
{
    private static readonly string SynthEBDexeDirPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
    public static readonly string ResourcesFolderPath = Path.Combine(SynthEBDexeDirPath, "Resources");
    // Toggle between the x86 and x64 bit dll
    public readonly string SevenZipPath = Path.Combine(ResourcesFolderPath, "7Zip", Environment.Is64BitProcess ? "x64" : "x86", "7z.dll");

The dll files are copied into my Resources folder from the latest version of 7-Zip. The calling code looks as follows:

using System.IO;
using System.Windows.Controls;
using SevenZip;

namespace SynthEBD;
public class VM_ZipArchiveHandler : VM
{
    public VM_ZipArchiveHandler(Window_SevenZipArchiveHandler window) 
    { 
        if (File.Exists(PatcherSettings.Paths.SevenZipPath))
        {
            SevenZipBase.SetLibraryPath(PatcherSettings.Paths.SevenZipPath);
            Initialized = true;
        }
        else
        {
            CustomMessageBox.DisplayNotificationOK("Initialization Error", "Could not initialize Seven Zip from " + PatcherSettings.Paths.SevenZipPath);
        }
        
        Window = window;
    }

    public string DispString { get; set; } = string.Empty;
    public ProgressBar Prog = new ProgressBar();
    public Window_SevenZipArchiveHandler Window { get; set; }
    private bool Initialized { get; set; } = false;

    public void Unzip(string archivePath, string destinationFolder)
    {
        if (!Initialized)
        {
            return;
        }
        Prog.Minimum = 0;
        Prog.Maximum = 100;
        Prog.Value = 0;

        Window.Show();

        var progressHandler = new Progress<byte>(
            percentDone => Prog.Value = percentDone);
        var progress = progressHandler as IProgress<byte>;

        var file = new SevenZipExtractor(archivePath);
        file.Extracting += (sender, args) =>
        {
            progress.Report(args.PercentDone);
        };
        file.ExtractionFinished += (sender, args) =>
        {
            // Do stuff when done
        };

        Task.Run(() =>
        {
            //Extract the stuff
            file.ExtractArchive(destinationFolder);
        });

        Window.Close();
    }

    public static void UnzipArchive(string archivePath, string destinationDir)
    {
        Window_SevenZipArchiveHandler window = new Window_SevenZipArchiveHandler();
        VM_ZipArchiveHandler handler = new(window);
        window.DataContext = handler;
        handler.Unzip(archivePath, destinationDir);
    }
}

I call UnzipArchive() :

string tempFolderPath = Path.Combine(PatcherSettings.ModManagerIntegration.TempExtractionFolder, DateTime.Now.ToString("yyyy-MM-dd-HH-mm", System.Globalization.CultureInfo.InvariantCulture));

try
{
    Directory.CreateDirectory(tempFolderPath);
}
catch (Exception ex)
{
    Logger.LogError("Could not create or access the temp folder at " + tempFolderPath + ". Details: " + ex.Message);
    return installedConfigs;
}

try
{
    VM_ZipArchiveHandler.UnzipArchive(path, tempFolderPath);
}   

     
    

In the end I get an empty directory; the.7z contents are never extracted to it. I've tried using both a.zip and.7z file as inputs, each containing two json files and nothing else. When I set a breakpoint at file.ExtractArchive(destinationFolder), it seems semi-correctly initialized: https://imgur.com/qjYpDur

It looks like it's correctly recognized as a SevenZip archive, but fields like _filesCount are null.

Am I doing something wrong with my setup?

I believe the issue is that your ExtractArchive is wrapped inside a Task and the calling thread returns before the extraction completes and isn't awaited. Not 100% on the details but as an experiment I found what works and what leaves the destination directory empty:

public static void Main(string[] args)
{
    SevenZipBase.SetLibraryPath(
        Path.Combine(
            Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"7z.dll"));
    string archivePath = "D:\\Downloads\\imgs.7z";
    var file = new SevenZipExtractor(archivePath);

    // works 
    file.ExtractArchive("D:\\Downloads\\unzipped");

    // doesnt work
    Task.Run(() =>
    {
        file.ExtractArchive("D:\\Downloads\\unzipped");
    });

    // works
    Task.Run(() =>
    {
        file.ExtractArchive("D:\\Downloads\\unzipped");
    }).Wait();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM