Tạo macro mở phần mềm với tài khoản Administrator

Liên hệ QC
Tôi tuân thủ nội quy khi đăng bài

test1986

Thành viên mới
Tham gia
19/10/22
Bài viết
15
Được thích
4
Em chào các anh chị đang hoạt động trên diễn đàn
Em đang có đoạn code để gọi phần mềm như sau:

Public Sub OpenSOFTZALO()
Dim sZALO As String
sZALO = "C:\Users\Tuan IT\AppData\Local\Programs\Zalo\Zalo.exe"
Shell sZALO
End Sub

Máy tính em đang sử dụng đang có hai tài khoản gồm:
+ Tài khoản user thông thường
+ Tài khoản administrator
Khi tạo nút gọi macro này thì có thể gọi phần mềm hoạt động được ngay trên tài khoản user, nhưng có một số phần mềm chỉ hoạt động tốt khi run as Administrator và nhập password Administrator.
Rất mong được mọi người hướng dẫn em cách gọi phần mềm và tự động chèn username và password của tài khoản Administrator trong code luôn được không ạ? ( tài khoản Administrator em đang quản lý nên em muốn thêm vào trong câu lệnh luôn để không phải thực hiện thao tác nhập username/password mỗi lần gọi phần mềm)
Em xin cảm ơn ạ.
 
Ngày trước tôi có sử dụng code trên (nguồn trên diễn đàn - cảm ơn tác giả)
Mã:
                                                                                                                            Private Const LOGON_WITH_PROFILE As Long = &H1
Private Const LOGON_NETCREDENTIALS_ONLY = &H2
Private Const LOGON32_LOGON_INTERACTIVE = 2
Private Const LOGON32_PROVIDER_DEFAULT = 0
Private Const INFINITE As Long = &HFFFFFFFF

Private Type STARTUPINFOW
    cb As Long
    lpReserved As Long
    lpDesktop As Long
    lpTitle As Long
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Byte
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadId As Long
End Type

