VB.NET 1.1 CreateProcesswithLogon API를 통한 TCPIP 프린터 포트 생성

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

  •  23-08-2019
  •  | 
  •  

문제

몇 달 전에 나는 약 100 개 이상의 프린터 그룹을 마이그레이션하기 위해 VB.NET 콘솔 애플리케이션을 작성하고 일부 이전 HP 인쇄 어플라이언스에서 혼합 인쇄 서버로, IP 인쇄 솔루션으로 직접 사용하는 1800 명 이상의 사용자를 마이그레이션했습니다. 이 응용 프로그램은 데이터베이스를 사용하여 설치된 프린터를 비교하고 이전/유효하지 않은 공유를 제거하고 새로운 Win2K3 기반 프린터 서버로 재발하거나 TCPIP 프린터 포트를 만들고 IP 인쇄에 직접 드라이버를 설치합니다.

실제로 잘 작동했지만 사용자는 TCPIP 프린터 포트를 만들기 위해 전원 사용자 권한이 필요했습니다. 메인 캠퍼스의 경우 이것은 문제가되지 않았지만 작은 원격 사이트에는 전원 사용자 권한이없는 사용자가 앱을 실행할 수있는 솔루션이 필요합니다.

내 솔루션은 "CreatePrinteripport"기능을 가져 와서 자체 래퍼 앱에 넣은 다음 목적을 위해 하드 코딩 된 로컬 관리자 계정을 사용하여 기본 앱에서 필요에 따라 호출하는 것이었지만 CreatePort를 생성 할 때 문제가 발생했습니다. 앱. 앱 독립형을 실행하면 문제가없는 포트를 생성하지만 테스트 앱에서 실행하면 CreateProcesswithLogon API를 사용하여 CreatePort를 스폰하여 "액세스 거부"오류로 포트 생성이 실패합니다. 2.0이 환경에 없어서 .NET 1.1을 사용하는 것으로 제한 되며이 앱에 대해서만 밀리지 않을 것이라고 들었습니다.

이견있는 사람?

아래에 나열된 소스.

산란 앱 :

Imports System.Runtime.InteropServices

모듈 모듈 1

지역 "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

끝 지역

영역 "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

끝 지역

지역 "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

끝 지역

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

TCPIP 포트 제작 앱에서 작동을 수행하고 위의 앱에서 스폰 될 때 실패합니다.

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

도움이 되었습니까?

해결책

WMI가 가장 한 계정에 대한 쓰기 액세스를 허용하지 않는 것 같습니다. 따라서 Prnadmin.dll을 사용하여 포트를 만들었습니다. 이를 위해서는 DLL이 등록되어 있는지 확인하고 그렇지 않은 경우 등록해야하지만 이것이 제가 찾을 수있는 유일한 방법 인 것 같습니다 (그리고 내 정신을 유지).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top