我在同一文件夹中有多个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 v0.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 v5.71创建的RAR文件时,它会引发此错误。
那么现在我如何获得多部分RAR文件的所有部分文件名?
谢谢你的帮助。
我最终使用了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;
}