Création de port d'imprimante TCPIP VB.net 1.1 avec l'API CreateProcessWithLogon

StackOverflow https://stackoverflow.com/questions/900104

  •  23-08-2019
  •  | 
  •  

Question

Il y a quelques mois, j'ai écrit une application console VB.net pour migrer un groupe d'environ 100+ imprimantes et les 1800+ utilisateurs qui les utilisent de certains anciens appareils d'impression HP vers un serveur d'impression mixte et des solutions d'impression directe vers IP.L'application utilise une base de données pour comparer les imprimantes installées, supprimer les partages anciens/invalides et remapper le nouveau serveur d'impression basé sur Win2K3 OU créer un port d'imprimante TCPIP et installer le pilote pour l'impression directe sur IP.

Cela a très bien fonctionné, mais les utilisateurs avaient besoin de droits d'utilisateur expérimentés pour créer le port d'imprimante TCPIP.Pour le campus principal, cela ne posait pas de problème, mais les sites distants plus petits ont besoin d'une solution permettant à l'application d'être exécutée par des utilisateurs sans droits d'utilisateur expérimenté.

Ma solution consistait à prendre la fonction "CreatePrinterIPPort" et à la placer dans sa propre application wrapper, puis à l'appeler si nécessaire à partir de l'application principale en utilisant un compte d'administrateur local codé en dur à cet effet, mais je rencontre des problèmes lors de la création du createport. application.Si j'exécute l'application de manière autonome, elle crée le port sans problème, mais lorsque je l'exécute dans mon application de test pour générer le createport à l'aide de l'API CreateProcessWithLogon, la création du port échoue avec une erreur "accès refusé".Je suis limité à l'utilisation de .net 1.1 car la version 2.0 n'est pas complètement présente dans notre environnement et on m'a dit qu'elle ne serait pas poussée uniquement pour cette application.

Des pensées?

Source indiquée ci-dessous.

Application de génération :

Imports System.Runtime.InteropServices

ModuleModule1

Région "Structures API"

<StructLayout(LayoutKind.Sequential)> _
  Public Structure PROCESS_INFORMATION
    Dim hProcess As System.IntPtr
    Dim hThread As System.IntPtr
    Dim dwProcessId As Integer
    Dim dwThreadId As Integer
End Structure

<StructLayout(LayoutKind.Sequential)> _
 Public Structure STARTUPINFO
    Dim cb As Integer
    Dim lpReserved As System.IntPtr
    Dim lpDesktop As System.IntPtr
    Dim lpTitle As System.IntPtr
    Dim dwX As Integer
    Dim dwY As Integer
    Dim dwXSize As Integer
    Dim dwYSize As Integer
    Dim dwXCountChars As Integer
    Dim dwYCountChars As Integer
    Dim dwFillAttribute As Integer
    Dim dwFlags As Integer
    Dim wShowWindow As Short
    Dim cbReserved2 As Short
    Dim lpReserved2 As System.IntPtr
    Dim hStdInput As System.IntPtr
    Dim hStdOutput As System.IntPtr
    Dim hStdError As System.IntPtr
End Structure

Région de fin

Région "Constantes API"

Private Const LOGON_NETCREDENTIALS_ONLY As Integer = &H2
Private Const NORMAL_PRIORITY_CLASS As Integer = &H20
Private Const CREATE_DEFAULT_ERROR_MODE As Integer = &H4000000
Private Const CREATE_NEW_CONSOLE As Integer = &H10
Private Const CREATE_NEW_PROCESS_GROUP As Integer = &H200
Private Const LOGON_WITH_PROFILE As Integer = &H1

Région de fin

Région "Fonctions API"

Private Declare Unicode Function CreateProcessWithLogon Lib "Advapi32" Alias "CreateProcessWithLogonW" _
    (ByVal lpUsername As String, _
     ByVal lpDomain As String, _
     ByVal lpPassword As String, _
     ByVal dwLogonFlags As Integer, _
     ByVal lpApplicationName As String, _
     ByVal lpCommandLine As String, _
     ByVal dwCreationFlags As Integer, _
     ByVal lpEnvironment As System.IntPtr, _
     ByVal lpCurrentDirectory As System.IntPtr, _
     ByRef lpStartupInfo As STARTUPINFO, _
     ByRef lpProcessInfo As PROCESS_INFORMATION) As Integer

Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As System.IntPtr) As Integer

