prnadminlib 在作为系统运行时无法在 winxp 上设置处理器,在域用户运行时工作

本文关键字:运行时 设置 处理器 工作 用户 系统 prnadminlib winxp | 更新日期: 2023-09-27 18:34:35

我有一个可执行文件,它安装打印机驱动程序,然后使用该驱动程序创建打印机。我使用来自服务器 2003 资源工具包的 tlbimp 生成的 prnadmin 托管版本。

在Windows XP上,我必须将打印处理器设置为MS_XPS。默认处理器为 WINPRINT。这个片段就是这样做的。

  static string winxpPrinterProcessor = "MS_XPS";
  if (isWinXP() && pPrinter.PrintProcessor != winxpPrinterProcessor)
  {
    Console.WriteLine("Oh No, the printer exists, but the processor isn't XPS. Setting now. It's currently " + pPrinter.PrintProcessor);
    pPrinter.PrintProcessor = winxpPrinterProcessor;
    Console.WriteLine("Set the processor to " + winxpPrinterProcessor);
    if (updateOnly)
    {
      pMaster.PrinterSet(pPrinter);
    } else { //else we're adding
      pMaster.PrinterAdd(pPrinter);
    }

自己运行程序时,双击即可完美运行。将其作为 MSI 自定义操作运行时,它不起作用。一切正常(安装打印机,驱动程序,设置端口(,但设置打印处理器。 Windows只是忽略处理器设置。

MSI 以系统用户身份启动自定义操作(它是一个控制台应用(进程。当我手动启动它时,它在我的域管理员帐户下运行。

我还应该注意,手动安装打印机也可以正常工作,因为 xp 从 INF 文件中获取处理器。使用 prnadmin dll 时,它会忽略该设置。

我度过了一个非常令人沮丧的早晨。有什么想法吗?或者更好的打印机安装方法?

prnadminlib 在作为系统运行时无法在 winxp 上设置处理器,在域用户运行时工作

好吧,从来没有弄清楚为什么它在那种特定情况下失败了,但我确实想出了一个更好的解决方法。如果有人能回答我原来的问题,我会给你答案。

背景:我们选择使用 prnadmin 包装器做所有事情,因为我们必须创建一个端口,这似乎是最简单的方法。

我们现在不再使用托管代码创建打印机,而是将命令外包给 PrintUI。我们可以用 PrintUI 设置端口,Windows XP 会在使用 PrintUI 时拾取 INF 文件中指定的处理器,因此它一石二鸟。

public static string PrinterDriverName = "MyPrinter.INF";
public static string portOutputFileName = "nul:";
/// <summary>
/// Installs a printer and driver from an INF file, setting the 
/// port to portOutputFileName ('nul:' in this case)
/// </summary>
private static void CreatePrinterPrintUI()
{
  string sCommand = String.Format(@"rundll32 printui,PrintUIEntry /if /K /m '{0}' /n '{0}' /r '{2}' /f '{1}'"
    ,PrinterDriverName,Path.Combine(Application.StartupPath,PrinterDriverInf)
    ,portOutputFileName).Replace("'","'""); //it fails on single quotes
  execCmd(sCommand);
}
public static void execCmd(string _sCmd)
{
  try
  {
    System.Diagnostics.ProcessStartInfo p = new ProcessStartInfo("cmd", "/c " + _sCmd);
    p.RedirectStandardOutput = true;
    p.UseShellExecute = false;
    p.CreateNoWindow = true;
    System.Diagnostics.Process proc = new System.Diagnostics.Process();
    proc.StartInfo = p;
    proc.Start();
    string sResult = proc.StandardOutput.ReadToEnd();
    Console.WriteLine(sResult);
  }
  catch (Exception e)
  {
    sErr += e.ToString();
  }
}