将作业添加到特定用户的PrintQueue

gle*_*ron 7 c# printing impersonation

我有一个应用程序,根据用户请求执行一些中央文件生成.我希望能够用它做一次创建的文件是将它们放置在用户的打印队列(在这个组织有一个中央打印队列,以便用户负责打印自己的文档),这样他们就可以有用户准备好后打印出来.

通过使用System.Printing.net中的程序集,我可以将作业添加到我自己的打印队列中,所以我听起来就是那个部分.我的打印代码如下所示:

private void RunPrintJob( string myFileName )
    {
        PrintServer ps = new PrintServer(@"\\printatron");
        PrintQueue queue = new PrintQueue(ps, "psandqueues");
        try
        {
            PrintSystemJobInfo pj = queue.AddJob(myFileName);
            Stream myStream = pj.JobStream;
            Byte[] myByteBuffer = GenerateBufferFromFile(myFileName);                myStream.Write(myByteBuffer, 0, myByteBuffer.Length);
            myStream.Close();
        }
        catch (Exception ed)
        {
            Debug.WriteLine(ed.Message);
            if (ed.InnerException != null)
            {
                Debug.WriteLine(" -> " + ed.InnerException);
            }
            result = false;
        }
        queue.Commit();
    }
Run Code Online (Sandbox Code Playgroud)

所以我有我的集中创建的文档,我知道哪个用户负责他们的创建,我可以将它们发送到打印机.

我现在需要的是一种将创建它们的用户设置为打印机的方法.有没有办法通过打印队列执行此操作?我知道它可以从PrintSystemJobInfo.Submitter属性读取,但这是只读的.如果没有,我是否必须通过模拟来实现,如果是这样,在后一种情况下,我可以做些什么来避免必须存储一堆用户密码并且每次用户更改密码时软件都会失败?这似乎是一种非常笨拙的操作方式,但由于此活动目前尚未以交互方式执行,我还有其他选择吗?

dov*_*yai 3

我正在做类似的事情。如果进程有足够的权限来获得您需要的模拟级别(例如模拟或委派与识别),那么模拟并不算太糟糕。

这是我模仿的方法:

    public static bool GetImpersonationToken(string UPN, out IntPtr dupToken)
    {
        dupToken = IntPtr.Zero;
        WindowsImpersonationContext impersonationContext = null;

        bool result = false;
        try
        {
            WindowsIdentity wid = new WindowsIdentity(UPN);
            impersonationContext = wid.Impersonate();
            result = DuplicateToken(wid.Token, 2, ref dupToken) != 0;
        }
        finally
        {
            if (impersonationContext != null)
                impersonationContext.Undo();
        }

        return result;
    }
Run Code Online (Sandbox Code Playgroud)

注意:调用方法有责任清理该令牌句柄。

我根据用户电子邮件从 LDAP 查询解析 UPN(通常它们是相同的,但很多时候它们并不相同)。

但我传入的字节数组存在一些问题。我尝试了 File.ReadAllBytes,但这会导致打印机吐出乱码。在GenerateBufferFromFile 中是否需要进行一些特殊的编码?

** 更新 **

看起来直接使用 JobStream 存在很多问题:

PrintSystemJobInfo.JobStream 是否损坏?

所以我只是要写入文件,尽管我希望避免这种情况。