7

Tôi hiện đang sử dụng phương pháp phát triển nội bộ để chạy quy trình với tư cách người dùng khác trong Vista và tôi không thể thoát khỏi cảm giác đó là hack-ish và ít hơn lý tưởng (ngoài thực tế là nó khao khát UAC, làm hỏng ứng dụng của tôi với một ngoại lệ bảo mật và buộc tôi phải tắt hoàn toàn UAC). quá trình của tôi bao gồm hai dự án (do hai tập tin EXE) - một "giao diện" và một "ra mắt còn sơ khai" - và đây là quá trình:Chạy quy trình mới với tư cách người dùng khác trong vb.net

  1. Người dùng có một phím tắt mà ra mắt "Interface.exe notepad.exe"
  2. Interface.exe có một hình thức mà yêu cầu các thông tin mà họ muốn sử dụng
  3. Interace.exe sử dụng ProcessStartInfo để tạo ra một thể hiện của LaunchStub.exe (LS) như là người dùng mới
  4. LS sử dụng ProcessStartInfo (với ShellExecute được đặt thành true) để khởi chạy tệp được yêu cầu và vì nó đã chạy như người dùng được yêu cầu, do đó, là quy trình mới.

Lý do tôi có quy trình gồm hai bước là tôi muốn người dùng có thể nhấp chuột phải vào bất kỳ tệp nào mà hệ điều hành có hành động mặc định cho (.EXE, .SQL, .MSC, v.v ...) khởi động nó, và ProcessStartInfo chỉ hỗ trợ rằng với "UseShellExecute" được kích hoạt, nhưng chuyển đổi đó ngăn cản tôi sử dụng thông tin đăng nhập mới, vì vậy tôi chỉ có thể làm một tại một thời điểm.

Điều này gây ra một số vấn đề - đầu tiên, người dùng phải đã tồn tại trên máy tính, nghĩa là họ phải đăng nhập cục bộ trước đó. Nếu không có hồ sơ cục bộ cho người dùng đó, ứng dụng được yêu cầu đôi khi sẽ khởi chạy, nhưng tôi nhận được đăng ký và ngoại lệ hồ sơ vì ứng dụng mong đợi mọi thứ tồn tại mà chưa (như HKCU hive trong sổ đăng ký mà người dùng không vì họ chưa bao giờ đăng nhập).

Tôi biết tôi có thể chỉ "Nâng cao" quyền của ứng dụng cho người dùng mà họ đang yêu cầu, khởi chạy quy trình mới của tôi và sau đó hoàn tác độ cao, nhưng tôi không thể tìm thấy mẫu mã tốt cho điều đó, và tôi không chắc rằng nó sẽ cho phép chạy như một người dùng hoàn toàn khác. Tất cả điều này có hợp lý không? Tôi không thể không cảm thấy như có một cách tốt hơn để làm điều này.


UPDATE: Tôi chỉ cố gắng some Impersonation code tôi tìm thấy trên mạng, nhưng không có kết quả. Khi được sử dụng kết hợp với ProcessStartInfo, nó vẫn có vẻ như khởi chạy các tiến trình bằng cách sử dụng thông tin đăng nhập hiện tại của tôi, không phải là quy trình mà tôi đã cung cấp, mặc dù tôi đã kích hoạt mạo danh bằng các thông tin được cung cấp.

Trả lời

3

Rất có thể bạn phải tạo chức năng "vỏ" của riêng mình bằng cách sử dụng API Win32.

Sử dụng API CreateProcessWithLogonW, bạn có thể tạo quy trình mới theo thông tin đăng nhập khác nhau và tùy chọn tải thông tin hồ sơ người dùng.

Trong đoạn mã dưới đây nếu bạn thay thế

  • tên người dùng - với tên đăng nhập
  • miền - với tên miền của bạn hoặc "vbNullString"
  • mật khẩu - với mật khẩu của bạn
  • tham số 4 - thay thế 0 với 'LOGON WITH PROFILE' để tải hồ sơ người dùng được chỉ định.

Xem tài liệu cho số CreateProcessWithLogonW API để biết thêm chi tiết cụ thể. Đi tuyến đường này bạn có toàn quyền kiểm soát và chịu trách nhiệm hoàn toàn về việc khởi chạy ứng dụng.

Một lần nữa đây chỉ là một mẫu và bạn có thể phải chơi với nó một chút để làm cho nó làm những gì bạn muốn.


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 

+0

Tôi sẽ thử tính năng này và xem điều gì sẽ xảy ra. Nếu tôi có thể làm điều đó mà không cần phải sử dụng một EXE thứ hai như là một bài sơ khai, tôi sẽ hạnh phúc, và thậm chí nhiều hơn như vậy nếu nó không crap ra khi UAC được kích hoạt (tôi sẽ đối phó với một dấu nhắc). Tôi sẽ được bakc sau khi tôi đã thử nó. – SqlRyan

+0

@SqlRyan và đã làm việc với UAC kích hoạt ?? – Jet

1

Bạn có thể thử chạy runas từ ứng dụng của mình. Một số ví dụ và tùy chọn here.

0

Hãy thử Module này:

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 

Sử dụng Runprogram() Để bắt đầu chương trình của bạn với user/pw y muốn. Programm có nghĩa là chỉ .exe, tham số ar được viết thành "commandline"

+0

Mô-đun này khác với mô-đun được đăng trước đó như thế nào? Tôi thành thật hỏi - nó trông khá giống nhau, vì vậy tôi chỉ muốn chắc chắn rằng tôi không thiếu một cái gì đó hiển nhiên mà sẽ làm cho rõ ràng hơn. Tôi chưa chấp nhận câu trả lời, nhưng mã trước đó đã làm việc cho tôi cho đến bây giờ. – SqlRyan

+0

có nó rất giống, chỉ có một hàm thứ hai được viết làm tròn apifunktion CreateProcessWithLogonW API - ready_to_use với errorhandling và successfeedback ... – DrFuture

0

Nếu bạn muốn bắt đầu ứng dụng có thông tin xác thực khác với quy trình đang chạy, bạn có thể sử dụng lớp .Net Quy trình.

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 
} 
Các vấn đề liên quan