0

プリンタードライバーをインストールし、そのドライバーを使用してプリンターを作成する実行可能ファイルがあります。サーバー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は、SYSTEMユーザーとしてカスタムアクション(コンソールアプリ)プロセスを起動します。手動で起動すると、ドメイン管理者アカウントで実行されます。

また、xpはINFファイルからプロセッサを取得するため、プリンタを手動でインストールしても問題なく動作することにも注意してください。prnadmin dllを使用する場合、その設定は無視されます。

とてもイライラする朝を過ごしました。何かご意見は?または、プリンタをインストールするためのより良い方法はありますか?

4

1 に答える 1

0

さて、その特定のケースでなぜ失敗したのかはわかりませんでしたが、私ははるかに優れた回避策を見つけました。誰かが私の元の質問に答えることができれば、私はあなたに答えを与えます。

背景:ポートを作成する必要があり、それが最も簡単な方法であると思われたため、prnadminラッパーを使用してすべてを実行することを選択しました。

マネージコードを使用してプリンターを作成する代わりに、PrintUIにコマンドをシェルアウトするようになりました。PrintUIを使用してポートを設定すると、Windows XPはPrintUIを使用するときにINFファイルで指定されたプロセッサを取得するため、1つの石で2羽の鳥を殺します。

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();
  }
}
于 2012-05-16T22:32:20.837 に答える