2013-04-16 48 views
6

我通過編程方式看到參考和提示,可以使用ManagementClass等將聯網的打印機添加到本地計算機。然而,我還沒有找到任何實際的教程來做到這一點。使用ManagementClass將打印機添加到本地計算機

有沒有人使用過ManagementClass來做到這一點?

我這樣做:

var connectionOption = new ConnectionOption(); 
var mgmScope = new ManagementScope("root\cimv2",connectionOptions); 

var printerClass = new ManagementClass(mgmScope, new ManagementPath("Win32_Printer"),null); 
var printerObj = printerClass.CreateInstance(); 

printerObj["DeviceID"] = prnName;  // 
printerObj["DriverName"] = drvName; // full path to driver 
printerObj["PortName"] = "myTestPort:"; 

var options = new PutOptions {Type = PutType.UpdateOrCreate}; 
printerObj.Put(options); 

這一切確實是創建一個錯誤「一般失敗」

我找不出我錯過了什麼.....任何幫助或想法這個將不勝感激。

我想我需要更好地解釋什麼,我試圖做...當需要的打印機不依賴於打印服務器,我需要: 創建TCPIP原始端口, 通過TCP連接打印機/ ip, 安裝驅動程序, 可選設置默認。

我希望WMI基本上能夠處理所有這些,但它似乎並不是這樣。

的感謝!

回答

1

爲了做到這一點,我最後不得不做了2步進...

首先建立一個命令行來火了:

rundll32.exe printui.dll,PrintUIEntry /if /b "test" /f x2DSPYP.inf /r 10.5.43.32 /m "845 PS" 

然後產卵它:

public static string ShellProcessCommandLine(string cmdLineArgs,string path) 
    { 
     var sb = new StringBuilder(); 
     var pSpawn = new Process 
     { 
      StartInfo = 
       { 
        WorkingDirectory = path, 
        FileName = "cmd.exe", 
        CreateNoWindow = true, 
        Arguments = cmdLineArgs, 
        RedirectStandardInput = true, 
        RedirectStandardOutput = true, 
        UseShellExecute = false 
       } 
     }; 
     pSpawn.OutputDataReceived += (sender, args) => sb.AppendLine(args.Data); 
     pSpawn.Start(); 
     pSpawn.BeginOutputReadLine(); 
     pSpawn.WaitForExit(); 

     return sb.ToString(); 
    } 

這似乎工作...不是理想的方法,但對於那些不在打印服務器上的打印機,它似乎可以完成這項工作。

9

WMI Win32_Printer類提供了一種方法,稱爲AddPrinterConnection至 將網絡打印機添加到本地打印機列表。 以下的代碼顯示瞭如何使用Win32_Printer類連接網絡打印機。

請注意,在某些情況下,AddPrinterConnection不能通過 來連接遠程打印機。在下面的例子中,我列出了最常見的錯誤案例 。

using (ManagementClass win32Printer = new ManagementClass("Win32_Printer")) 
{ 
    using (ManagementBaseObject inputParam = 
    win32Printer.GetMethodParameters("AddPrinterConnection")) 
    { 
    // Replace <server_name> and <printer_name> with the actual server and 
    // printer names. 
    inputParam.SetPropertyValue("Name", "\\\\<server_name>\\<printer_name>"); 

    using (ManagementBaseObject result = 
     (ManagementBaseObject)win32Printer.InvokeMethod("AddPrinterConnection", inputParam, null)) 
    { 
     uint errorCode = (uint)result.Properties["returnValue"].Value; 

     switch (errorCode) 
     { 
     case 0: 
      Console.Out.WriteLine("Successfully connected printer."); 
      break; 
     case 5: 
      Console.Out.WriteLine("Access Denied."); 
      break; 
     case 123: 
      Console.Out.WriteLine("The filename, directory name, or volume label syntax is incorrect."); 
      break; 
     case 1801: 
      Console.Out.WriteLine("Invalid Printer Name."); 
      break; 
     case 1930: 
      Console.Out.WriteLine("Incompatible Printer Driver."); 
      break; 
     case 3019: 
      Console.Out.WriteLine("The specified printer driver was not found on the system and needs to be downloaded."); 
      break; 
     } 
    } 
    } 
} 
+0

有些時候我不知道服務器名稱,只會有IP地址......這意味着它還需要有一種方法來安裝驅動程序。那種讓我難倒的東西。 – Kixoka

+0

@Kevin:您也可以使用IP而不是服務器名稱。只需用IP地址替換服務器名稱即可。上面的代碼也適用於IP地址。 – Hans

+0

好吧..會試試看,謝謝! :) – Kixoka

0

我在這個問題上花了差不多一週的時間!我的目標有點複雜,我想將C#代碼包裝在由SharePoint加載項調用的WCF服務中,並且此WCF服務應遠程調用客戶端來安裝打印機。因此我嘗試了WMI。 在平均時間,我設法使用RUNDLL32解決方案(這需要首先創建的端口),並且還做了PowerShell的變異,真正簡單:

$printerPort = "IP_"+ $printerIP 
$printerName = "Xerox WorkCentre 6605DN PCL6" 
Add-PrinterPort -Name $printerPort -PrinterHostAddress $printerIP 
Add-PrinterDriver -Name $printerName 
Add-Printer -Name $printerName -DriverName $printerName -PortName $printerPort 

真正棘手的部分是要知道的名字打印機,它應該匹配INF文件中的字符串!

但是回到C#解決方案:我創建了一個包含printerName,printerIP和managementScope的類作爲屬性。並且driverName = printerName

