Chạy Runas ứng dụng trong VBA

Liên hệ QC

VMH0307

Thành viên tiêu biểu
Tham gia
5/8/11
Bài viết
765
Được thích
602
Kính gửi: mọi người trên diễn đàn!
Em đang có nhu cầu sử dụng VBA để mở 1 ứng dụng khác (ví dụ: Task manager) bằng user khác (ví dụ: user administrator)
Em sử dụng lệnh:
Shell "runas /u:administrator taskmgr"
sau đó MSDOS hiện ra cửa sổ nhập pass để mình nhập vào.
Vậy có cách nào để công đoạn nhập Pass này thông qua VBA luôn không?
Em cám ơn!
 
Kính gửi: mọi người trên diễn đàn!
Em đang có nhu cầu sử dụng VBA để mở 1 ứng dụng khác (ví dụ: Task manager) bằng user khác (ví dụ: user administrator)
Em sử dụng lệnh:
Shell "runas /u:administrator taskmgr"
sau đó MSDOS hiện ra cửa sổ nhập pass để mình nhập vào.
Vậy có cách nào để công đoạn nhập Pass này thông qua VBA luôn không?
Em cám ơn!

sao không thử qua mấy hàm API
tôi thử dùng hàm sau : ( lưu ý máy mình là win 7 64bits, bạn tự tùy chỉnh cho phù hợp với 32 bits nhé )
Mã:
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
'-----------------------------------------------------------------------
Sub GPE()
    ShellExecute 0&, "runas", [B]"C:\Program Files (x86)\TeamViewer\Version9\TeamViewer.exe"[/B], "", "", 1
    'Shell "runas /user:administrator taskmgr"
End Sub
p/s : 32 bits thì bỏ ptrsafe và thay longptr = long
 
Upvote 0
Cám ơn bạn hungpecc1, bạn có thể giải thích giúp mình về "công đoạn" điền password cho user thông qua code theo như cách của bạn được không.
cám ơn bạn nhiều.
 
Upvote 0
Cám ơn bạn hungpecc1, bạn có thể giải thích giúp mình về "công đoạn" điền password cho user thông qua code theo như cách của bạn được không.
cám ơn bạn nhiều.

Hàm Shellexecute của API khác hàm Shell của VBA !
Bình thường khi bạn mở 1 file hay một chương trình(exe) , bạn có thể click trực tiếp, hay chuột phải lên file để chọn các tính năng khác như : run as adimintrator, print, find ....

và hàm shellexecute cho phép bạn làm tất cả các hành động trên một cách tự đông !
 
Upvote 0
Hàm Shellexecute của API khác hàm Shell của VBA !
Bình thường khi bạn mở 1 file hay một chương trình(exe) , bạn có thể click trực tiếp, hay chuột phải lên file để chọn các tính năng khác như : run as adimintrator, print, find ....

và hàm shellexecute cho phép bạn làm tất cả các hành động trên một cách tự đông !
Mình hơi dốt khoản này, mình đã chạy hàm bằng API, với runas và máy cho hiện ra hộp thoại để mình chọn user và pass. Còn chạy bằng Shell thì cho ra CMD để nhập pass. Hiện mình muốn việc nhập pass này cũng làm bằng code luôn. Bạn có thể chỉ giúp mình việc như thế nào không.
 
Upvote 0
Mình hơi dốt khoản này, mình đã chạy hàm bằng API, với runas và máy cho hiện ra hộp thoại để mình chọn user và pass. Còn chạy bằng Shell thì cho ra CMD để nhập pass. Hiện mình muốn việc nhập pass này cũng làm bằng code luôn. Bạn có thể chỉ giúp mình việc như thế nào không.
** bạn dùng hệ điều hành gì //
** Cụ thể bạn muốn mở chương trình gì ?? với quyền run as adminitrator ??
 
