1

我在同一个文件夹中有多部分 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]+"");
}

但后来我得到了错误:

无效的存档打开/读取错误!它是否已加密并且提供了错误的密码?如果您的存档是异国情调的,则 SevenZipSharp 可能没有其格式的签名,因此错误地认为它是 TAR

请注意,WinRAR 程序似乎会更改 RAR 文件格式,因为我创建了一个版本为 5.71 的 RAR 文件,当我尝试使用旧版本的 WinRAR 打开它时,它无法正常打开,我的意思是文件格式不正确。

这同样适用于 SevenZipSharp。如果我打开自 2014 年以来创建的旧 RAR 文件,它可以正常打开,但是当我打开使用 WinRAR v 5.71 创建的 RAR 文件时,它会引发此错误。

那么现在如何获取多部分 RAR 文件的所有部分文件名?

谢谢你的帮助。

4

1 回答 1

0

我最终使用 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;
        }

于 2020-03-27T18:03:10.993 回答