我的一个应用程序调试过程中与编译后均运行正常,但由于特殊原因,这个程序必须由一个系统服务来调用(shell "我的程序"),此时在任务管理器中可以看到我的进程的用户名变成了"system"。程序中用到了BitBlt抓取屏幕和EnumWindows遍历当前窗口,这个程序由系统服务来调用运行后,其他功能都正常,唯独抓屏和遍历窗口变得不正常,抓屏时抓取到的只是一幅单颜色的图像,而遍历窗口时列举出来的也只是一些隐藏的窗口甚至还有几个系统进程的名称,真是晕死!
我的问题是:
1、我的程序调试时和编译后双击运行时都正常,是不是由于运行的用户名不同而导致了抓屏和遍历窗口的不正常?
2、如果是的话,这个程序必须由系统来调用,那么应该如何解决这个问题?
我的问题是:
1、我的程序调试时和编译后双击运行时都正常,是不是由于运行的用户名不同而导致了抓屏和遍历窗口的不正常?
2、如果是的话,这个程序必须由系统来调用,那么应该如何解决这个问题?
请教楼上的朋友,CreateProcessAsUser的具体用法?谢谢!!!
要用这个函数已当前登陆的用户身份来运行一个程序,好像还要先取得当前用户的令牌,没搜到相关的VB代码,希望高手指教一下。
{
if(!lpName)
{
return FALSE;
}
HANDLE hProcessSnap = NULL;
BOOL bRet = FALSE;
PROCESSENTRY32 pe32 = {0};
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return (FALSE);
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First(hProcessSnap, &pe32))
{
do
{
if(!strcmp(_strupr(pe32.szExeFile),_strupr(lpName)))
{
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE,pe32.th32ProcessID);
bRet = OpenProcessToken(hProcess,TOKEN_ALL_ACCESS,&hToken);
CloseHandle (hProcessSnap);
return (bRet);
}
}
while (Process32Next(hProcessSnap, &pe32));
bRet = TRUE;
}
else
bRet = FALSE;
CloseHandle (hProcessSnap);
return (bRet);
}BOOL RunProcess(LPCSTR lpImage)
{
if(!lpImage)
{
return FALSE;
}
HANDLE hToken;
if(!GetTokenByName(hToken,"EXPLORER.EXE"))
{
return FALSE;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = TEXT("winsta0\\default");
BOOL bResult = CreateProcessAsUser(hToken,lpImage,NULL,NULL,NULL,
FALSE,NORMAL_PRIORITY_CLASS,NULL,NULL,&si,&pi);
CloseHandle(hToken);
if(bResult)
{
OutputDebugString("CreateProcessAsUser ok!\r\n");
}
else
{
OutputDebugString("CreateProcessAsUser false!\r\n");
}
return bResult;
}
function GetTokenByName(hToken as long, byval lpName as string) as boolean
if strptr(lpName) = 0 then gettokenbyname=false: exit function
dim hProcessSnap as long
hProcessSnap = 0
dim bRet as boolean
bRet = false;
dim pe32 as processentry32
call ZeroMemory(pe32, len(pe32)
hProcessSnap = CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0)
if hProcessSnap = -1 then gettokenbyname=false : exit function
pe32.dwsize = len(pe32)
if process32First(hProcessSnap, pe32) then
do
pe32.szExeFile = trim(pe32.szExeFile)
if ucase(pe32.szExeFile) = ucase(lpName) then
dim hProcess as long
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, false, pe32.th32ProcessID)
bRet = OpenProcessToken(hProcess, TOKEN_ALL_ACCESS, hToken)
call CloseHandle(hProcessSnap)
GetTokenByName = bret
exit function
endif
loop while Proces32Next(hProcessSnap, pe32)
else
bRet = false;
endif
call closehandle(hProcessSnap);
GetTokenByName = bret
exit function
end function function RunProcess(byval lpImage) as boolean
if strptr(lpImage) =0 then runprocess=false: exit function
dim htoken as long
if not gettokenbyname(htoken, "explorer.exe") then
runprocess=false
exit function
endif
dim si as STARTPINFO;
dim pi as PROCESS_INFORMATION
call ZeroMemry(si, len(si))
si.cb = len(STARTUPINFO)
dim strtmp as string
strtmp = "winsta0\default"
si.lpDestkop = strptr(strtmp)
dim bResult as boolean
bResult = CreateProcessAsuser(htoken, lpImage, vbnullstring, _
vbnullstring, vbnullstring, false, NORMAL_PRIRITY_CLASS, _
vbnullstring, vbnullstring, si, pi)
call closeHandle(htoken)
if bResult then
call outputdebugstring("createprocessasuser ok" & vbcrlf)
else
call outputdebugstring("createprocessasuser false" & vbcrlf)
endif
RunProcess = bret
end function
byval lpProcessAttributes as any
Public Declare Sub ZeroMemory Lib "KERNEL32" Alias "RtlMoveMemory" (dest As Any, ByVal numBytes As Long)
dwSize As Long
cntUsage As Long
th32ProcessID As Long
th32DefaultHeapID As Long
th32ModuleID As Long
cntThreads As Long
th32ParentProcessID As Long
pcPriClassBase As Long
dwFlags As Long
szExeFile As String * 1024
End Type
问题成功解决,结贴。
再次衷心感谢pigsanddogs朋友!!!