Получить файлы томов из многочастного RAR-файла c# - PullRequest
1 голос
/ 12 марта 2020

У меня есть файлы RAR, состоящие из нескольких частей, в одной папке, и я хочу проверить, существуют ли все части RAR. Я использую SharpCompress v0.24, вот мой код:

using (var archive = RarArchive.Open("D:/Ontology tool.part1.rar"))
{

    foreach (RarVolume vol in archive.Volumes)
    {
        MessageBox.Show(vol.IsMultiVolume + " \n"+ vol.IsFirstVolume+"\n"+ vol.IsSolidArchive);
    }
}

Но я не могу получить полное имя файла тома. Затем я использую SevenZipSharp v 0.64 и 7z.dll версии 19, вот мой код:

using (var extractor = new SevenZipExtractor("D:/Ontology tool.part1.rar"))
{
    MessageBox.Show(extractor.VolumeFileNames[0]+"");
}

Но тогда я получаю ошибку:

Недопустимая ошибка открытия / чтения архива! Это зашифровано и был введен неправильный пароль? Если ваш архив является exoti c, возможно, что SevenZipSharp не имеет подписи для своего формата и, таким образом, решил, что это TAR по ошибке

Обратите внимание, что программа WinRAR, похоже, вносит изменения в RAR форматы файлов, потому что я создаю файл RAR с версией 5.71, и когда я пытаюсь открыть его со старой версией WinRAR, он не открывается нормально, я имею в виду файлы не в правильном формате.

То же самое относится к SevenZipSharp. Если я открываю старый файл RAR, который я создал с 2014 года, он открывается нормально, но когда я открываю файл RAR, созданный с помощью WinRAR v 5.71, возникает эта ошибка.

Итак, как теперь получить все имена файлов деталей для нескольких часть RAR файла?

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 27 марта 2020

Я заканчиваю тем, что использую winrar.exe, отправляю команду в тестовый файл так:

  [DllImport("User32.dll")]
        static extern int SetForegroundWindow(IntPtr point);


        [DllImport("user32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool GetWindowPlacement(IntPtr hWnd, ref WINDOWPLACEMENT lpwndpl);

        [DllImport("user32.dll")]
        static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private const int SW_MAXIMIZE = 3;
        private const int SW_MINIMIZE = 6;
        private struct WINDOWPLACEMENT
        {
            public int length;
            public int flags;
            public int showCmd;
            public System.Drawing.Point ptMinPosition;
            public System.Drawing.Point ptMaxPosition;
            public System.Drawing.Rectangle rcNormalPosition;
        }
        private enum WindowShowStyle : uint
        {
            /// <summary>Hides the window and activates another window.</summary>
            /// <remarks>See SW_HIDE</remarks>
            Hide = 0,
            /// <summary>Activates and displays a window. If the window is minimized
            /// or maximized, the system restores it to its original size and
            /// position. An application should specify this flag when displaying
            /// the window for the first time.</summary>
            /// <remarks>See SW_SHOWNORMAL</remarks>
            ShowNormal = 1,
            /// <summary>Activates the window and displays it as a minimized window.</summary>
            /// <remarks>See SW_SHOWMINIMIZED</remarks>
            ShowMinimized = 2,
            /// <summary>Activates the window and displays it as a maximized window.</summary>
            /// <remarks>See SW_SHOWMAXIMIZED</remarks>
            ShowMaximized = 3,
            /// <summary>Maximizes the specified window.</summary>
            /// <remarks>See SW_MAXIMIZE</remarks>
            Maximize = 3,
            /// <summary>Displays a window in its most recent size and position.
            /// This value is similar to "ShowNormal", except the window is not
            /// actived.</summary>
            /// <remarks>See SW_SHOWNOACTIVATE</remarks>
            ShowNormalNoActivate = 4,
            /// <summary>Activates the window and displays it in its current size
            /// and position.</summary>
            /// <remarks>See SW_SHOW</remarks>
            Show = 5,
            /// <summary>Minimizes the specified window and activates the next
            /// top-level window in the Z order.</summary>
            /// <remarks>See SW_MINIMIZE</remarks>
            Minimize = 6,
            /// <summary>Displays the window as a minimized window. This value is
            /// similar to "ShowMinimized", except the window is not activated.</summary>
            /// <remarks>See SW_SHOWMINNOACTIVE</remarks>
            ShowMinNoActivate = 7,
            /// <summary>Displays the window in its current size and position. This
            /// value is similar to "Show", except the window is not activated.</summary>
            /// <remarks>See SW_SHOWNA</remarks>
            ShowNoActivate = 8,
            /// <summary>Activates and displays the window. If the window is
            /// minimized or maximized, the system restores it to its original size
            /// and position. An application should specify this flag when restoring
            /// a minimized window.</summary>
            /// <remarks>See SW_RESTORE</remarks>
            Restore = 9,
            /// <summary>Sets the show state based on the SW_ value specified in the
            /// STARTUPINFO structure passed to the CreateProcess function by the
            /// program that started the application.</summary>
            /// <remarks>See SW_SHOWDEFAULT</remarks>
            ShowDefault = 10,
            /// <summary>Windows 2000/XP: Minimizes a window, even if the thread
            /// that owns the window is hung. This flag should only be used when
            /// minimizing windows from a different thread.</summary>
            /// <remarks>See SW_FORCEMINIMIZE</remarks>
            ForceMinimized = 11
        }

        [DllImport("user32.dll")]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int count);


        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        public static extern IntPtr GetParent(IntPtr hWnd);

        const int SW_RESTORE = 9;
        [DllImport("user32.dll")]
        static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);


        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport("user32.dll")]
        static extern bool MoveWindow(IntPtr Handle, int x, int y, int w, int h, bool repaint);

        static readonly int GWL_STYLE = -16;
        static readonly int WS_VISIBLE = 0x10000000;

