문제

저는 현재 Vista에서 다른 사용자로 프로세스를 실행하기 위해 자체 재배 방법을 사용하고 있으며, Hack-Dish and Indevin보다 덜 느낌을 피할 수 없습니다. 보안 예외가있는 앱과 UAC를 완전히 비활성화하도록 강요). 내 프로세스는 두 개의 프로젝트 (따라서 두 개의 EXE 파일) - "인터페이스"와 "런칭 스텁"로 구성되어 있으며 다음은 다음과 같습니다.

  1. 사용자는 "interface.exe notepad.exe"를 시작하는 바로 가기가 있습니다.
  2. Interface.exe는 사용하고 싶은 자격 증명을 요구하는 양식이 있습니다.
  3. interace.exe는 ProcessStartInfo를 사용하여 새로운 사용자로서 launchstub.exe (ls)의 인스턴스를 만듭니다.
  4. LS는 ProcessStartInfo (ShellexEcute가 True로 설정된)를 사용하여 요청 된 파일을 시작하고 이미 요청 된 사용자로 실행 중이므로 새 프로세스도 마찬가지입니다.

2 단계 프로세스가있는 이유는 사용자가 파일을 마우스 오른쪽 버튼으로 클릭 할 수 있기를 원하기 때문입니다. OS에는 (.exe, .sql, .msc 등)에 대한 기본 조치가 있고 그것을 시작하고 processStartinfo 만 "USESHELLEXECUTE"를 활성화하여 지원하지만 스위치로 인해 새로운 자격 증명을 사용하지 않으므로 한 번에 하나만 수행 할 수 있습니다.

이로 인해 몇 가지 문제가 발생합니다. 먼저 사용자는 컴퓨터에 이미 존재해야하므로 이전에 로컬로 기록해야합니다. 해당 사용자에 대한 로컬 프로필이없는 경우 요청 된 앱이 때때로 시작되지만 응용 프로그램은 아직 존재하지 않는 것이 존재하지 않는 것 (레지스트리의 HKCU Hive와 같이 사용자가하지 않는 레지스트리)이 있기 때문에 레지스트리 및 프로필 예외를 얻습니다. 로그인 한 적이 없기 때문에).

나는 그들이 요청하는 사용자에게 내 응용 프로그램의 권한을 "높이"할 수 있어야한다는 것을 알고 있으며, 새 프로세스를 시작한 다음 고도를 취소 할 수는 있지만 좋은 코드 샘플을 찾을 수는 없으며, 그에 대한 좋은 코드 샘플을 찾을 수는 없습니다. 완전히 다른 사용자로 실행할 수 있는지 확신 할 수 없습니다. 이것이 모두 의미가 있습니까? 나는 이것을하는 더 좋은 방법이 있다고 느끼는 것을 도울 수 없다.


업데이트: 방금 시도했습니다 일부 가장 한 사람 온라인으로 찾았지만 아무 소용이 없습니다. ProcessStartInfo와 함께 사용되면 제공된 자격 증명을 사용하여 가장 한 사람을 활성화했지만 현재 로그인이 아닌 현재 로그인을 사용하여 프로세스를 시작하는 것으로 보입니다.

도움이 되었습니까?

해결책

Win32 API를 사용하여 나만의 "쉘"기능을 만들어야 할 가능성이 있습니다.

CreateProcesswithLogonw API를 사용하면 다른 자격 증명에서 새 프로세스를 만들고 선택적으로 사용자 프로필 정보를로드 할 수 있습니다.

아래 코드 스 니펫에서 교체하면

  • 사용자 이름 - 사용자 이름과 함께
  • 도메인 - 도메인 또는 "vbnullstring"과 함께
  • 비밀번호 - 비밀번호로
  • 매개 변수 4- 지정된 사용자 프로필을로드하려면 0을 '프로파일로 로그온'으로 바꾸십시오.

문서를 참조하십시오 CreateProcesswithlogonw API 추가 세부 사항. 이 경로로 이동하면 애플리케이션을 시작하는 데 대한 완전한 제어력과 모든 책임이 있습니다.

다시 이것은 단지 샘플 일 뿐이며 원하는 것을하기 위해 조금 놀아야 할 수도 있습니다.


Imports System.Runtime.InteropServices

Public Module modShell

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

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

    Public Declare Unicode Function CreateProcessWithLogonW Lib "Advapi32" (ByVal lpUsername As String, ByVal lpDomain As String, ByVal lpPassword As String, ByVal dwLogonFlags As Int32, ByVal lpApplicationName As String, ByVal lpCommandLine As String, ByVal dwCreationFlags As Int32, ByVal lpEnvironment As IntPtr, ByVal lpCurrentDirectory As String, ByRef si As STARTUPINFO, ByRef pi As PROCESS_INFORMATION) As Integer
    Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As IntPtr) As Integer

    Public Const LOGON_WITH_PROFILE As Int32 = &H1

    Public Const NORMAL_PRIORITY_CLASS As Int32 = &H20&

    Public Const STARTF_USESHOWWINDOW As Int32 = &H1
    Public Const SW_HIDE As Int16 = 0
    Public Const SW_SHOW As Int16 = 5

    Public Function Shell(ByVal strCmdLine As String, ByVal strCurrentDirectory As String) As Boolean

        Dim pi As PROCESS_INFORMATION
        Dim si As New STARTUPINFO

        si.cb = Marshal.SizeOf(si)
        si.dwFlags = STARTF_USESHOWWINDOW
        si.wShowWindow = SW_SHOW

        Dim result As Integer = CreateProcessWithLogonW("username", "domain", "password", 0, vbNullString, strCmdLine, NORMAL_PRIORITY_CLASS, IntPtr.Zero, strCurrentDirectory, si, pi)

        If result <> 0 Then
            Call CloseHandle(pi.hThread)
            Call CloseHandle(pi.hProcess)
        Else
            Return False
        End If

        Return True

    End Function

End Module

다른 팁

앱에서 Runas를 실행하려고 할 수 있습니다. 몇 가지 예와 옵션 여기.

이 모듈을 시도하십시오.

Module Impersonation

#Region "API Structures"
    <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
#End Region

#Region "API Constants"
    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
#End Region

#Region "API Functions"
    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

#End Region

    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

End Module

runprogram ()을 사용하여 사용자/pw y 좋아요로 프로그램을 시작하십시오. 프로그램은 .exe만이 "Commandline"에 작성된 매개 변수를 의미합니다.

현재 실행중인 프로세스와 다른 자격 증명으로 응용 프로그램을 시작하려면 .NET를 사용할 수 있습니다. 프로세스 수업.

this.Process = new Process();

this.Process.StartInfo.Arguments = "Arguments";
this.Process.StartInfo.FileName = "C:\your.exe";
this.Process.StartInfo.UserName = "UserName";
string password = "some password";

this.Process.StartInfo.Password.Clear();
foreach (char c in password)
{
    this.Process.StartInfo.Password.AppendChar(c);
}


//allow the process to raise events
this.Process.EnableRaisingEvents = true;
this.Process.StartInfo.ErrorDialog = false;
//Method for handling the exit event
this.Process.Exited += new EventHandler(ApplicationProcess_Exited);

//Set the application directory as the current working directory
Environment.CurrentDirectory = System.IO.Directory.GetParent("C:\").ToString();

if (this.Process.Start())
{
    // Do something on start
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top