Private Declare Function CreateProcessWithLogonW Lib "advapi32" (ByVal UserName As String, _
ByVal Domain As String, ByVal Password As String, ByVal dwLogonFlags As Long, _
ByVal ApplicationName As String, ByVal strCommandLine As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal strCurrentDirectory As Long, ByRef lpStartupInfo As STARTUPINFOW, _
ByRef lppiProcessInfo As PROCESS_INFORMATION) As Long

Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
            (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
            ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
            
Private Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
          
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long

Public Function RunAsUser(ByVal UserName As String, ByVal Password As String, _
    ByVal DomainName As String, AppName As String, Optional ByVal Wait As Boolean = False) As Long

    Dim si As STARTUPINFOW
    Dim pi As PROCESS_INFORMATION
    
    Dim wUser As String
    Dim wDomain As String
    Dim wPassword As String
    Dim wAppName As String
    Dim Result As Long
    
    si.cb = Len(si)
    wUser = StrConv(UserName & Chr(0), vbUnicode)
    wDomain = StrConv(DomainName & Chr(0), vbUnicode)
    wPassword = StrConv(Password & Chr(0), vbUnicode)
    wAppName = StrConv(AppName & Chr(0), vbUnicode)
    
    Result = CreateProcessWithLogonW(wUser, wDomain, wPassword, _
          LOGON_WITH_PROFILE, wAppName, 0, 0, 0, 0, si, pi)
    If Result <> 0 Then '        thanh cong
'        neu Wait  TRUE thi code dung o dong WaitForSingleObject cho toi khi process cua wAppName ket thuc
'        sau do moi chay tiep code CloseHandle pi.hThread
        If Wait Then WaitForSingleObject pi.hProcess, INFINITE
        CloseHandle pi.hThread
        CloseHandle pi.hProcess
        RunAsUser = 0
    Else
'        that bai
        RunAsUser = Err.LastDllError
        MsgBox "CreateProcessWithLogonW that bai " & Err.LastDllError, vbExclamation
    End If

End Function

Cấu trúc câu lệnh
RunAsUser "username có quyền admin", "password", "Domain", "Đường dẫn đến file zalo.exe"
 
Upvote 0
Mã trên ở quá khứ thì sử dụng được, hiện tại cần phải đưa chúng về dạng mã tương thích.

JavaScript:
Option Explicit
#If VBA7 = 0 Then
  Private Enum LongPtr: [_]: End Enum
#End If

Private Const LOGON_WITH_PROFILE As Long = &H1
Private Const LOGON_NETCREDENTIALS_ONLY = &H2
Private Const LOGON32_LOGON_INTERACTIVE = 2
Private Const LOGON32_PROVIDER_DEFAULT = 0
Private Const INFINITE As Long = &HFFFFFFFF

Private Type STARTUPINFOW
    cb As Long
    lpReserved As LongPtr
    lpDesktop As LongPtr
    lpTitle As LongPtr
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Byte
    hStdInput As LongPtr
    hStdOutput As LongPtr
    hStdError As LongPtr
End Type

Private Type PROCESS_INFORMATION
    hProcess As LongPtr
    hThread As LongPtr
    dwProcessId As Long
    dwThreadId As Long
End Type

#If VBA7 Then
Private Declare PtrSafe Function CreateProcessWithLogonW Lib "advapi32" (ByVal UserName As LongPtr, _
ByVal Domain As LongPtr, ByVal Password As LongPtr, ByVal dwLogonFlags As Long, _
ByVal ApplicationName As LongPtr, ByVal strCommandLine As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As LongPtr, ByVal strCurrentDirectory As LongPtr, ByVal lpStartupInfo As LongPtr, _
ByVal lppiProcessInfo As LongPtr) As Long
Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
            (ByVal hwnd As LongPtr, ByVal lpOperation As String, ByVal lpFile As String, _
            ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare PtrSafe Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As LongPtr, ByVal dwMilliseconds As Long) As Long
Private Declare PtrSafe Function CloseHandle Lib "kernel32.dll" (ByVal hObject As LongPtr) As Long
#Else
Private Declare Function CreateProcessWithLogonW Lib "advapi32" (ByVal UserName As Long, _
ByVal Domain As Long, ByVal Password As Long, ByVal dwLogonFlags As Long, _
ByVal ApplicationName As Long, ByVal strCommandLine As Long, ByVal dwCreationFlags As Long, _
ByVal lpEnvironment As Long, ByVal strCurrentDirectory As Long, ByVal lpStartupInfo As Long, _
ByVal lppiProcessInfo As Long) As Long
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" _
            (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, _
            ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare Function WaitForSingleObject Lib "kernel32.dll" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
#End If


Public Function RunAsUser(ByVal UserName As String, ByVal Password As String, _
    ByVal DomainName As String, AppName As String, Optional ByVal Wait As Boolean = False) As Long

    Dim si As STARTUPINFOW
    Dim pi As PROCESS_INFORMATION
    
    Dim wUser As LongPtr
    Dim wDomain As LongPtr
    Dim wPassword As LongPtr
    Dim wAppName As LongPtr
    Dim Result As Long
    
    si.cb = Len(si)
    wUser = StrPtr(UserName & Chr(0))
    wDomain = StrPtr(DomainName & Chr(0))
    wPassword = StrPtr(Password & Chr(0))
    wAppName = StrPtr(AppName & Chr(0))
    
    
    Result = CreateProcessWithLogonW(wUser, wDomain, wPassword, LOGON_WITH_PROFILE, wAppName, 0, 0, 0, 0, VarPtr(si), VarPtr(pi))
    
    If Result <> 0 Then '        thanh cong
'        neu Wait  TRUE thi code dung o dong WaitForSingleObject cho toi khi process cua wAppName ket thuc
'        sau do moi chay tiep code CloseHandle pi.hThread
        If Wait Then WaitForSingleObject pi.hProcess, INFINITE
        CloseHandle pi.hThread
        CloseHandle pi.hProcess
        RunAsUser = 0
    Else
'        that bai
        RunAsUser = Err.LastDllError
        MsgBox "CreateProcessWithLogonW that bai " & Err.LastDllError, vbExclamation
    End If

End Function
 
Upvote 0
Cho mình hỏi chỗ này
ByVal Domain As LongPtr, ByVal Password As LongPtr

Thường thì Domain hay Password chắc phải để dạng string chứ, sao lại là Long được nhỉ
 
Upvote 0
Cho mình hỏi chỗ này
ByVal Domain As LongPtr, ByVal Password As LongPtr

Thường thì Domain hay Password chắc phải để dạng string chứ, sao lại là Long được nhỉ
Bạn ngâm cứu biến con trỏ (pointer) đi. Nó lưu địa chỉ trên vùng nhớ.
 
Upvote 0
@anhdepjai
Nếu các API có khai báo có chữ W hoa đằng sau như API này CreateProcessWithLogonW
Ta sẽ hiểu rằng các tham số chuỗi nên đặt thành địa chỉ trỏ đến vùng nhớ. Chữ W cũng hiểu thêm là hỗ trợ mã hóa Unicode.
Điều này giúp chúng ta bỏ qua bước chuyển mã chuỗi.
Hàm StrPtr sẽ chuyển chuỗi thành địa chỉ con trỏ bộ nhớ.
Chỉ cần hiểu là "địa chỉ nhà tôi đây, đến nhận hàng". Thay vì đưa hàng tận tay.

Khi khai báo các API có các Structure Type trong phiên 64bit thì luôn luôn đặt về địa chỉ con trỏ bộ nhớ. Đồng thời viết mã truy cập địa chỉ con trỏ bộ nhớ dễ dàng hơn.

Dễ hiểu vì trên HĐH 64bit vùng lưu trữ cho mỗi kiểu dữ liệu được cấp phát lớn hơn so với HĐH 32bit hay cũ hơn.
Sử dụng địa chỉ con trỏ bộ nhớ trong lập trình API cũng dễ dàng viết mã tương thích với hệ 32bit.
 
Lần chỉnh sửa cuối:
Upvote 0
Web KT

Bài viết mới nhất

Back
Top Bottom