Upvote 0
** bạn dùng hệ điều hành gì //
** Cụ thể bạn muốn mở chương trình gì ?? với quyền run as adminitrator ??
Mình dùng hệ điều hành Window XP. Mình có 1 tập hợp các user khác nhau và password tương ứng của chúng. Nhu cầu của mình là việc mở file hoặc ứng dụng với phân quyền của user đó bằng code (có thể mình đang log on bằng guest, admin hoặc 1 user abc nào đó và chuyển đổi qua lại giữa chúng)
Nói thêm: mình chỉ muốn mở file, ứng dụng chuyển đổi qua lại user theo cách Runas
 
Upvote 0
Xin ké 1 câu hỏi trong chủ đề này?

Dear all,
Tôi có một câu hỏi tương tự với chủ đề này nên xin phép chủ topfic và ban quản trị cho phép ạ!

Trong khi chờ đợi kết quả mọi người xem trường hợp của tôi có cách nào giải quyết bằng code được không ạ?

Untitled.jpg

Trong ảnh đính kèm nhờ các bạn giúp tôi sửa số 0 trong khung màu xanh thành số 1 qua việc chạy code?
Xin cảm ơn.
 
Upvote 0
Kính gửi: mọi người trên diễn đàn!
Em đang có nhu cầu sử dụng VBA để mở 1 ứng dụng khác (ví dụ: Task manager) bằng user khác (ví dụ: user administrator)
Em sử dụng lệnh:
Shell "runas /u:administrator taskmgr"
sau đó MSDOS hiện ra cửa sổ nhập pass để mình nhập vào.
Vậy có cách nào để công đoạn nhập Pass này thông qua VBA luôn không?
Em cám ơn!

Thế khi hiện cửa sổ CMD thì bạn có gõ được mật khẩu không?
Tôi thử trên XP Home Edition của tôi thì tôi không gõ được bất cứ phím chữ cái nào để nhập mật khẩu. Chỉ có thể nhấn Enter mà thôi. Tất nhiên chỉ Enter thì sẽ có thông báo lỗi. Nhưng không thể gõ được phím nào khác mới bực chứ.

Nếu bạn nhập được mật khẩu và sau khi nhấn Enter thì khởi động được Task Manager thì ...

Tôi chưa làm cái này bao giờ nhưng nhớ hồi ở DOS có cách sau đây. Không phải là RunAs.

Nếu ở DOS ta nhập dòng lệnh vd. là del c:\blala\*.*, tức ta định xóa tất cả các tập tin trong thư mục c:\blala thì bao giờ cũng có thông báo đại loại là "c:\blala\*.* Chắc chắn chứ <Y/N>?"
Lúc đó nếu đúng là ta muốn (vì có thể nhầm) thì phải nhập y (hoặc Y) rồi nhấn Enter.

Để khỏi phải y + Enter thì ta soạn 1 tập tin: mở notepad --> nhấn y --> nhấn Enter --> lưu vd. là c:\yes.txt

Sau đó thì câu lệnh là

Mã:
del c:\blala\*.* < c:\yes.txt

Ai đó có thể nói: nếu phải gõ thêm "< c:\yes.txt" thì thà gõ "y + Enter" còn nhanh hơn. Đúng thế. Nhưng nếu ta viết 1 tập tin BAT trong đó có vd. 10 dòng lệnh như trên thì mỗi lần chạy BAT ta phải gõ 10 lần "y + Enter". Nếu ta thêm vào 10 dòng lệnh kia 10 "y + Enter" thì cho dù khi cần ta có chạy 100 lần BAT thì chả bao giờ ta phải cặm cụi gõ "y + Enter" nữa.

Có nhiều câu lệnh khác mà khi ta chạy thì DOS cũng hiển thị câu hỏi và chờ ta nhập thông tin. Lúc đó cũng có thể nhập thông tin từ tập tin TXT (có nội dung: <câu trả lời> --> Enter)

Tóm lại bạn hãy thử như sau: mở notepad --> gõ mật khẩu --> gõ Enter (sẽ thấy trỏ text xuống dòng) --> ghi lại vd. là c:\pass.txt

