2011-01-21 36 views
7

Tôi cần một số mã sẽ thêm biểu tượng quyền quản trị vào các nút lệnh và hiển thị lời nhắc khi các nút đó được nhấp. Làm thế nào tôi có thể làm điều này trong VB6? Một số hành động yêu cầu quyền quản trị vì chúng thay thế tệp và nội dung mà Windows Vista/7 không cho phép chương trình truy cập bình thường vào tệp.Làm cách nào để tích hợp UAC vào chương trình VB6 của tôi?

Trả lời

7

Dưới đây là ví dụ VB6 về ShellExecuteEx cho phép bạn tùy chọn thực thi bất kỳ quy trình nào có quyền quản trị viên. Bạn có thể thả điều này vào một mô-đun hoặc lớp học.

Option Explicit 

Private Const SEE_MASK_DEFAULT = &H0 

Public Enum EShellShowConstants 
     essSW_HIDE = 0 
     essSW_SHOWNORMAL = 1 
     essSW_SHOWMINIMIZED = 2 
     essSW_MAXIMIZE = 3 
     essSW_SHOWMAXIMIZED = 3 
     essSW_SHOWNOACTIVATE = 4 
     essSW_SHOW = 5 
     essSW_MINIMIZE = 6 
     essSW_SHOWMINNOACTIVE = 7 
     essSW_SHOWNA = 8 
     essSW_RESTORE = 9 
     essSW_SHOWDEFAULT = 10 
End Enum 

Private Type SHELLEXECUTEINFO 
     cbSize  As Long 
     fMask   As Long 
     hwnd   As Long 
     lpVerb  As String 
     lpFile  As String 
     lpParameters As String 
     lpDirectory As String 
     nShow   As Long 
     hInstApp  As Long 
     lpIDList  As Long  'Optional 
     lpClass  As String 'Optional 
     hkeyClass  As Long  'Optional 
     dwHotKey  As Long  'Optional 
     hIcon   As Long  'Optional 
     hProcess  As Long  'Optional 
End Type 

Private Declare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" (lpSEI As SHELLEXECUTEINFO) As Long 

Public Function ExecuteProcess(ByVal FilePath As String, ByVal hWndOwner As Long, ShellShowType As EShellShowConstants, Optional EXEParameters As String = "", Optional LaunchElevated As Boolean = False) As Boolean 
    Dim SEI As SHELLEXECUTEINFO 

    On Error GoTo Err 

    'Fill the SEI structure 
    With SEI 
     .cbSize = Len(SEI)     ' Bytes of the structure 
     .fMask = SEE_MASK_DEFAULT   ' Check MSDN for more info on Mask 
     .lpFile = FilePath     ' Program Path 
     .nShow = ShellShowType    ' How the program will be displayed 
     .lpDirectory = PathGetFolder(FilePath) 
     .lpParameters = EXEParameters  ' Each parameter must be separated by space. If the lpFile member specifies a document file, lpParameters should be NULL. 
     .hwnd = hWndOwner     ' Owner window handle 

     ' Determine launch type (would recommend checking for Vista or greater here also) 
     If LaunchElevated = True Then ' And m_OpSys.IsVistaOrGreater = True 
      .lpVerb = "runas" 
     Else 
      .lpVerb = "Open" 
     End If 
    End With 

    ExecuteProcess = ShellExecuteEx(SEI) ' Execute the program, return success or failure 

    Exit Function 
Err: 
    ' TODO: Log Error 
    ExecuteProcess = False 
End Function 

