如何将 UAC 集成到我的 VB6 程序中?

发布于 2024-10-13 03:08:54 字数 115 浏览 5 评论 0原文

我需要一些代码,将管理员权限图标添加到命令按钮,并在单击此类按钮时显示提示。我怎样才能在VB6中做到这一点?某些操作需要管理员权限,因为它们会替换 Windows Vista/7 不允许程序正常访问文件的文件和内容。

I need some code that will add the admin rights icon to command buttons and display the prompt when such buttons are clicked. How can I do this in VB6? Some actions require admin rights because they replace files and stuff where Windows Vista/7 don't allow the program normal access to the files.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浴红衣 2024-10-20 03:08:54

下面是 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

Here's a VB6 example of ShellExecuteEx that will allow you to optionally execute any process with admin permissions. You can drop this into a module or class.

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
暮凉 2024-10-20 03:08:54

代码示例确实可以继续运行,但这里有一个简单的代码示例,展示了“我的第二个实例”方法。

该程序有一个启动静态模块,其中包含一些公共功能,包括“提升操作”处理程序,以及一个只有一个 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集会。

Code examples can really run on, but here is a trivial one showing the "second instance of me" approach.

The program has a startup static module with a few public functions including an "elevated operation" handler, and a Form with just one CommandButton on it:

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

The application has a simple "asInvoker" manifest selecting the Common Controls 6.0 assembly.

陪我终i 2024-10-20 03:08:54

首先,获取当有人单击按钮时运行的代码,并将其放入单独的 exe 中。更改按钮单击代码以使用 ShellExecute 启动 exe。其次,为每个新 exe 构建外部清单并指定 requireAdministrator。第三,向按钮发送 BCM_SETSHIELD 消息(您可能需要查找消息 ID 的数值)以使防护罩出现在按钮上。

First, take the code that runs when someone clicks the button, and put it in a separate exe. Change your button-click code to launch the exe using ShellExecute. Second, build external manifests for each new exe and have it specify requireAdministrator. Third, send your buttons the BCM_SETSHIELD message (you will probably have to look up the numerical value of the message ID) to make the shield appear on them.

吹泡泡o 2024-10-20 03:08:54

  1. 将所有需要提升的代码移至外部进程中。
  2. 向您的按钮发送 BCM_SETSHIELD 消息以添加盾牌图标。
  3. 将清单嵌入到这些进程中,告诉 Windows 它们需要提升。见下文。

为了强制 Vista 及更高版本在 UAC 中以管理员身份运行 VB6 exe,您必须将清单 xml 作为资源嵌入其中。步骤如下:

  1. 创建清单文件。将其命名为“YourProgram.exe.manifest”,它应包含以下内容。重要的一行是“requestedExecutionLevel”。更改属性以匹配您的 exe。

    <块引用>

    >>
    <程序集 xmlns=“urn:schemas-microsoft-com:asm.v1”manifestVersion=“1.0”>
      <程序集标识
        版本=“1.0.0.0”
        处理器架构=“X86”
        名称=“你的程序”
        类型=“win32”
      >
      <描述>应用描述
      
        <安全性
          <请求的权限>
            
          
        
      
    
    
  2. 创建一个名为“YourProgram.exe.manifest.rc”的文件。它应包含以下内容。

    <块引用>

    #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
    #define RT_MANIFEST 24 CREATEPROCESS_MANIFEST_RESOURCE_ID
    RT_MANIFEST“YourProgram.exe.manifest”

  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 中的资源编辑器插件执行此操作。工具栏上的图标看起来像绿色块。如果您没有该图标,请确保在插件管理器中启用它。如果插件管理器中没有,则需要在 C:\Program Files\Microsoft Visual Studio\VB98\Wizards\Resedit.dll 上进行 regsvr32。打开资源编辑器后,单击“打开”并选择您的 .RES 文件。

  5. 编译您的项目。

  6. 要仔细检查清单是否正确嵌入,您可以使用名为 InspectExe。在资源管理器中,转到 exe 的属性,如果嵌入了清单,您应该有一个清单选项卡(.Net 程序集也将有此清单选项卡)。

  7. 尝试在 Vista 或更高版本上运行您的程序。如果确实启用了 UAC,它应该立即出现提示。

  1. Move all of the code that requires elevation into external processes.
  2. Send your buttons the BCM_SETSHIELD message to add the shield icon.
  3. Embed manifests into those processes, telling Windows that they require elevation. See below.

In order to force Vista and higher to run a VB6 exe as administrator in UAC, you must embed a manifest xml as a resource inside of it. Steps follow;

  1. Create the manifest file. Name it "YourProgram.exe.manifest" it should contain the following. The important line is the "requestedExecutionLevel". Change the attributes in to match your 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. Create a file named "YourProgram.exe.manifest.rc". It should contain the following.

    #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
    #define RT_MANIFEST 24 CREATEPROCESS_MANIFEST_RESOURCE_ID
    RT_MANIFEST "YourProgram.exe.manifest"

  3. Compile your resource using rc.exe. It is located by default in C:\Program Files\Microsoft Visual Studio\COMMON\MSDev98\Bin. This will create a file called YourProgram.exe.manifest.RES. The syntax is;

    rc /r YourProgram.exe.manifest.rc

  4. Add the .RES file to your project. Do this using the Resource Editor Add-In in VB6. The icon on the toolbar looks like green blocks. If you do not have the icon, make sure it is enabled in the addin manager. If it is not in the addin manager, you need to regsvr32 on C:\Program Files\Microsoft Visual Studio\VB98\Wizards\Resedit.dll. Once you've got the resource editor open, click open and select your .RES file.

  5. Compile your project.

  6. To double check that the manifest was embedded properly, you can use a tool called InspectExe. In explorer, go to the properties of the exe, and if the manifest was embedded you should have a manifest tab (.Net assemblies will also have this manifest tab).

  7. Try running your program on Vista or later. If UAC is indeed enabled, it should come up with the prompt right away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文