Sau đó thử sửa câu lệnh như sau

Mã:
Shell "runas /user:administrator taskmgr < c:\pass.txt"

Cũng có thể dùng code để: tạo tập tin pass.txt --> ghi lên đĩa --> dùng tập tin --> xóa tập tin.

Tôi không dám chắc vì chưa bao giờ làm. Chỉ là nhớ lại hồi xửa hồi xưa ... Nếu không được thì tôi cũng chịu
 
Upvote 0
Thế khi hiện cửa sổ CMD thì bạn có gõ được mật khẩu không?
Tôi thử trên XP Home Edition của tôi thì tôi không gõ được bất cứ phím chữ cái nào để nhập mật khẩu. Chỉ có thể nhấn Enter mà thôi. Tất nhiên chỉ Enter thì sẽ có thông báo lỗi. Nhưng không thể gõ được phím nào khác mới bực chứ.

Nếu bạn nhập được mật khẩu và sau khi nhấn Enter thì khởi động được Task Manager thì ...

Tôi chưa làm cái này bao giờ nhưng nhớ hồi ở DOS có cách sau đây. Không phải là RunAs.

Nếu ở DOS ta nhập dòng lệnh vd. là del c:\blala\*.*, tức ta định xóa tất cả các tập tin trong thư mục c:\blala thì bao giờ cũng có thông báo đại loại là "c:\blala\*.* Chắc chắn chứ <Y/N>?"
Lúc đó nếu đúng là ta muốn (vì có thể nhầm) thì phải nhập y (hoặc Y) rồi nhấn Enter.

Để khỏi phải y + Enter thì ta soạn 1 tập tin: mở notepad --> nhấn y --> nhấn Enter --> lưu vd. là c:\yes.txt

Sau đó thì câu lệnh là

Mã:
del c:\blala\*.* < c:\yes.txt

Ai đó có thể nói: nếu phải gõ thêm "< c:\yes.txt" thì thà gõ "y + Enter" còn nhanh hơn. Đúng thế. Nhưng nếu ta viết 1 tập tin BAT trong đó có vd. 10 dòng lệnh như trên thì mỗi lần chạy BAT ta phải gõ 10 lần "y + Enter". Nếu ta thêm vào 10 dòng lệnh kia 10 "y + Enter" thì cho dù khi cần ta có chạy 100 lần BAT thì chả bao giờ ta phải cặm cụi gõ "y + Enter" nữa.

Có nhiều câu lệnh khác mà khi ta chạy thì DOS cũng hiển thị câu hỏi và chờ ta nhập thông tin. Lúc đó cũng có thể nhập thông tin từ tập tin TXT (có nội dung: <câu trả lời> --> Enter)

Tóm lại bạn hãy thử như sau: mở notepad --> gõ mật khẩu --> gõ Enter (sẽ thấy trỏ text xuống dòng) --> ghi lại vd. là c:\pass.txt

Sau đó thử sửa câu lệnh như sau

Mã:
Shell "runas /user:administrator taskmgr < c:\pass.txt"

Cũng có thể dùng code để: tạo tập tin pass.txt --> ghi lên đĩa --> dùng tập tin --> xóa tập tin.

Tôi không dám chắc vì chưa bao giờ làm. Chỉ là nhớ lại hồi xửa hồi xưa ... Nếu không được thì tôi cũng chịu
Vâng
đối với Runas trên màn hình Command line (CMD) thì ví dụ:
runas /u:administrator taskmgr
enter the password for administrator:
thì nhập pass vào đây máy vẫn nhận nhưng không hiển thị -> đó là lý do vì sao bác thấy máy không nhận bất cứ phím chữ cái nào. (thực ra bác cứ nhập đúng mật khẩu thì là OK)

Với phép thử của bác
Shell "runas /user:administrator taskmgr < c:\pass.txt"
không cho kết quả.
kể cả khi cháu đang ở màn hình administrator mở chính user này hay user guest cũng đều hiển thị lỗi log on failure bác ạ.
Cám ơn bác nhiều, mong bác có cao kiến khác.

