1

For various reasons I use 7z.exe, instead of wrappers, and unzipping looks like this:

        var args = new StringBuilder();
        args.AppendFormat("x \"{0}\"", source);
        args.AppendFormat(" -o\"{0}\"", destination);
        args.Append(" -y");
        args.AppendFormat(" -p{0}", PassEscape(password)); // the password may contain special characters, etc

        var code = ProcessHelper.Run(
            new ProcessStartInfo
            {
                FileName  = _zipPath,
                Arguments = args.ToString()
            },
            token,
            DefaultTimeout);

        error = code != 0 ? ExitCodeTable.GetOrDefault(code, "Unknown 7z error") : null;
        return code == 0;

I omit some trivial parts of the code such as ProcessHelper, it just start process and run it to completion. The sample I use for testing contains test password !@#$%^&*()_+"; and using code above it always says the password is wrong.

The function PassEscape is completely unknown to me, because I can't find any info which will help me to completely escape all of those special characters (including other encodings), but currently it is pretty simple:

    private static string PassEscape(string input)
    {
        if (string.IsNullOrEmpty(input))
            return input;

        var b = new StringBuilder();
        b.Append('"');
        b.Append(input);
        b.Append('"');
        return b.ToString();
    }

Any help?

eocron
  • 6,885
  • 1
  • 21
  • 50
  • https://sourceforge.net/p/sevenzip/discussion/45797/thread/ee631feb/ – xdtTransform Nov 19 '19 at 09:53
  • Currently I tried combinations -p"""", -p""", -p"", -p"\"" and still no luck to unpack archive with password ".... – eocron Nov 19 '19 at 09:53
  • No luck, rar archive is currently unpackable with latests version of 7zip, tried with bat file: *7z.exe x ".\foo.rar" -o".\out" -y -p""* – eocron Nov 19 '19 at 10:10
  • @xdtTransform, how one can pass 7zip configuration in text file? or can it be passed in stdin? – eocron Nov 19 '19 at 10:12
  • @eocron, Sorry I have been miss leading. All my memories were wrong. I messed up betwwen 7Zip / Winrar / WinZip command line. – xdtTransform Nov 19 '19 at 10:29
  • 1
    related: https://stackoverflow.com/questions/40438074/extract-password-archive-with-double-quote-in-windows-command-line – xdtTransform Nov 19 '19 at 10:29

1 Answers1

1

This works for me:

string source = @"C:\Temp\New folder.7z";
string destination = @"C:\Temp\destination";
string password = "!@#$%^&*()_+\";";

Process sevenzip = Process.Start(
    new ProcessStartInfo
    {
        FileName = @"C:\Program Files\7-Zip\7z.exe",
        Arguments = $"x \"{source}\" -o\"{destination}\" -y -sccutf-8",
        RedirectStandardInput = true,
        UseShellExecute = false
    });

sevenzip.StandardInput.WriteLine(password);
sevenzip.WaitForExit();
Longoon12000
  • 774
  • 3
  • 13
  • This actually worked! No more fights with windows parsing and just plain stdin command! Thank you! Checked for null password (i.e. no password) - this works too. – eocron Nov 19 '19 at 10:38
  • @eocron There's no Windows parsing. This isn't Unix :) Either 7zip handles quotes, or it doesn't. Windows doesn't come into it in the slightest. Do keep in mind this solution is rather brittle, though, depending on non-contractual behaviour of 7z.exe. – Luaan Nov 19 '19 at 10:42
  • @Luaan, based on his source code there is actually different parsers for *nix and windows =( – eocron Nov 19 '19 at 10:46
  • @eocron Yup. They have their own command-line parser, and it pretty much sucks. If you look in CommandLineParser.SplitCommandLine, that's all the quoting logic there is - a quote character switches between "quoted mode" and "non-quoted mode", which in turn only affects whether `' '` and `'\t'` are currently interpreted as argument separators or not. There's no way to escape a quote character. My point was mainly that you're not fighting some Windows parsing - Windows doesn't come into it at all. The C++ compiler does, but in this case, even that is ignored (otherwise `"-p\""` would work). – Luaan Nov 19 '19 at 11:03
  • Agree. In run for back-compat or whatever, those parsers became unusable for modern passwords/path. – eocron Nov 19 '19 at 11:36