在尝试在命令提示符中运行相同命令时无法正常工作

3
我正在制作一个程序,用 ImageMagick 在文件夹中查找安全的 PDF 文件并将它们转换为 PNG 文件。以下是我的代码。
string WorkDir = @"C:\Users\rwong\Desktop\TestFiles";
Directory.SetCurrentDirectory(WorkDir);
String[] SubWorkDir = Directory.GetDirectories(WorkDir);

foreach (string subdir in SubWorkDir)
{
    string[] filelist = Directory.GetFiles(subdir);
    for(int f = 0; f < filelist.Length; f++)
    {
        if (filelist[f].ToLower().EndsWith(".pdf") || filelist[f].EndsWith(".PDF"))
        {
            PDFReader reader = new Pdfreader(filelist[f]);
            bool PDFCheck = reader.IsOpenedWithFullPermissions;
            reader.CLose();
            if(PDFCheck)
            {
            //do nothing
            }
            else
            {
                string PNGPath = Path.ChangeExtension(filelistf], ".png");
                string PDFfile = '"' + filelist[f] + '"';
                string PNGfile = '"' + PNGPath + '"';
                string arguments = string.Format("{0} {1}", PDFfile, PNGfile);
                ProcessStartInfo startInfo = new ProcessStartInfo(@"C:\Program Files\ImageMagick-6.9.2-Q16\convert.exe");
                startInfo.Arguments = arguments;
                Process.Start(startInfo);
            }
      }
}

我在命令提示符中运行了原始命令,并且它可以正常工作,因此命令不是问题。下面是示例命令:

"C:\Program Files\ImageMagick-6.9.2-Q16\convert.exe" "C:\Users\rwong\Desktop\TestFiles\Test_File File_10.PDF" "C:\Users\rwong\Desktop\TestFiles\Test_File File_10.png"

我在SO上查看了一下,有暗示我的变量中的空格可能会导致问题,但这些线程大多谈论硬编码参数名称,并且只讨论一个参数。我认为给每个变量添加双引号会解决问题,但事实并非如此。我还读到使用ProcessStartInfo可能会有所帮助,但仍然没有结果。我猜测是我格式化了两个参数以及调用命令的方式,或者我使用ProcessStartInto的方法不对。有什么想法吗?
编辑:根据下面的评论,我进行了额外的测试,等待命令窗口退出,我发现以下错误。

Error when calling convert.exe

顺便提一下:我暂时不想使用GhostScript,因为我觉得使用ImageMagick就能很快得到答案。


1
你目前检查了什么?你是否跨过自己的代码并验证了正确的变量内容? - Tobias Knauss
你看到了什么错误?你的 C# 程序的路径是否有 Ghostscript,因为它的路径可能与你在命令行处的路径不同。 - Mark Setchell
@TobiasKnauss 我目前检查的是我传递的可变参数。我的 string arguments 变量如下: "\"C:\\Users\\rwong\\Desktop\\RoundPoint\\1000965275\\1000965275_157_Credit File_10.PDF\" \"C:\\Users\\rwong\\Desktop\\RoundPoint\\1000965275\\1000965275_157_Credit File_10.png\"" - LampPost
尝试不带参数启动进程,以查看它是否正在运行。此外,在测试中使用较短的路径和文件名,没有空格,例如c:\temp\file.pdf。 - Tobias Knauss
@rene,我已经更新了这篇文章,如果有帮助解答你的问题,请查看。 - LampPost
显示剩余3条评论
2个回答

1
解决方案:
string PNGPath = Path.ChangeExtension(Loan_list[f], ".png");
string PDFfile = PNGPath.Replace("png", "pdf");
string PNGfile = PNGPath;
Process process = new Process();
process.StartInfo.FileName = @"C:\Program Files\ImageMagick-6.9.2 Q16\convert.exe";
process.StartInfo.Arguments = "\"" + PDFfile + "\"" +" \"" + PNGPath +"\""; // Note the /c command (*)
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.RedirectStandardError = true;
process.Start();
//* Read the output (or the error)
string output = process.StandardOutput.ReadToEnd();
Console.WriteLine(output);
string err = process.StandardError.ReadToEnd();
Console.WriteLine(err);
process.WaitForExit();

它不喜欢我格式化参数字符串的方式。

0
这将帮助你在C#中运行命令,同时你还可以在C#中获取控制台的结果。
string WorkDir = @"C:\Users\rwong\Desktop\TestFiles";
Directory.SetCurrentDirectory(WorkDir);
String[] SubWorkDir = Directory.GetDirectories(WorkDir);

foreach (string subdir in SubWorkDir)
{
    string[] filelist = Directory.GetFiles(subdir);
    for(int f = 0; f < filelist.Length; f++)
    {
        if (filelist[f].ToLower().EndsWith(".pdf") || filelist[f].EndsWith(".PDF"))
        {
            PDFReader reader = new Pdfreader(filelist[f]);
            bool PDFCheck = reader.IsOpenedWithFullPermissions;
            reader.CLose()l
            if(!PDFCheck) 
            {
                string PNGPath = Path.ChangeExtension(filelistf], ".png");
                string PDFfile = '"' + filelist[f] + '"';
                string PNGfile = '"' + PNGPath + '"';
                string arguments = string.Format("{0} {1}", PDFfile, PNGfile);
                Process p = new Process();
                p.StartInfo.UseShellExecute = false;
                p.StartInfo.RedirectStandardOutput = true;
                p.StartInfo.RedirectStandardError = true;
                p.EnableRaisingEvents = true;
                p.StartInfo.CreateNoWindow = true;
                p.startInfo.FileName = "C:\Program Files\ImageMagick-6.9.2-Q16\convert.exe";
                p.startInfo.Arguments = arguments;
                p.OutputDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);
                //You can receive the output provided by the Command prompt in Process_OutputDataReceived
                p.Start();
            }
      }
}

private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
    {
        string s = e.Data.ToString();
        s = s.Replace("\0", string.Empty);
        //Show s 
        Console.WriteLine(s);
    }
}

谢谢你对两个问题的输出!在尝试调用'DataReceivedEventHandler'时我遇到了一个错误,大致意思是“需要非静态字段、方法或属性的对象引用”,所以我在函数声明前面添加了关键字'static',尽管编译通过了,但函数从未运行。 - LampPost
你在哪里添加了static关键字?在Process中还有一个错误处理程序,请注意不要在Console应用程序中运行程序。请创建一个WPF或WinForm应用程序。 - Mohit S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接