P/s: Nếu không dùng Shell mà dùng ShellExcute thì thay vì màn hình command line, nó hiển thị hộp thoại runas.
với hộp thoại này cháu có kiểm tra thấy;
Check box của User: ID: 260, ClassName: Editbox
Textbox nhập pass: ID: 1005, ClassName: Edit
Nút nhấn OK: ID: 1, ClassName: Button, text: OK.
 
Upvote 0
Vâng
đối với Runas trên màn hình Command line (CMD) thì ví dụ:
runas /u:administrator taskmgr
enter the password for administrator:
thì nhập pass vào đây máy vẫn nhận nhưng không hiển thị -> đó là lý do vì sao bác thấy máy không nhận bất cứ phím chữ cái nào. (thực ra bác cứ nhập đúng mật khẩu thì là OK)

Với phép thử của bác
Shell "runas /user:administrator taskmgr < c:\pass.txt"
không cho kết quả.
kể cả khi cháu đang ở màn hình administrator mở chính user này hay user guest cũng đều hiển thị lỗi log on failure bác ạ.
Cám ơn bác nhiều, mong bác có cao kiến khác.

P/s: Nếu không dùng Shell mà dùng ShellExcute thì thay vì màn hình command line, nó hiển thị hộp thoại runas.
với hộp thoại này cháu có kiểm tra thấy;
Check box của User: ID: 260, ClassName: Editbox
Textbox nhập pass: ID: 1005, ClassName: Edit
Nút nhấn OK: ID: 1, ClassName: Button, text: OK.

Kể cũng lạ. Tôi gõ không nhìn thấy gì và trỏ text cũng không di chuyển, và khi Enter thì có thông báo lỗi.
Có thể do phiên bản Windows của tôi.
Tôi dùng XP Home Edition (chắc chắn không có bảo mật như vd. Professional) và Windows 7 Starter (cũng là loại vét đĩa)
-------
Nếu những class và ID này không thay đổi theo phiên bản Windows, tức như nhau trong Xp, Windows 7 thì có thể dùng kỹ thuật "điều khiển tự động".
Để tôi kiểm tra lại trong XP thì các class và ID này là gì
--------------
View attachment 116602

Như trong hình, cả user và pass đều bị disabled nên tôi không đọc được class và ID của chúng.
Hình này là trên XP Home Edition của tôi.

Để tôi sang máy người khác - Windows 7 Starter xem thế nào.
----------

Bạn dùng XP? Cái cửa sổ đăng nhập có class trong XP của tôi là #32770, bạn có thế không? Thế title (trên thanh tiêu đề) của nó là gì? Bạn dùng Windows nào? Nếu nhập bằng tay thì bạn nhập pass thế nào? Nếu cả user thì là chọn (combobox?) hay gõ, gõ gì chọn gì nếu làm bằng tay?
 
Lần chỉnh sửa cuối:
Upvote 0
Tôi đã thử với ShellExecute nhưng không được.

Mã:
Sub GPE()
Dim hwnd As Long, ChildWnd As Long
'    run taskmgr
    ShellExecute 0, "runas", "C:\WINDOWS\system32\TaskMgr.exe", "", "", 1
'    tim cua so Run As
    hwnd = FindWindow("#32770", "Run As")
'    tim nut OK
    ChildWnd = FindWindowEx(hwnd, 0, "Button", "OK")
'    thu doc handle cua OK
    MsgBox ChildWnd
End Sub

