2012-05-16 19 views
0

我有一個安裝打印機驅動程序的可執行文件,然後使用該驅動程序創建打印機。我使用服務器2003資源工具包中的tlbimp生成的prnadmin託管版本。當以SYSTEM身份運行時,prnadminlib無法在winxp上設置處理器,在域用戶時工作

在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時會忽略該設置。

我已經有一個非常沮喪的早晨。有什麼想法嗎?或更好的方式來安裝打印機?

+0

我在計算出PrintUI.dll是否可以使用,在這方面的任何提示將不勝感激。由於這個怪癖,「受管理」代碼版本無法使用真的讓人感到不安。 – scaryman

回答

0

好的,從來沒有想過爲什麼它在這個特定的情況下失敗了,但我確實找出了一個更好的工作。如果有人能回答我原來的問題,我會給你答案。

背景:我們選擇使用prnadmin包裝來做所有事情,因爲我們必須創建一個端口,而且這似乎是最簡單的方法。

除了使用託管代碼創建打印機外,我們現在還向PrintUI輸出命令。我們可以使用PrintUI設置端口,當使用PrintUI時,Windows XP將選取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(); 
    } 
} 
相關問題