Private Function PathGetFolder(psPath As String) As String 
    On Error Resume Next 
    Dim lPos As Long 
    lPos = InStrRev(psPath, "\") 
    PathGetFolder = Left$(psPath, lPos - 1) 
End Function 
+0

Làm cách nào để thêm biểu tượng cái khiên vào nút? – WindozeNT

+0

Nevermind Tôi tìm thấy BCM_SETSHEILD cho VB6. Làm cách nào để nhận lời nhắc thực hiện một hành động thay vì khởi động chương trình. Giống như nơi nó nói "Windows cần sự cho phép của bạn để tiếp tục" thay vì "Một chương trình không xác định muốn truy cập máy tính của bạn"? Và cú pháp để chạy là gì? – WindozeNT

+0

Ví dụ về ghi nhật ký lỗi: Mở Đối với Đầu ra Là FreeFile – WindozeNT

1

Trước tiên, hãy lấy mã chạy khi ai đó nhấp vào nút và đặt mã đó vào một exe riêng biệt. Thay đổi mã bấm nút của bạn để khởi chạy exe bằng ShellExecute. Thứ hai, xây dựng các biểu hiện bên ngoài cho mỗi exe mới và có nó chỉ định requireAdministrator. Thứ ba, gửi các nút của bạn thông báo BCM_SETSHIELD (có thể bạn sẽ phải tra cứu giá trị số của ID tin nhắn) để làm cho lá chắn xuất hiện trên chúng.

+0

Tôi chỉ đề xuất, thay vì tạo một exe riêng biệt, khởi chạy phiên bản thứ 2 của ứng dụng bằng đối số dòng lệnh cho biết bạn chỉ muốn thực hiện tác vụ cụ thể này, sau đó thoát. –

+0

Vấn đề với bản thân thứ hai của bản thân bạn là bản kê khai. Bạn muốn trường hợp thứ hai được nâng lên và trường hợp đầu tiên không được. Cùng một ứng dụng có nghĩa là tệp kê khai giống nhau, do đó sẽ không hoạt động. –

+1

Kate, bạn có thể sử dụng ShellExecuteEx và chuyển nó một cấu trúc SHELLEXECUTEINFO có .lpFile làm đường dẫn ứng dụng và .lpVerb = "runas". Điều đó sẽ khởi chạy ứng dụng hiện có với đặc quyền quản trị viên. –

4

Ví dụ mã thực sự có thể chạy, nhưng đây là một ví dụ nhỏ cho thấy cách tiếp cận "ví dụ thứ hai của tôi".

Chương trình có một module khởi động tĩnh với một vài chức năng công cộng bao gồm một "hoạt động cao" xử lý, và một mẫu chỉ với một CommandButton vào nó:

Module1.bas

Option Explicit 

Private Const BCM_SETSHIELD As Long = &H160C& 

Private Declare Sub InitCommonControls Lib "comctl32"() 

Private Declare Function IsUserAnAdmin Lib "shell32"() As Long 

Private Declare Function SendMessage Lib "user32" _ 
    Alias "SendMessageA" (_ 
    ByVal hWnd As Long, _ 
    ByVal wMsg As Long, _ 
    ByVal wParam As Long, _ 
    ByRef lParam As Any) As Long 

Private Declare Function ShellExecute Lib "shell32" _ 
    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 VbAppWinStyle) As Long 

Private mblnIsElevated As Boolean 

Public Function IsElevated() As Boolean 
    IsElevated = mblnIsElevated 
End Function 

Public Sub OperationRequiringElevation(ByRef Params As Variant) 
    MsgBox "Insert logic here for: " & vbNewLine _ 
     & Join(Params, vbNewLine) 
End Sub 

Public Sub RequestOperation(_ 
    ByVal hWnd As Long, _ 
    ByVal Focus As VbAppWinStyle, _ 
    ByRef Params As Variant) 

    ShellExecute hWnd, "runas", App.EXEName & ".exe", _ 
       Join(Params, " "), CurDir$(), Focus 
End Sub 

Public Sub SetShield(ByVal hWnd As Long) 
    SendMessage hWnd, BCM_SETSHIELD, 0&, 1& 
End Sub 

Private Sub Main() 
    If Len(Command$()) > 0 Then 
     'Assume we've been run elevated to execute an operation 
     'specified as a set of space-delimited strings. 
     OperationRequiringElevation Split(Command$(), " ") 
    Else 
     mblnIsElevated = IsUserAnAdmin() 
     InitCommonControls 
     Form1.Show 
    End If 
End Sub 

Form1. frm

Option Explicit 

Private Sub Command1_Click() 
    Dim Params As Variant 

    Params = Array("ReplaceFile", "abc", "123") 
    If IsElevated() Then 
     OperationRequiringElevation Params 
    Else 
     RequestOperation hWnd, vbHide, Params 
    End If 
End Sub 

Private Sub Form_Load() 
    If Not IsElevated() Then 
     SetShield Command1.hWnd 
    End If 
End Sub 

