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
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.
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 !
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.
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.
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
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
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
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.
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?
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
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 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