Tạo macro mở phần mềm với tài khoản Administrator (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

Tôi tuân thủ nội quy khi đăng bài

test1986

Thành viên chính thức
Tham gia
19/10/22
Bài viết
52
Được thích
11
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
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
Em đã thử nghiệm với cấu trúc câu lệnh
RunAsUser "administrator", "test", "laptop", "D:\chrome.exe"
Nhưng kết quả nhận được là "CreateProcessWithLogonW that bai 1326"
Em tìm hiểu lỗi 1326 nhưng vẫn chưa tìm được ra lý do báo lỗi này.
Anh hướng dẫn giúp em với ạ, em cảm ơn
 
Upvote 0
Bạn xóa các dòng có mã

xem sao
Sau khi em kiểm tra thì 4 dòng có mã code trên.
Nếu để nguyên dòng này wAppName = StrPtr(AppName & Chr(0)) thì báo lỗi 1326
Nếu xóa dòng wAppName = StrPtr(AppName & Chr(0)) thì báo lỗi 87
Còn 3 dòng khác thì có xóa hay để nguyên thì không ảnh hường tới thông báo lỗi anh ạ.
Nhưng đường dẫn file em thấy đã rất ngắn gọn mà, em chưa hiểu được lỗi này lắm ạ.
 
Upvote 0
bạn thử sửa wDomain = 0
 
Upvote 0
User không phải là "administrator" nếu bạn đang sử dụng Win 10 và 11
Nó phải là địa chỉ mail đã đăng ký trên trang microsoft
 
Upvote 0
User không phải là "administrator" nếu bạn đang sử dụng Win 10 và 11
Nó phải là địa chỉ mail đã đăng ký trên trang microsoft
Dạ mặc định là tài khoản Administrator sẽ bị disable. Nhưng hiện tại, em đang enable tài khoản này để làm tài khoản quản lý anh ạ, đây là tài khoản local thuộc Windows Credentials anh ạ.
Bài đã được tự động gộp:

User không phải là "administrator" nếu bạn đang sử dụng Win 10 và 11
Nó phải là địa chỉ mail đã đăng ký trên trang microsoft
Anh có thể kiểm tra tài khoản administrator và enable tài khoản này trong "Computer Management\Local users and group\users"
 
Upvote 0
User không phải là "administrator" nếu bạn đang sử dụng Win 10 và 11
Nó phải là địa chỉ mail đã đăng ký trên trang microsoft
Nếu làm thủ công khi cài đặt bằng quyền administrator, thì ở khung nhập username|password thì em thấy có thể nhập username bằng 3 cách này thì window 10 đều chấp nhận
Cách 1: administrator|test
Cách 2: laptop\administrator|test
Cách 3: .\administrator|test

3 cách nhập trên đều hoạt động giống nhau anh ạ. Nên em không rõ phần wdomain hoạt động như thế nào trong đoạn code trên có trả về 1 trong 3 cách nhập username|password này không?
 
Upvote 0
Bạn thử đăng nhập với thiết đặt giá trị LOGON32_LOGON_NEW_CREDENTIALS = 9
 
Upvote 0
Mấy ngày cuối tuần em đã thử chỉnh sửa code theo hướng dẫn nhưng vẫn gặp 1 trong 2 lỗi 1326 và 87.
Laptop em đang dùng là sử dụng windows 10 pro version mới nhất.
Tài khoản Administrator đã hoạt động với pass Test.
Mong anh @HeSanbi và mọi người hướng dẫn giúp em khắc phục lỗi trên với ạ.
Em cảm ơn
1726448219792.png
 
Upvote 0
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 ạ.

Nếu mình làm app chỏ mình chạy thôi thì ý tưởng này được nhưng nếu đưa cho người khác dùng thì có vẻ không cần thiết nhỉ.
 
Upvote 0
Nếu mình làm app chỏ mình chạy thôi thì ý tưởng này được nhưng nếu đưa cho người khác dùng thì có vẻ không cần thiết nhỉ.
Dạ trong môi trường công việc, có những trường hợp đặc biệt cần phải sử dụng quyền administrator để sử dụng phần mềm. Nên em mới hướng tới giải pháp này để người sử dụng không cần biết mật khẩu administrator mà vẫn sử dụng được mà không cần phải đợi nhân viên IT đến chỉ để thực hiện công việc đơn giản là nhập mật khẩu administrator, như vậy sẽ tiết kiệm được thời gian của người sử dụng và nhân viên IT.
 
Upvote 0
Web KT

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

Back
Top Bottom