服务程序以管理员身份启动一个进程,被启动进程要能与桌面交互

Willin 2006-12-22 11:31:58
我有一个程序,直接运行则可以修改桌面,做了一个守护服务(发现进程不在就启动),在服务里面创建进程,这个时候进程是SYSTEM用户.用了CreateProcessAsUser()后,总算是Administrator用户了,可是桌面死活改不了,请大家帮忙!
//下面是服务程序中的代码
HANDLE hExp = GetProcessHandle("EXPLORER.EXE");
if(hExp == NULL)
return FALSE;

OpenProcessToken(hExp,TOKEN_ALL_ACCESS,&hToken);
if(hToken == NULL)
return FALSE;

ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";

TCHAR szParameter[10] = {0};

if(CreateProcessAsUser(hToken,lpAppName,szParameter,NULL,
NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
...全文
713 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
Willin 2006-12-28
  • 打赏
  • 举报
回复
按照你所说的,我在客户程序里面调用GetUserName()得到的是当前用户的用户名.我试了一下,如果用服务程序打开客户程序,那么客户程序将不能显示桌面背景,可是如果这时打开IE的属性,点击确定,那么背景就会显示出来.而直接运行客户程序的话,就不会出现问题.
又,我的服务程序是用OpenProcessToken打开EXPLORER.EXE的令牌.在调用CreateProcessAsUser前调用ImpersonateLoggedOnUser,在调用完CreateProcessAsUser()后调用RevertToSelf().
Willin 2006-12-28
  • 打赏
  • 举报
回复
那么我是该用"winsta0\\default"桌面呢?还是用其他的什么桌面呢?
Willin 2006-12-28
  • 打赏
  • 举报
回复
呵呵,问题解决了,在ImpersonateLoggedOnUser之前调用LoadUserProfile(),因为IActiveDesktop在设置桌面的时候会用到一些HKEY_CURRENT_USER键里面的东西,CreateProcessAsUser不负责载入用户配置.

新问题又来了
在XP下测试没问题,怎么在Win2000下又不好使了呢?
wangk 2006-12-27
  • 打赏
  • 举报
回复
应该是不用的,不过你还是在IActiveDesktop输出当前的用户名,看看是不是正确。
Willin 2006-12-26
  • 打赏
  • 举报
回复
线程创建是成功的,我的目的是让服务程序启动一个新进程,而不是要服务程序本身去和桌面交互
Willin 2006-12-26
  • 打赏
  • 举报
回复
我的客户进程里面用的IActiveDesktop来改变桌面,这有关系吗?
LiChenYue 2006-12-25
  • 打赏
  • 举报
回复
这个线程能创建成功吗?
Willin 2006-12-25
  • 打赏
  • 举报
回复
我要的不是与服务程序进行交互,我的目的只是让服务程序在用户登陆后创建一个新进程,这个新进程能够修改用户的桌面.
Willin 2006-12-25
  • 打赏
  • 举报
回复
我的环境是Windows XP,我是用服务程序创建了一个客户程序,这个客户程序使用了IActiveDesktop来设置桌面.我想知道,客户程序里面要加上一些特别的代码吗?

下面是我在创建客户程序的代码

HANDLE hToken;
HDESK hdesk;
HWINSTA hwinsta;
PROCESS_INFORMATION pi;
PSID psid;
STARTUPINFO si;

HANDLE hExp = GetProcessHandle("EXPLORER.EXE");
if(hExp == NULL)
return FALSE;

OpenProcessToken(hExp,TOKEN_ALL_ACCESS,&hToken);
if(hToken == NULL)
return FALSE;

HWND hDesk = GetDesktopWindow();
// BOOL bOk = ImpersonateLoggedOnUser(hToken);
// GenericLog(Info,"ImpersonateLoggedOnUser %s",bOk?"Ok":"Failed");
GenericLog(Info,"Desktop HWND %s",(hDesk == GetDesktopWindow())?"Equal":"Not Equal");


//
// obtain a handle to the interactive windowstation
//
hwinsta = OpenWindowStation(
"winsta0",
FALSE,
READ_CONTROL | WRITE_DAC
);
if (hwinsta == NULL)
return RTN_ERROR;

HWINSTA hwinstaold = GetProcessWindowStation();
GenericLog(Info,"WindowStation Old = %.8x,Curr = %.8x",hwinstaold,hwinsta);
//
// set the windowstation to winsta0 so that you obtain the
// correct default desktop
//
if (!SetProcessWindowStation(hwinsta))
return RTN_ERROR;

//
// obtain a handle to the "default" desktop
//
hdesk = OpenDesktop(
"default",
0,
FALSE,
READ_CONTROL | WRITE_DAC |
DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS
);
if (hdesk == NULL)
return RTN_ERROR;

//
// obtain the logon sid of the user fester
//
if (!ObtainSid(hToken, &psid))
return RTN_ERROR;

//
// add the user to interactive windowstation
//
if (!AddTheAceWindowStation(hwinsta, psid))
return RTN_ERROR;

//
// add user to "default" desktop
//
if (!AddTheAceDesktop(hdesk, psid))
return RTN_ERROR;

//
// free the buffer for the logon sid
//
RemoveSid(&psid);

//
// close the handles to the interactive windowstation and desktop
//
CloseWindowStation(hwinsta);

CloseDesktop(hdesk);
//

ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";

TCHAR szParameter[10] = {0};
// ShellExecute(NULL,"open",lpAppName,NULL,NULL,SW_HIDE);
if(CreateProcessAsUser(hToken,lpAppName,szParameter,NULL,
NULL,FALSE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
GenericLog(Info,"Running %s ....",lpAppName);
UnregisteTimer(TIMER_CONNECT);
RegisteTimer(TIMER_FEEDDOG,3000);
return 1;
}
else
{
GenericLog(Info,"CreateProcess %s Fails ,reason = %d",lpAppName,GetLastError());
}
SetProcessWindowStation(hwinstaold);
return RTN_OK;
Willin 2006-12-22
  • 打赏
  • 举报
回复
牛人呢?
wangk 2006-12-22
  • 打赏
  • 举报
回复
1 CreateService 时 在dwServiceType加上SERVICE_INTERACTIVE_PROCESS标记.
2 http://www.osronline.com/showthread.cfm?link=102869
大熊猫侯佩 2006-12-22
  • 打赏
  • 举报
回复
错误信息是什么?
palmax 2006-12-22
  • 打赏
  • 举报
回复
程序没有错
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
----------------------------------------------------------------
既然你硬要这么说,我也没办法
Willin 2006-12-22
  • 打赏
  • 举报
回复
救命啊
Willin 2006-12-22
  • 打赏
  • 举报
回复
程序没有错,
原因是服务程序是和登陆用户无关的,先于WinLogon,而桌面是和用户相关的,一个用户对应一个或多个桌面——当然,只有一个是可见的。
由于修改桌面的程序是被服务程序启动的,因此无法得到用户的信息。
看了一些牛人说可以用DACL和ACEs来做,可是改过后还是不行。因为我对DACL和ACEs不熟,所以希望能有人指点一下。
palmax 2006-12-22
  • 打赏
  • 举报
回复
在你那个改桌面的进程里打断点调试啊!
调用设置桌面的函数后,GetLastError()看下
qiujian5628 2006-12-22
  • 打赏
  • 举报
回复
mark
0011411 2006-12-22
  • 打赏
  • 举报
回复
牛人还没出现

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