2013-04-16 10 views
6

Vedo riferimenti e suggerimenti che a livello di programmazione si può aggiungere una stampante di rete a un computer locale utilizzando ManagementClass e così via. Tuttavia non sono stato in grado di trovare alcun tutorial effettivo su come fare proprio questo.aggiungere la stampante al computer locale con ManagementClass

qualcuno ha effettivamente utilizzato ManagementClass per eseguire questa operazione?

sto facendo questo:

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); 

Tutto questo non fa altro che creare un errore "Errore generico"

Non riesco a capire che cosa manco ..... qualsiasi aiuto o pensieri su questo sarebbe apprezzato.

Penso di aver bisogno di spiegare meglio quello che sto cercando di fare ... quando le stampanti necessarie non sono legate a un server di stampa, ho bisogno di: creare una porta grezzo tcpip, collegare una stampante tramite TCP/ip, installa driver, opzionalmente impostato come predefinito.

Speravo che WMI potesse occuparsi di tutto questo ma non sembra essere il caso.

grazie!

risposta

1

Per fare questo ho finito per dover fare un passo-passo 2 ...

prima costruire una riga di comando per sparare:

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

Poi uova esso:

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(); 
    } 

Questo sembra funzionare ... non è il metodo ideale, ma per le stampanti non su un server di stampa sembra di fare il lavoro.

9

La classe WMI Win32_Printer fornisce un metodo chiamato AddPrinterConnection a aggiungere una stampante di rete all'elenco delle stampanti locali. Il codice sottostante mostra come collegare una stampante di rete utilizzando la classe Win32_Printer.

Si prega di notare che, in determinate condizioni, lo AddPrinterConnection non riesce a collegare per la stampante remota. Nell'esempio seguente ho elencato il maggior numero di casi di errore comuni .

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

Ci saranno dei momenti in cui non conosco il nomeserver e avrò solo l'indirizzo IP ... Ciò significa che dovrà anche avere un modo per installare il conducente. Un po 'mi lascia perplesso. – Kixoka

+0

@ Kevin: è anche possibile utilizzare l'IP al posto del nome del server. Basta sostituire il nome del server con l'indirizzo IP. Il codice sopra funziona anche con un indirizzo IP. – Hans

+0

ok .. ci provo grazie! :) – Kixoka

0

Ho trascorso quasi una settimana su questo argomento! Il mio obiettivo è un po 'più complicato, voglio racchiudere il codice C# in un servizio WCF chiamato da un componente aggiuntivo di SharePoint, e questo servizio WCF dovrebbe chiamare in remoto il client per installare le stampanti. Così ho provato con WMI. Nel frattempo, sono riuscito a usare rundll32 soluzione (che richiede in primo luogo per creare la porta), e ha fatto anche una variante powershell, davvero il più semplice:

$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 

La parte veramente difficile è quello di conoscere il nome del la stampante, dovrebbe corrispondere alla stringa nel file INF!

Ma torniamo alla soluzione C#: ho creato una classe con printerName, printerIP e managementScope come attributi.E 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); 
     } 
    } 

installare infine il driver. Ho ancora bisogno di ulteriori test se funziona su un Windows pulito. Sono stati installati/disinstallati molti driver durante i miei test

Problemi correlati