Как интегрировать UAC в мою программу VB6? - PullRequest
7 голосов
/ 21 января 2011

Мне нужен код, который добавит значок прав администратора к командным кнопкам и отобразит подсказку при нажатии на такие кнопки. Как я могу сделать это в VB6? Некоторые действия требуют прав администратора, потому что они заменяют файлы и прочее, если Windows Vista / 7 не разрешает программе нормальный доступ к файлам.

Ответы [ 4 ]

7 голосов
/ 21 января 2011

Вот пример ShellExecuteEx для VB6, который позволит вам при желании выполнить любой процесс с правами администратора.Вы можете поместить это в модуль или класс.

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
4 голосов
/ 26 января 2011

Примеры кода действительно могут быть запущены, но вот тривиальный подход, показывающий подход «второй экземпляр меня».

Программа имеет статический модуль запуска с несколькими общедоступными функциями, включая «повышенную операцию»обработчик и форма с одним CommandButton:

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

Приложение имеет простой "asInvoker"манифест выбора сборки Common Controls 6.0.

1 голос
/ 26 января 2011


  1. Переместите весь код, требующий повышения, во внешние процессы.
  2. Отправьте своим кнопкам сообщение BCM_SETSHIELD , чтобы добавить значок щита..
  3. Embed проявляется в этих процессах, сообщая Windows, что они требуют повышения прав.См. Ниже.



Чтобы Vista и выше запускали исполняемый файл VB6 в качестве администратора в UAC, вы должны встроить XML-файл манифеста в качестве ресурса.внутри него.Последующие шаги:

  1. Создайте файл манифеста.Назовите его «YourProgram.exe.manifest», он должен содержать следующее.Важной строкой является «требуемый уровень выполнения».Измените атрибуты в соответствии с вашим exe.

    <?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. Создайте файл с именем «YourProgram.exe.manifest.rc».Он должен содержать следующее.

    # define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
    #define RT_MANIFEST 24 CREATEPROCESS_MANIFEST_RESOURCE_ID
    RT_MANIFEST "YourProgram.exe.1034 * ** 10 * * 10 * 10 * *

    *
  3. Скомпилируйте ваш ресурс, используя rc.exe.По умолчанию он находится в C: \ Program Files \ Microsoft Visual Studio \ COMMON \ MSDev98 \ Bin.Это создаст файл с именем YourProgram.exe.manifest.RES.Синтаксис есть;

    rc /r YourProgram.exe.manifest.rc

  4. Добавьте файл .RES в свой проект.Сделайте это с помощью надстройки редактора ресурсов в VB6.Значок на панели инструментов выглядит как зеленые блоки.Если у вас нет значка, убедитесь, что он включен в менеджере надстроек.Если его нет в диспетчере надстроек, вам нужно выполнить regsvr32 на C: \ Program Files \ Microsoft Visual Studio \ VB98 \ Wizards \ Resedit.dll.Открыв редактор ресурсов, нажмите кнопку «Открыть» и выберите файл .RES.

  5. Скомпилируйте ваш проект.

  6. Чтобы дважды проверить правильность встраивания манифеста, вы можете использовать инструмент под названием InspectExe .В проводнике перейдите к свойствам exe, и если манифест был внедрен, у вас должна быть вкладка манифеста (.Net сборок также будет иметь эту вкладку манифеста).

  7. Попробуйте запустить программу в Vista или более поздней версии.Если UAC действительно включен, он должен сразу же получить приглашение.

1 голос
/ 21 января 2011

Сначала возьмите код, который запускается, когда кто-то нажимает кнопку, и поместите его в отдельный исполняемый файл. Измените код нажатия кнопки, чтобы запустить исполняемый файл с помощью ShellExecute. Во-вторых, создайте внешние манифесты для каждого нового exe-файла и попросите его указать requireAdministrator. В-третьих, отправьте своим кнопкам сообщение BCM_SETSHIELD (вам, вероятно, придется искать числовое значение идентификатора сообщения), чтобы на них появился экран.

...