2

我之前已经成功使用过 wkhtmltopdf,但现在我有一个场景是我需要在启动该过程时使用特定帐户。当我设置一个有效的用户名/密码时,标准输出流是空的,返回码是-1。一旦我注释掉用户名/密码,它就会按预期工作。

在 .Net 4、Win 7 64 位中对此进行测试。

class Program
{
    static void Main(string[] args)
    {
        var wkhtmlDir = AppDomain.CurrentDomain.BaseDirectory;
        var wkhtml = wkhtmlDir + @"\wkhtmltopdf.exe";

        var info = new ProcessStartInfo(wkhtml);

        info.CreateNoWindow = true;
        info.RedirectStandardOutput = true;
        info.RedirectStandardError = true;
        info.RedirectStandardInput = true;
        info.UseShellExecute = false;
        info.WorkingDirectory = wkhtmlDir;

        info.Arguments = "http://www.google.com -";

        var securePassword = new SecureString();
        var password = "mypassword";

        foreach (var c in password)
        {
            securePassword.AppendChar(c);
        }

        //comment out next three lines, and it works!
        info.UserName = "myuser"; 
        info.Password = securePassword;
        info.Domain = "mydomain"; 

        using (var process = Process.Start(info))
        {
            var output = process.StandardOutput.ReadToEnd();

            // wait or exit
            process.WaitForExit(60000);

            var returnCode = process.ExitCode;
        }

    }

如果我注释掉 info.UserName、Password、Domain,则输出有数据,否则如果我尝试使用凭据,则输出为空白且 returnCode 为-1。

希望其他人遇到这种情况,这似乎是一个常见的情况,我肯定错过了一些简单的东西......

谢谢你的帮助!!

4

2 回答 2

3

我还在 .net 应用程序中使用 WKHTMLTOPDF。我发现的一些可能对您有帮助的事情是:

在您的情况下,您可能会遇到写入错误并导致死锁的问题?

您可以将您的流程设置为异步读取标准错误和标准输出,就像我在下面的示例中所做的那样。我希望这有帮助

sub doConversion()
        dim p as System.Diagnostics.Process = new System.Diagnostics.Process()
        p.StartInfo.FileName = "wkhtmltopdf.exe"

        dim url as string = "[[[YOUR URL TO CONVERT]]]"
        dim outfilename as string = "[[[WHERE YOU WANT THE FILE]]]"
        dim switches as string = ""
        switches &= "--disable-smart-shrinking  --print-media-type "
        switches &= "--margin-top 0mm --margin-bottom 0mm --margin-right 0mm --margin-left 0mm "
        switches &= "--page-size A4 "

        p.StartInfo.Arguments = switches & Url & " " & outfilename

        console.writeline("Running command: " & commandToRun & " " & switches & Url & " " & outfilename)

        '## needs to be false in order to redirect output
        p.StartInfo.UseShellExecute = false 

        p.StartInfo.RedirectStandardOutput = true
        AddHandler p.OutputDataReceived, addressOf PDFOutputHandler

        p.StartInfo.RedirectStandardError = true
        AddHandler p.ErrorDataReceived, addressOf PDFOutputHandler

        p.StartInfo.WorkingDirectory = rootPath & iif(rootpath.endswith("\"),"","\") 
        console.writeline("Starting...")

        try
            p.Start()
            p.BeginOutputReadLine()
            p.BeginErrorReadLine()
            console.writeline("Started...")
        catch ex as exception
            throw new exception("Could not start process [" & p.startInfo.Filename & "] with arguments [" & p.startInfo.Arguments & "], " & vbcrlf & "(RootPath: " & rootpath & ")" & vbcrlf & ex.tostring & vbcrlf)
        end try

        '## ...then wait for exit 
        p.WaitForExit()
end sub

Private Sub PDFOutputHandler(sendingProcess As Object, outLine As DataReceivedEventArgs)
    If Not String.IsNullOrEmpty(outLine.Data) Then
        console.writeline(outLine.Data)
     End If 
End Sub 
于 2013-11-06T17:13:07.963 回答
1

我不确定,在.net 中是否可行,但是当我创建具有不同凭据的进程(例如 Win API 中的 CreateProcessAsUser)并创建管道时,我显然必须传递给 CreateNamedPipe Null 安全或本地安全属性。

可能是你有同样的问题。

于 2012-06-06T23:29:34.507 回答