private string PrinterPortName 
    { 
     get { return "IP_" + printerIP; } 
    } 

    private void CreateManagementScope(string computerName) 
    { 
     var wmiConnectionOptions = new ConnectionOptions(); 
     wmiConnectionOptions.Impersonation = ImpersonationLevel.Impersonate; 
     wmiConnectionOptions.Authentication = AuthenticationLevel.Default; 
     wmiConnectionOptions.EnablePrivileges = true; // required to load/install the driver. 
     // Supposed equivalent to VBScript objWMIService.Security_.Privileges.AddAsString "SeLoadDriverPrivilege", True 

     string path = "\\\\" + computerName + "\\root\\cimv2"; 
     managementScope = new ManagementScope(path, wmiConnectionOptions); 
     managementScope.Connect(); 
    } 

    private bool CheckPrinterPort() 
    { 
     //Query system for Operating System information 
     ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_TCPIPPrinterPort"); 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher(managementScope, query); 

     ManagementObjectCollection queryCollection = searcher.Get(); 
     foreach (ManagementObject m in queryCollection) 
     { 
      if (m["Name"].ToString() == PrinterPortName) 
       return true; 
     } 
     return false; 
    } 

    private bool CreatePrinterPort() 
    { 
     if (CheckPrinterPort()) 
      return true; 

     var printerPortClass = new ManagementClass(managementScope, new ManagementPath("Win32_TCPIPPrinterPort"), new ObjectGetOptions()); 
     printerPortClass.Get(); 
     var newPrinterPort = printerPortClass.CreateInstance(); 
     newPrinterPort.SetPropertyValue("Name", PrinterPortName); 
     newPrinterPort.SetPropertyValue("Protocol", 1); 
     newPrinterPort.SetPropertyValue("HostAddress", printerIP); 
     newPrinterPort.SetPropertyValue("PortNumber", 9100); // default=9100 
     newPrinterPort.SetPropertyValue("SNMPEnabled", false); // true? 
     newPrinterPort.Put(); 
     return true; 
    } 

    private bool CreatePrinterDriver(string printerDriverFolderPath) 
    { 
     var endResult = false; 
     // Inspired from https://msdn.microsoft.com/en-us/library/aa384771%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 
     // and http://microsoft.public.win32.programmer.wmi.narkive.com/y5GB15iF/adding-printer-driver-using-system-management 
     string printerDriverInfPath = IOUtils.FindInfFile(printerDriverFolderPath); 
     var printerDriverClass = new ManagementClass(managementScope, new ManagementPath("Win32_PrinterDriver"), new ObjectGetOptions());    
     var printerDriver = printerDriverClass.CreateInstance(); 
     printerDriver.SetPropertyValue("Name", driverName); 
     printerDriver.SetPropertyValue("FilePath", printerDriverFolderPath); 
     printerDriver.SetPropertyValue("InfName", printerDriverInfPath); 

     // Obtain in-parameters for the method 
     using (ManagementBaseObject inParams = printerDriverClass.GetMethodParameters("AddPrinterDriver")) 
     { 
      inParams["DriverInfo"] = printerDriver; 
      // Execute the method and obtain the return values.    

      using (ManagementBaseObject result = printerDriverClass.InvokeMethod("AddPrinterDriver", inParams, null)) 
      { 
       // result["ReturnValue"] 
       uint errorCode = (uint)result.Properties["ReturnValue"].Value; // or directly result["ReturnValue"] 
       // https://msdn.microsoft.com/en-us/library/windows/desktop/ms681386(v=vs.85).aspx 
       switch (errorCode) 
       { 
        case 0: 
         //Trace.TraceInformation("Successfully connected printer."); 
         endResult = true; 
         break; 
        case 5: 
         Trace.TraceError("Access Denied."); 
         break; 
        case 123: 
         Trace.TraceError("The filename, directory name, or volume label syntax is incorrect."); 
         break; 
        case 1801: 
         Trace.TraceError("Invalid Printer Name."); 
         break; 
        case 1930: 
         Trace.TraceError("Incompatible Printer Driver."); 
         break; 
        case 3019: 
         Trace.TraceError("The specified printer driver was not found on the system and needs to be downloaded."); 
         break; 
       } 
      } 
     } 
     return endResult; 
    } 

    private bool CreatePrinter() 
    { 
     var printerClass = new ManagementClass(managementScope, new ManagementPath("Win32_Printer"), new ObjectGetOptions()); 
     printerClass.Get(); 
     var printer = printerClass.CreateInstance(); 
     printer.SetPropertyValue("DriverName", driverName); 
     printer.SetPropertyValue("PortName", PrinterPortName); 
     printer.SetPropertyValue("Name", printerName); 
     printer.SetPropertyValue("DeviceID", printerName); 
     printer.SetPropertyValue("Location", "Front Office"); 
     printer.SetPropertyValue("Network", true); 
     printer.SetPropertyValue("Shared", false); 
     printer.Put(); 
     return true; 
    } 


    private void InstallPrinterWMI(string printerDriverPath) 
    { 
     bool printePortCreated = false, printeDriverCreated = false, printeCreated = false; 
     try 
     {     
      printePortCreated = CreatePrinterPort(); 
      printeDriverCreated = CreatePrinterDriver(printerDriverPath); 
      printeCreated = CreatePrinter(); 
     } 
     catch (ManagementException err) 
     { 
      if (printePortCreated) 
      { 
       // RemovePort 
      } 
      Console.WriteLine("An error occurred while trying to execute the WMI method: " + err.Message); 
     } 
    } 

終於安裝了驅動程序。如果它在乾淨的Windows上工作,我仍然需要進一步的測試。在我的測試過程中,驅動程序有很多安裝/卸載的問題

相關問題