使用ARJ自动生成带密码归档文件时遇执行异常求助
问题排查与修复方案
让我们一步步拆解你的问题,找到根源并给出可行的修复方案:
第一个版本代码的问题
你最初的代码报错“文件不存在”,核心原因是工作目录不匹配:
当你直接调用Process.Start(@"C:\ARJ_TEST\programming\test\ARJ.EXE", command)时,ARJ程序的工作目录是你C#程序的运行目录(而非E:\TestFiles)。虽然命令里用了file.FullName作为源文件路径,但ARJ在解析参数时若路径处理有歧义,就会触发找不到文件的错误;同时归档目标文件也会被创建在程序运行目录而非文件所在目录,不符合预期。
第二个版本代码的问题
你修改后切换了工作目录,但代码执行无反应,有几个核心错误:
- 调用
cmd.exe缺少必要参数:cmd.exe需要/c参数来执行传入的命令并自动退出,直接传ARJ命令的话,cmd只会启动一个空会话,不会执行任何实际操作。 - ARJ程序路径未明确指定:你手动在CMD中能执行是因为当前会话的环境变量包含ARJ的路径,但代码调用的cmd会话可能没有这个配置,导致找不到ARJ程序。
- 重复复用
ProcessStartInfo实例:同一个ProcessStartInfo被多次传递给Process.Start,可能导致内部状态异常,引发不可预期的行为。
修复后的代码方案(推荐直接调用ARJ,无需通过CMD)
这种方式更高效,避免CMD带来的额外问题:
DirectoryInfo dInfoForTesting = new DirectoryInfo(@"E:\TestFiles"); FileInfo[] files = dInfoForTesting.GetFiles(); // 明确指定ARJ程序的完整路径 string arjExePath = @"C:\ARJ_TEST\programming\test\ARJ.EXE"; string archivePassword = "134"; foreach (FileInfo file in files) { // 构造ARJ命令参数:归档到当前工作目录的[文件名].arj,源文件为当前目录下的文件名 string arjArguments = $"a -m1 -g{archivePassword} \"{file.Name}.arj\" \"{file.Name}\""; ProcessStartInfo startInfo = new ProcessStartInfo { FileName = arjExePath, Arguments = arjArguments, // 设置工作目录为文件所在路径,确保ARJ能找到源文件 WorkingDirectory = dInfoForTesting.FullName, // 可选:若不需要显示ARJ的命令行窗口,设为true CreateNoWindow = false, UseShellExecute = true }; // 使用using包裹Process,确保进程资源正确释放 using (Process arjProcess = Process.Start(startInfo)) { // 等待当前归档完成再处理下一个文件,避免并发冲突 arjProcess.WaitForExit(); } }
关键修改点说明:
- 指定ARJ完整路径:彻底避免“找不到ARJ程序”的问题。
- 设置正确的工作目录:让ARJ直接在
E:\TestFiles下操作,源文件和归档文件的路径都可以用简单的文件名,无需完整路径。 - 使用
using管理Process:确保每个归档进程结束后释放资源,避免内存泄漏。 - 添加
WaitForExit():防止多个ARJ进程同时运行(如果ARJ不支持多实例并发的话),保证归档操作有序完成。
若必须通过CMD调用的修复方案
如果你确实需要通过CMD执行,需要修正参数传递方式:
DirectoryInfo dInfoForTesting = new DirectoryInfo(@"E:\TestFiles"); FileInfo[] files = dInfoForTesting.GetFiles(); string arjExePath = @"C:\ARJ_TEST\programming\test\ARJ.EXE"; string archivePassword = "134"; foreach (FileInfo file in files) { // 构造完整的ARJ命令(包含程序路径),用引号包裹避免路径含空格的问题 string arjCommand = $"\"{arjExePath}\" a -m1 -g{archivePassword} \"{file.Name}.arj\" \"{file.Name}\""; // CMD需要/c参数来执行命令并退出 string cmdArguments = $"/c {arjCommand}"; // 每次循环创建新的ProcessStartInfo实例,避免状态冲突 ProcessStartInfo startInfo = new ProcessStartInfo { FileName = "cmd.exe", Arguments = cmdArguments, WorkingDirectory = dInfoForTesting.FullName, CreateNoWindow = false, UseShellExecute = true }; using (Process cmdProcess = Process.Start(startInfo)) { cmdProcess.WaitForExit(); } }
关键修改点说明:
- 添加
/c参数:告诉CMD执行完指定命令后退出。 - ARJ路径用引号包裹:避免路径中包含空格时CMD解析错误。
- 每次循环新建
ProcessStartInfo:避免复用导致的状态异常。
内容的提问来源于stack exchange,提问作者Setplus
相关产品推荐
相关产品推荐