Région de fin

Public Sub RunProgram(ByVal UserName As String, ByVal Password As String, ByVal Domain As String, ByVal Application As String, ByVal CommandLine As String)

    Dim siStartup As STARTUPINFO
    Dim piProcess As PROCESS_INFORMATION
    Dim intReturn As Integer

    If CommandLine Is Nothing OrElse CommandLine = "" Then CommandLine = String.Empty

    siStartup.cb = Marshal.SizeOf(siStartup)
    siStartup.dwFlags = 0

    intReturn = CreateProcessWithLogon(UserName, Domain, Password, LOGON_WITH_PROFILE, Application, CommandLine, _
    NORMAL_PRIORITY_CLASS Or CREATE_DEFAULT_ERROR_MODE Or CREATE_NEW_CONSOLE Or CREATE_NEW_PROCESS_GROUP, _
    IntPtr.Zero, IntPtr.Zero, siStartup, piProcess)

    If intReturn = 0 Then
        Throw New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
    End If

    CloseHandle(piProcess.hProcess)
    CloseHandle(piProcess.hThread)

End Sub

Overloads Sub Main(ByVal args() As String)
    Dim command As String = "C:\Program Files\Printer Server Update Utility\CreatePrinterPort.exe"
    Dim arguments As String = Chr(34) & "C:\Program Files\Printer Server Update Utility\CreatePrinterPort.exe" & Chr(34) & " /I:138.90.1.3"
    Dim user As String = "PrintAdmin" 
    Dim domain As String = System.Environment.MachineName
    Dim password As String = "Pa$$word" '<---- No not really
    Dim currentDirectory As String = System.IO.Directory.GetCurrentDirectory()

    RunProgram(user, password, domain, command, arguments)
    System.Console.WriteLine("Please press the ENTER key to close window.")
    System.Console.WriteLine("")
    System.Console.Read()
End Sub

End Module

Fonction dans l'application de création de port TCPIP qui effectue le travail et échoue lorsqu'elle est générée dans l'application ci-dessus.

Function CreatePrinterIPPort(ByVal strPrinterIPAddress As String, Optional ByVal Protocol As Short = 1, Optional ByVal QueueName As String = "Dummy", _ Optional ByVal ByteCount As Boolean = False) As Boolean ' Protocal 1 = RAW (Default) 2 = LPR System.Console.WriteLine("Attempting to create port at IP Address: " & strPrinterIPAddress) Dim options As New ConnectionOptions options.Impersonation = ImpersonationLevel.Impersonate Dim mpBasePath As New ManagementPath("\.\ROOT\CIMV2") Dim mpTCPIPPort As New ManagementPath("Win32_TCPIPPrinterPort") Dim msLocalMachine As New ManagementScope(mpBasePath, options) msLocalMachine.Connect() Dim mcNetworkPorts As New ManagementClass(msLocalMachine, mpTCPIPPort, New ObjectGetOptions) Dim moNewPort As ManagementObject = mcNetworkPorts.CreateInstance() moNewPort.Properties("Name").Value = "IP_" & strPrinterIPAddress moNewPort.Properties("Protocol").Value = Protocol moNewPort.Properties("HostAddress").Value = strPrinterIPAddress If Protocol = 1 Then moNewPort.Properties("PortNumber").Value = "9100" ElseIf Protocol = 2 Then moNewPort.Properties("ByteCount").Value = ByteCount moNewPort.Properties("Queue").Value = QueueName End If

    Try
        moNewPort.Put()
    Catch ex As Exception
        System.Console.WriteLine("Port creation failed.")
        System.Console.WriteLine(ex.Message.ToString)
        Return False
    End Try
    System.Console.WriteLine("Created port at IP Address: " & strPrinterIPAddress)
    Return True
End Function

Était-ce utile?

La solution

Il semble que WMI n'autorise pas l'accès en écriture à un compte usurpé, j'ai donc commencé à utiliser prnadmin.dll pour créer des ports.Cela m'oblige à vérifier que la DLL est enregistrée et à l'enregistrer si ce n'est pas le cas, mais il semble que ce soit le seul moyen que je puisse trouver (et garder la raison) pour y parvenir.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top