CreateProcessAsUser返回值为0,但是进程未启动,是怎么回事
时间: 2024-05-17 19:18:05 浏览: 8
CreateProcessAsUser() 函数返回值为 0 可能有多种原因导致进程未启动。以下是一些可能的原因:
1. 访问权限问题:在使用 CreateProcessAsUser() 函数启动进程时,可能需要具有管理员权限或其他特定的权限。请确保您的程序具有足够的权限来执行此操作。
2. 安全问题:如果您的程序在受保护的会话中运行,可能需要使用与会话 ID 相应的安全令牌才能启动进程。请确保您已正确设置安全令牌。
3. 参数错误:在调用 CreateProcessAsUser() 函数时,可能会出现参数错误。请确保您已正确指定了进程路径、命令行参数等参数。
4. 路径问题:在指定进程路径时,可能需要使用绝对路径或者相对路径。请确保您已正确指定路径。
5. 环境变量问题:如果您的进程依赖于环境变量,请确保您已正确设置环境变量。
您可以通过检查错误代码来获取更多信息,以确定造成此问题的确切原因。同时,您还可以考虑使用其他工具或方法来启动您的进程,并且在启动前仔细检查上述因素。
相关问题
CreateProcessAsUser 函数返回成功,但是程序未启动
这种情况下,可以考虑使用 GetLastError 函数来获取更多的错误信息。你可以在函数调用失败后使用 GetLastError 函数获取错误码,并将其转化为对应的错误信息。
在此之前,你可以先检查一下传递给 CreateProcessAsUser 函数的参数是否正确。比如:
1. 检查 strExePath 参数是否指向一个存在的可执行文件路径。
2. 检查 lpDesktop 参数是否指向一个有效的桌面名称。
3. 检查 STARTUPINFO 结构体中的其他参数是否正确设置,比如 wShowWindow 和 dwFlags。
如果以上参数都正确,仍然无法启动程序,可以尝试使用 GetLastError 函数查找具体的错误信息。
CreateProcessAsUser,C#写的windows服务弹框提示消息或者启动子进程
您好,针对您的问题,可以使用以下代码实现:
```csharp
using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Windows.Forms;
namespace WindowsServiceDialog
{
public partial class ServiceDialog : Form
{
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool CreateProcessAsUser(
IntPtr hToken,
string lpApplicationName,
string lpCommandLine,
ref SECURITY_ATTRIBUTES lpProcessAttributes,
ref SECURITY_ATTRIBUTES lpThreadAttributes,
bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string lpCurrentDirectory,
ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool OpenProcessToken(
IntPtr ProcessHandle,
uint DesiredAccess,
out IntPtr TokenHandle);
[DllImport("userenv.dll", SetLastError = true)]
private static extern bool CreateEnvironmentBlock(
out IntPtr lpEnvironment,
IntPtr hToken,
bool bInherit);
[DllImport("userenv.dll", SetLastError = true)]
private static extern bool DestroyEnvironmentBlock(
IntPtr lpEnvironment);
private const uint TOKEN_QUERY = 0x0008;
private const uint TOKEN_DUPLICATE = 0x0002;
private const uint TOKEN_ASSIGN_PRIMARY = 0x0001;
private const uint GENERIC_ALL_ACCESS = 0x10000000;
private const uint CREATE_NEW_CONSOLE = 0x00000010;
private const uint CREATE_UNICODE_ENVIRONMENT = 0x00000400;
private const int SW_SHOW = 5;
private IntPtr _userToken;
private IntPtr _envBlock;
[StructLayout(LayoutKind.Sequential)]
private struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public uint dwProcessId;
public uint dwThreadId;
}
[StructLayout(LayoutKind.Sequential)]
private struct SECURITY_ATTRIBUTES
{
public int nLength;
public IntPtr lpSecurityDescriptor;
public bool bInheritHandle;
}
[StructLayout(LayoutKind.Sequential)]
private struct STARTUPINFO
{
public int cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public uint dwX;
public uint dwY;
public uint dwXSize;
public uint dwYSize;
public uint dwXCountChars;
public uint dwYCountChars;
public uint dwFillAttribute;
public uint dwFlags;
public short wShowWindow;
public short cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
public ServiceDialog()
{
InitializeComponent();
}
private void ServiceDialog_Load(object sender, EventArgs e)
{
// 获取当前用户的令牌
WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
if (currentUser != null)
{
if (!OpenProcessToken(currentUser.Token, TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_QUERY, out _userToken))
{
MessageBox.Show("无法获取当前用户的令牌!");
}
}
}
private void btnShowDialog_Click(object sender, EventArgs e)
{
MessageBox.Show("Hello World!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void btnStartProcess_Click(object sender, EventArgs e)
{
if (_userToken != IntPtr.Zero)
{
// 构造启动进程的信息结构体
STARTUPINFO startupInfo = new STARTUPINFO();
startupInfo.cb = Marshal.SizeOf(startupInfo);
startupInfo.lpDesktop = "winsta0\\default";
startupInfo.dwFlags = 0x00000100;
// 创建进程的安全属性
SECURITY_ATTRIBUTES processAttributes = new SECURITY_ATTRIBUTES();
processAttributes.nLength = Marshal.SizeOf(processAttributes);
processAttributes.bInheritHandle = true;
// 创建线程的安全属性
SECURITY_ATTRIBUTES threadAttributes = new SECURITY_ATTRIBUTES();
threadAttributes.nLength = Marshal.SizeOf(threadAttributes);
IntPtr environmentPtr = IntPtr.Zero;
if (CreateEnvironmentBlock(out environmentPtr, _userToken, false))
{
_envBlock = environmentPtr;
}
else
{
MessageBox.Show("无法创建环境块!");
}
// 启动进程
PROCESS_INFORMATION processInfo = new PROCESS_INFORMATION();
if (!CreateProcessAsUser(
_userToken,
null,
"notepad.exe",
ref processAttributes,
ref threadAttributes,
false,
CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT,
_envBlock,
null,
ref startupInfo,
out processInfo))
{
MessageBox.Show("无法启动进程!");
}
DestroyEnvironmentBlock(_envBlock);
}
else
{
MessageBox.Show("未获取到当前用户的令牌!");
}
}
private void ServiceDialog_FormClosing(object sender, FormClosingEventArgs e)
{
if (_userToken != IntPtr.Zero)
{
CloseHandle(_userToken);
}
}
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr hObject);
}
}
```
以上代码实现了一个 Windows 窗体程序,其中包含两个按钮,分别用于弹出提示框和启动子进程。在服务中使用时,可以将此程序安装为 Windows 服务,并在需要弹出提示框或启动子进程的时候,调用相应的方法即可。需要注意的是,如果要启动的子进程需要与当前用户交互,需要获取当前用户的令牌,并使用 `CreateProcessAsUser` 函数创建进程。