管理员权限运行程序ShellExecuteex等待进程执行结束

在Shell中执行命令并等待进程结束可以使用/bin/sh -c命令,并在命令后加上&& echo Success || echo Failure来检查命令是否成功执行。

以下是一个使用ShellExecuteEx函数的例子,该函数在Windows中可以用来启动一个进程并等待其结束:

 
cpp#include <windows.h>
#include <shellapi.h>
#include <iostream>

int main() {
SHELLEXECUTEINFO ShExecInfo = {0};
ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
ShExecInfo.fMask = SEE_MASK_NOCLOSEPROCESS;
ShExecInfo.hwnd = NULL;
ShExecInfo.lpVerb = NULL;
ShExecInfo.lpFile = L"cmd.exe";
ShExecInfo.lpParameters = L"/c dir && echo Success || echo Failure";
ShExecInfo.lpDirectory = NULL;
ShExecInfo.nShow = SW_HIDE;
ShExecInfo.hInstApp = NULL;

BOOL result = ShellExecuteEx(&ShExecInfo);
if( result ) {
// 等待进程结束
WaitForSingleObject(ShExecInfo.hProcess, INFINITE);
DWORD dwExitCode;
if(GetExitCodeProcess(ShExecInfo.hProcess, &dwExitCode)) {
std::cout << "Process exit code: " << dwExitCode << std::endl;
}
else {
std::cerr << "Cannot get exit code of the process." << std::endl;
}
// 关闭进程句柄
CloseHandle(ShExecInfo.hProcess);
}
return 0;
}

在这个例子中,SEE_MASK_NOCLOSEPROCESS标志被设置,这样我们可以在ShellExecuteEx调用之后获取进程句柄。然后使用WaitForSingleObject函数等待进程结束。

请注意,这个代码是在Windows环境下编译的,并且需要包含适当的头文件和链接必要的库。在Linux环境下,你可以使用system函数或者popenpclose函数来执行Shell命令,并通过它们的返回值检查命令执行的成功与否。

用VB6代码实现

在 VB6 (Visual Basic 6.0) 中,你可以使用 Shell 函数来执行一个外部命令,并使用 WaitForSingleObject 函数来等待进程结束。然而,VB6 并没有内置的 WaitForSingleObject 函数,因为那是 Windows API 的一部分。为了在 VB6 中使用这个功能,你需要调用 Windows API。以下是一个示例,展示了如何在 VB6 中执行一个外部命令并等待它完成:

首先,你需要定义一些 Windows API 函数。在 VB6 的代码编辑器中,选择“项目”菜单,然后选择“添加模块”。在模块中添加以下声明:

 
vbDeclare Function CreateProcess Lib "kernel32" Alias "CreateProcessA" (
ByVal lpApplicationName As String,
lpCommandLine As String,
lpProcessAttributes As Long,
lpThreadAttributes As Long,
ByVal bInheritHandles As Long,
ByVal dwCreationFlags As Long,
lpEnvironment As Long,
lpCurrentDirectory As String,
lpStartupInfo As STARTUPINFO,
lpProcessInformation As PROCESS_INFORMATION) As Long

Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As Long
bInheritHandle As Long
End Type

Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
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 Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type

Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type

Const INFINITE = -1
Const SYNCHRONIZE = &H100000
Const CREATE_NO_WINDOW = &H8000000

然后,你可以创建一个函数来执行命令并等待其完成:

 
vbFunction ExecuteAndWait(ByVal CommandLine As String) As Boolean
Dim sa As SECURITY_ATTRIBUTES
Dim si As STARTUPINFO
Dim pi As PROCESS_INFORMATION
Dim Result As Long
Dim ExitCode As Long

' 初始化结构
sa.nLength = Len(sa)
sa.lpSecurityDescriptor = 0
sa.bInheritHandle = True

si.cb = Len(si)
si.wShowWindow = 0 ' 隐藏窗口
si.hStdInput = 0
si.hStdOutput = 0
si.hStdError = 0

' 创建进程
Result = CreateProcess(vbNullString, CommandLine, ByVal 0&, ByVal 0&, True, CREATE_NO_WINDOW, ByVal 0&, vbNullString, si, pi)

If Result <> 0 Then
' 等待进程结束
Result = WaitForSingleObject(pi.hProcess, INFINITE)

' 获取退出代码
GetExitCodeProcess pi.hProcess, ExitCode

' 关闭句柄
CloseHandle pi.hProcess
CloseHandle pi.hThread

' 根据退出代码返回结果
ExecuteAndWait = (ExitCode = 0)
Else
' 创建进程失败
ExecuteAndWait = False
End If
End Function

现在你可以调用 ExecuteAndWait 函数来执行一个命令,并等待它完成:

 
vbSub Main()
Dim CommandLine As String
Dim Success As Boolean

' 设置要执行的命令
CommandLine = "cmd.exe /c dir" ' 示例命令,你可以替换为其他命令

' 执行命令并等待完成
Success = ExecuteAndWait(CommandLine)