....
 private string GetMissingCompressedFile(string FilePath, string WinRARPath)
        {
            string MissingCompressedFile = "";
            Process p = new Process();
            p.StartInfo.FileName = WinRARPath;
            p.EnableRaisingEvents = true;
            // -ibck -inul
            p.StartInfo.Arguments = " t " + " \"" + FilePath + "\"";
            //p.StartInfo.UseShellExecute = false;
           // p.StartInfo.RedirectStandardOutput = true;
            //p.StartInfo.RedirectStandardError = true;
            //p.StartInfo.CreateNoWindow = true;
            p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;

            IntPtr PanelHandler=new IntPtr();
            WinRARPanel_Ref.Invoke((MethodInvoker)delegate
            {
                PanelHandler = WinRARPanel_Ref.Handle;
            });

            p.Start();

            IntPtr h = p.MainWindowHandle;

            while (true)
            {
                if (p.HasExited)
                    break;
                if (p.MainWindowHandle != IntPtr.Zero)
                    break;

                    Thread.Sleep(100); // Don't hog the CPU
                p.Refresh(); // You need this since `MainWindowHandle` is cached

            }
                if (!p.HasExited)
                {
                    SetParent(p.MainWindowHandle, PanelHandler);
                    //SetWindowLong(p.MainWindowHandle, GWL_STYLE, WS_VISIBLE);
                    //MoveWindow(p.MainWindowHandle, 0, 0, WinRARPanel_Ref.Width, WinRARPanel_Ref.Height, true);
                }


            while (!p.HasExited)
            {
                var _windowHandle = FindWindow(null, "Next volume is required");
                var _parent = GetParent(_windowHandle);
                if (_parent == p.MainWindowHandle)
                {
                    if (!p.HasExited)
                    {
                        SetParent(_windowHandle, WinRARPanel_Ref.Handle);
                    }
                    Thread.Sleep(1000);
                    if (!p.HasExited)
                        {

                        MainForm_Ref.Invoke((MethodInvoker)delegate
                        {     
                            Clipboard.Clear();


                            ShowWindow(h, SW_RESTORE);
                            SetForegroundWindow(h);
                            SendKeys.SendWait("^(c)");
                            string ClipboardText = Clipboard.GetText();
                            if (!string.IsNullOrEmpty(ClipboardText))
                            {

                                try
                                {
                                    string n = new FileInfo(ClipboardText).Name;

                                    MissingCompressedFile = ClipboardText;

                                    if (!p.HasExited)
                                    {
                                        p.Kill();
                                    }
                                }
                                catch
                                {
                                    if (ClipboardText.Contains("You need to start extraction from a previous volume to unpack"))
                                    {
                                        MissingCompressedFile = "";
                                        p.Kill();
                                    }
                                }

                                Clipboard.Clear();
                            }
                        });

                        }
                }
                else
                {
                    if (!p.HasExited)
                    {

                        MainForm_Ref.Invoke((MethodInvoker)delegate
                        {
                            Clipboard.Clear();

                            if (!p.HasExited)
                            {
                                ShowWindow(h, SW_RESTORE);
                                SetForegroundWindow(h);
                            }
                            SendKeys.SendWait("^(c)");
                            string ClipboardText = Clipboard.GetText();
                            if (!string.IsNullOrEmpty(ClipboardText))
                            {

                                try
                                {
                                    string n = new FileInfo(ClipboardText).Name;

                                    MissingCompressedFile = ClipboardText;

                                    if (!p.HasExited)
                                    {
                                        p.Kill();
                                    }
                                }
                                catch
                                {
                                    if (ClipboardText.Contains("You need to start extraction from a previous volume to unpack"))
                                    {
                                        MissingCompressedFile = "";
                                        p.Kill();
                                    }
                                }

                                Clipboard.Clear();
                            }
                        });

                    }
                }
            }

            if (!p.HasExited)
            {
                p.Kill();
            }
            p = null;

            return MissingCompressedFile;
        }

...