Nguyên nhân là control dừng ở dòng ShellExecute ... cho tới tận khi chạy Task Manager. Nhưng cửa sổ "Run As" thì lại dừng và đợi nhập user + pasword + OK rồi mới run Task Manager. Vậy code dừng ở dòng ShellExecute cho tới ngày tận thế. Hoặc cho tới lúc ta nhập bằng tay user + password rồi nhấn OK. Lúc đó thì Task Manager được run và control lúc này mới chuyển tới dòng code hwnd = FindWindow("#32770", "Run As") để thực hiện. Nhưng lúc này thì cửa sổ "Run As" đã đóng từ đời nào rồi nên hwnd = 0, tiếp theo dĩ nhiên ChildWnd = 0.
-------------
Hồi xa xưa tôi có "vọc" trong Delphi. Bây giờ tìm lại và dịch sang VBA.
Tôi thử trên XP Home Edition thì thành công. Bạn test thử xem.
Nếu vẫn không thành công thì tôi xin dừng tại đây.

Về các thông số của hàm API CreateProcessWithLogonW thì bạn hãy đọc tại

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682431(v=vs.85).aspx

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 [COLOR=#0000ff]WaitForSingleObject[/COLOR] cho toi khi process cua wAppName ket thuc
'        sau do moi chay tiep code CloseHandle pi.hThread
        If Wait Then [COLOR=#0000ff]WaitForSingleObject[/COLOR] 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

Sub GPE()
Dim hwnd As Long, ChildWnd As Long
    [COLOR=#ff0000]RunAsUser[/COLOR] "user", "password", "Domain", "C:\WINDOWS\system32\taskmgr.exe"
    ...
End Sub

Nếu sau dòng code RunAsUser còn có nhiều code khác mà ta truyền cho RunAsUser thông số cuối cùng là TRUE thì control sẽ dừng ở dòng RunAsUser cho tới tận khi Task Manager được đóng. Lúc đó các code sau RunAsUser mới được thực thi. Nguyên nhân là do khi Wait = TRUE thì control sẽ dừng ở dòng WaitForSingleObject cho tới khi process của Task Manager kết thúc (đợi cho tới "ngàn thu" - do INFINITE hoặc cho tới khi process kết thúc - pi.hProcess). Lúc đó RunAsUser mới trở về (return) và các code sau RunAsUser mới được thực hiện.

Nói nôm na thì WaitForSingleObject "đợi" cho tới khi một trong 2 sự kiện sẩy ra thì mới return. Sự kiện 1 là process có handle là pi.hProcess kết thúc. Sự kiện 2 là "khoảng thời gian ấn định" đã trôi qua. INFINITE có nghĩa là "khoảng thời gian ấn định" là "ngàn thu". Vậy thực chất là ta đợi cho tới khi process kết thúc. Vì "ngàn thu" có bao giờ kết thúc đâu.
 
Lần chỉnh sửa cuối:
Upvote 0
Cháu cám ơn bác Siwtom rất nhiều. Chuyến này cháu phải ngâm cứu số Code này mới được. Phần WaitForSingleObject hay quá bác ạ.
 
Upvote 0
Dear all,
Tôi có một câu hỏi tương tự với chủ đề này nên xin phép chủ topfic và ban quản trị cho phép ạ!

Trong khi chờ đợi kết quả mọi người xem trường hợp của tôi có cách nào giải quyết bằng code được không ạ?

View attachment 116595

Trong ảnh đính kèm nhờ các bạn giúp tôi sửa số 0 trong khung màu xanh thành số 1 qua việc chạy code?
Xin cảm ơn.

Nếu chủ topfic đã thỏa mãn với câu trả lời rồi thì tôi xin phép được nhắc lại bài này để nhờ giúp đỡ.
Xin cảm ơn.
 
Upvote 0
Nếu chủ topfic đã thỏa mãn với câu trả lời rồi thì tôi xin phép được nhắc lại bài này để nhờ giúp đỡ.
Xin cảm ơn.

Lần sau bạn đừng chen ngang như thế. Muốn hỏi thì lập chủ đề mà hỏi

Mã:
Private Sub Hichic()
Dim name As String, shellObj As Object
    name = "HKEY_CURRENT_USER\Console\ColorTable00"
    Set shellObj = CreateObject("WScript.Shell")
    shellObj.RegWrite name, 1, "REG_DWORD"
    Set shellObj = Nothing
End Sub
 
Upvote 0
Web KT
Back
Top Bottom