' 显示结果
If Success Then
MsgBox "命令执行成功"
Else
MsgBox "命令执行失败"
End If
End Sub

请注意,CreateProcess 函数的 lpCommandLine 参数应该是包含完整命令行的字符串,包括任何必要的参数和路径。在上面的例子中,我使用了 cmd.exe /c dir 作为示例命令,它会启动命令提示符并执行 dir 命令。你可以

VB6 ShellExecuteEx,如何添加RUNAS参数

在 VB6 中使用 ShellExecuteEx 函数时,如果你想要以管理员权限运行程序,你需要设置 lpVerb 成员为 "runas"。这将尝试以提升的权限执行指定的程序。请注意,runas 动词在 Windows Vista 及更高版本中可用,并且用户可能会看到一个 UAC(用户帐户控制)提示来确认权限提升。

以下是如何在 VB6 中使用 ShellExecuteEx 函数并添加 RUNAS 参数的示例:

 
vbDeclare Function ShellExecuteEx Lib "shell32.dll" Alias "ShellExecuteExA" (lpExecInfo As SHELLEXECUTEINFO) As Long

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
lpClass As String
hkeyClass As Long
dwHotKey As Long
hIcon As Long
hProcess As Long
End Type

Const SEE_MASK_NOCLOSEPROCESS = &H40

Sub RunAsAdmin()
Dim sei As SHELLEXECUTEINFO
Dim Result As Long

' 初始化SHELLEXECUTEINFO结构
sei.cbSize = Len(sei)
sei.fMask = SEE_MASK_NOCLOSEPROCESS
sei.hwnd = Me.hwnd ' 使用当前窗体的句柄
sei.lpVerb = "runas" ' 使用RUNAS动词
sei.lpFile = "C:\path\to\your\program.exe" ' 要执行的程序路径
sei.lpParameters = "" ' 程序参数,如果需要的话
sei.lpDirectory = "" ' 初始目录,如果需要的话
sei.nShow = SW_SHOWNORMAL ' 显示方式

' 执行ShellExecuteEx
Result = ShellExecuteEx(sei)

' 检查是否成功执行
If Result > 32 Then
' 进程句柄在sei.hProcess中,如果需要的话可以使用它
' 例如,你可以使用WaitForSingleObject来等待进程结束
' ...

' 关闭进程句柄(如果不再需要)
CloseHandle sei.hProcess
Else
MsgBox "无法以管理员权限运行程序。"
End If
End Sub

在这个例子中,lpVerb 被设置为 "runas",这将尝试以管理员权限运行指定的 lpFile。如果成功,ShellExecuteEx 会返回一个大于 32 的值,并且 hProcess 成员会被填充,以便你可以后续操作进程(例如等待它结束)。如果 ShellExecuteEx 返回一个小于或等于 32 的值,那么调用就失败了。

请注意,由于 UAC 的限制,不是所有的程序都可以或应该使用 runas 动词来运行。而且,如果用户拒绝提升权限请求,程序将不会以管理员权限运行。

12:12

VB6用ShellExecuteEx如何以非管理员权限运行EXE

在 VB6 中使用 ShellExecuteEx 函数来以非管理员权限运行一个 .exe 文件实际上是一个有点误导的概念,因为 ShellExecuteEx 本身并不直接控制权限级别。当你使用 ShellExecuteEx 时,它会按照调用它的应用程序的权限级别来执行指定的文件。如果 VB6 应用程序以管理员权限运行,那么 ShellExecuteEx 也将尝试以相同的权限级别执行文件。

如果你想确保以非管理员权限运行一个 .exe 文件,你需要确保你的 VB6 应用程序本身不是以管理员权限运行的。这通常意味着你需要以标准用户身份登录到 Windows,或者确保你的应用程序的快捷方式或启动配置没有设置为“以管理员身份运行”。

不过,如果你确实需要以编程方式降低权限级别(尽管这通常不是一个推荐的做法,因为它可能导致权限不足的问题),你可能需要创建一个辅助进程,该进程以较低的权限级别运行,并通过某种形式的进程间通信(如命名管道、套接字或共享内存)与你的主应用程序通信。

但是,在大多数情况下,你应该尽量避免需要降低权限级别的情况。相反,你应该设计你的应用程序以便它可以在标准用户权限下运行,或者提供适当的用户界面来提示用户以管理员身份运行特定的操作(如果确实需要)。

如果你只是想确保你的 VB6 应用程序不以管理员身份运行,你可以检查它的快捷方式属性或启动配置,确保没有设置“以管理员身份运行”选项。另外,确保你的应用程序的清单文件(如果存在)没有请求更高的执行级别。

如果你仍然需要在 VB6 中使用 ShellExecuteEx 并确保以非管理员权限运行,你可能需要创建一个单独的、权限较低的服务或应用程序来执行这项任务,并通过某种机制与你的 VB6 应用程序进行通信。但请注意,这样做可能会引入额外的复杂性和安全风险。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

专注VB编程开发20年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值