Ứng dụng này có tệp kê khai "asInvoker" đơn giản chọn lắp ráp Common Controls 6.0.

+1

+1 để đề cập đến IsUserAnAdmin() – CSharper

1


  1. Move tất cả các mã mà đòi hỏi cao vào các quá trình bên ngoài.
  2. Gửi các nút của bạn thông báo BCM_SETSHIELD để thêm biểu tượng cái khiên.
  3. Nhúng tệp kê khai vào các quy trình đó, cho Windows biết rằng chúng yêu cầu độ cao. Xem bên dưới.



Để buộc Vista và cao hơn để chạy một exe VB6 as administrator trong UAC, bạn phải nhúng một xml biểu hiện như một nguồn lực bên trong của nó. Các bước tiếp theo;

  1. Tạo tệp kê khai. Đặt tên cho nó là "YourProgram.exe.manifest" nó phải chứa những điều sau đây. Dòng quan trọng là "requestedExecutionLevel". Thay đổi các thuộc tính để khớp với exe của bạn.

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>> 
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
        <assemblyIdentity 
        version="1.0.0.0" 
        processorArchitecture="X86" 
        name="YourProgram" 
        type="win32" 
        > 
        <description>application description</description> 
        <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> 
        <security 
         <requestedPrivileges> 
         <requestedExecutionLevel level="requireAdministrator" uiAccess="false"/> 
         </requestedPrivileges> 
        </security> 
        </trustInfo> 
    </assembly> 
    
  2. Tạo một file có tên "YourProgram.exe.manifest.rc". Nó nên chứa những điều sau đây.

    # xác định CREATEPROCESS_MANIFEST_RESOURCE_ID 1
    # xác định RT_MANIFEST 24 CREATEPROCESS_MANIFEST_RESOURCE_ID
    RT_MANIFEST "YourProgram.exe.manifest"

  3. Biên soạn tài nguyên của bạn sử dụng rc.exe. Nó được đặt theo mặc định trong C: \ Program Files \ Microsoft Visual Studio \ COMMON \ MSDev98 \ Bin. Điều này sẽ tạo ra một tập tin gọi là YourProgram.exe.manifest.RES. Cú pháp là;

    rc /r YourProgram.exe.manifest.rc

  4. Thêm file res để dự án của bạn. Thực hiện việc này bằng cách sử dụng trình soạn thảo tài nguyên bổ trợ trong VB6. Biểu tượng trên thanh công cụ trông giống như các khối màu xanh lục. Nếu bạn không có biểu tượng, hãy đảm bảo nó được bật trong trình quản lý addin. Nếu nó không có trong trình quản lý addin, bạn cần phải regsvr32 trên C: \ Program Files \ Microsoft Visual Studio \ VB98 \ Wizards \ Resedit.dll. Khi bạn đã mở trình chỉnh sửa tài nguyên, hãy nhấp vào mở và chọn tệp .RES của bạn.

  5. Biên dịch dự án của bạn.

  6. Để kiểm tra kỹ xem tệp kê khai đã được nhúng đúng chưa, bạn có thể sử dụng công cụ có tên là InspectExe. Trong thám hiểm, đi đến các thuộc tính của exe, và nếu manifest được nhúng, bạn nên có một thẻ manifest (.Net hội đồng cũng sẽ có thẻ manifest này).

  7. Thử chạy chương trình của bạn trên Vista hoặc phiên bản mới hơn. Nếu UAC thực sự được kích hoạt, nó sẽ xuất hiện với dấu nhắc ngay lập tức.

+0

Tôi đang sử dụng Visual Basic 6 Portable, vì vậy nó chỉ là IDE. – WindozeNT

+2

Không có "Phiên bản di động" - bạn đang sử dụng phần mềm bị đánh cắp. – Bob77

+0

Bạn không cần những chuyển động RC.EXE này để nhúng tệp kê khai ứng dụng.Chỉ cần tạo tệp kê khai của bạn dưới dạng văn bản ANSI (đủ gần với UTF-8 bình thường), hãy đảm bảo nó được đệm thành bội số là 4 byte, sau đó thêm nó làm Tài nguyên tùy chỉnh bằng cách sử dụng Trình chỉnh sửa tài nguyên IDE và đặt Kiểu thành # 24 và Id thành # 1 và Lưu. – Bob77

Các vấn đề liên quan