一段在服务中创建进程的源代码,没看明白思路,恳请各位给指点迷津~~

danxuezx 2010-05-18 04:50:03
下面的代码经过验证是好的,现在没明白为什么要经过这么多步骤,这些步骤都有什么含义呢?
完整示例代码:http://blog.csdn.net/cmkyec/archive/2010/01/12/5180511.aspx
HANDLE ProcessHandle = NULL;   
HANDLE CurrentToken = NULL;
HANDLE TokenDup = NULL;
ProcessHandle = GetCurrentProcess();
if (!OpenProcessToken(ProcessHandle,TOKEN_ALL_ACCESS,¤tToken))
{
int d = GetLastError();
WriteLogString(L"OpenProcessToken failed.Last Error is:%d",d);
return;
}
if (!DuplicateTokenEx(CurrentToken,MAXIMUM_ALLOWED,NULL,SecurityIdentification,TokenPrimary,&TokenDup))
{
int dd = GetLastError();
WriteLogString(L"DuplicateTokenEx failed.Last error is:%d",dd);
return;
}
DWORD dwSessionID = WTSGetActiveConsoleSessionId();
WriteLogString(L"WTSGetActiveConsoleSessionId:%d",dwSessionID);
if (!SetTokenInformation(TokenDup,TokenSessionId,&dwSessionID,sizeof(DWORD)))
{
int ddd = GetLastError();
WriteLogString(L"SetTokenInformation failed.Last error is:%d",ddd);
return;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(STARTUPINFO));
ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
si.cb = sizeof(STARTUPINFO);
si.lpDesktop = L"WinSta0\\Default";

LPVOID pEnv = NULL;
DWORD dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE | CREATE_UNICODE_ENVIRONMENT;
if (!CreateEnvironmentBlock(&pEnv,TokenDup,FALSE))
{
int error1 = GetLastError();
WriteLogString(L"CreateEnvironmentBlock failed.Last error is:%d",error1);
return;
}

if (!CreateProcessAsUser(TokenDup,L"C:\\log.exe",NULL,NULL,NULL,FALSE,dwCreationFlags,pEnv,NULL,&si,&pi))
{
int error2 = GetLastError();
WriteLogString(L"CreateProcessAsUser failed.Last error is:%d",error2);
return;
}


...全文
487 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
danxuezx 2010-05-21
  • 打赏
  • 举报
回复
多谢大家给我这么多悉心的指导。我决定还是把相关的东西放到驱动加载时完成。因为我的比较特殊,用服务等其他方法可能也能办到,但我觉得这些可能都不是最为合理的做法。
sanguomi 2010-05-21
  • 打赏
  • 举报
回复
你把EXE的代码写到服务里不就行了,虽然可能有些地方服务有些不同,但还是都能找到替代的方法
sanguomi 2010-05-21
  • 打赏
  • 举报
回复
感觉楼主弄复杂了
cnzdgs 2010-05-21
  • 打赏
  • 举报
回复
即使设置了密码登陆,服务也未必比run键下的早。在加载run键下程序前执行自己的程序的办法倒是可以想出一些,不过感觉都不太好,就不提了。

CreateProcess创建进程是没问题的,你自己再找原因吧。

服务组件(EXE)可以被一般用户身份的进程调用,在服务进程中执行操作,调用方法没有特别之处,不过看起来不适合LZ目前的问题。
danxuezx 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 wangk 的回复:]
XP以后的服务为了增强用户体验,只要不是系统关键服务,或者被关键服务依赖的话,一般情况下就会用LazyLoad的方式,导致服务不一定比run键下的早。

我不知道你为什么要比run键下的早。也许有其他更简单的方式实现你的需求。

另外可以用注册表控制加载顺序(包括服务和驱动)。参考文章: How To Control Device Driver Load Order
[/Quote]
多谢您的指点。我需要比run键下的早是因为极有可能run下的某个文件依赖于我,所以我要比它先起来。
我已经改到驱动里面了。回头我再来看这块有没有简单点的方法。
wangk 2010-05-20
  • 打赏
  • 举报
回复
XP以后的服务为了增强用户体验,只要不是系统关键服务,或者被关键服务依赖的话,一般情况下就会用LazyLoad的方式,导致服务不一定比run键下的早。

我不知道你为什么要比run键下的早。也许有其他更简单的方式实现你的需求。

另外可以用注册表控制加载顺序(包括服务和驱动)。参考文章: How To Control Device Driver Load Order
尹成 2010-05-20
  • 打赏
  • 举报
回复
创建用户进程以保证服务进程和当前进程的一致性
danxuezx 2010-05-20
  • 打赏
  • 举报
回复

服务程序不一定在用户登录前加载,如果系统启动后立即登录用户,进到桌面后可能服务还没有加载。
您说的这一点我已经验证到了。如果一个没有设置密码的用户,一个AutoStart类型的服务里做的事情完全有可能比注册表run键下设置的exe启动的晚。如果设置了密码登陆的话,服务里一定比run键下的早。

如果不考虑用户登录,直接用CreateProcess加载进程即可,不用这么麻烦。
我有试过试图在服务里的service main里初始化服务之后用CreateProcess创建一个进程,用来执行这个exe,结果发现服务启动了,但是exe没有被执行。用CreateProcess创建进程的时候我只设置了命令行等必须要设置的参数。

另外,用服务的方式(服务加载驱动的方式)有没有办法做到让一件事情一定比用户在注册表的任何地方设置的开机自启动做的事情发生的早呢?目前我感觉没有方法。因为服务的启动类型最早也就是AutoStart了,而AutoStart类型的在没有用户密码的时候有可能比run键下的更晚。
你妹的特盗不 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 jameshooo 的回复:]
把你的程序做成服务类型的进程外组件,让RUN里面的程序调用你的组件不就行了吗
[/Quote]
讲解下噻

主是不明白,怎么让别的程序起来后就要调用我的DLL
danxuezx 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 wangk 的回复:]
这样的话其实直接用run下的某个执行文件用QueryServiceStatus探测你的Service的信息,等待加载也是一个解决方法
[/Quote]
其实我并不知道run下哪个exe可能会依赖我。


[Quote=引用 19 楼 jameshooo 的回复:]
把你的程序做成服务类型的进程外组件,让RUN里面的程序调用你的组件不就行了吗
[/Quote]
您说的这个方法现在我还不懂……汗
jameshooo 2010-05-20
  • 打赏
  • 举报
回复
把你的程序做成服务类型的进程外组件,让RUN里面的程序调用你的组件不就行了吗
cnzdgs 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 danxuezx 的回复:]
也就是说,由服务程序在当前活动session中以服务权限加载进程的话并不能让此进程在用户登录之前完成它应该做的事情了?
[/Quote]
服务程序不一定在用户登录前加载,如果系统启动后立即登录用户,进到桌面后可能服务还没有加载。
如果不考虑用户登录,直接用CreateProcess加载进程即可,不用这么麻烦。
wangk 2010-05-20
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 danxuezx 的回复:]
我需要比run键下的早是因为极有可能run下的某个文件依赖于我,所以我要比它先起来。
[/Quote]

这样的话其实直接用run下的某个执行文件用QueryServiceStatus探测你的Service的信息,等待加载也是一个解决方法
fangchao918628 2010-05-19
  • 打赏
  • 举报
回复
cnzdgs 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 danxuezx 的回复:]
刚看到一篇不错的文章,里面详细的讲解了这个问题。
Windows Vista 交互式服务编程

我的问题是这样产生的,本来我有一个驱动和一个配套的APP,驱动时开机加载的,APP需要开机启动。一开始是放在Run键下,后来发现有问题,所以准备做成服务。本来先前的app里做的事情完全可以在服务里完成而不需要和APP交互,只是我懒不想再驱动中再修改相应的代码,所以准备在服务里创建一个用户进程。
看了上面的文章,服务和APP的交互竟然如此麻烦,我还是在服务里把事情做完得了。

为啥我想偷个懒就这么难捏~~~~
[/Quote]
这篇文章讲的不是服务程序与应用程序交互,而是由服务程序在当前活动session中以服务权限加载进程。
这几行代码根本算不上麻烦,而且一半以上是写错误日志的。另外,这段代码并不完整,句柄都没有关,还有,这段代码没有体现出在什么时候执行,如果把相关代码补充上,比这一段还要长。
jameshooo 2010-05-19
  • 打赏
  • 举报
回复
作用就是在新的SESSION环境中创建一个自身进程的副本,除SESSION外其它上下文都相同,避免跨SESSION时遇到的很多限制(比如桌面交互),多数情况下不需要这样做,因为通常用户桌面只会启动一个,远程桌面才需要启动第二个SESSION。即使有多个SESSION,也很少有创建副本进程的需求。
danxuezx 2010-05-19
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 cnzdgs 的回复:]
这篇文章讲的不是服务程序与应用程序交互,而是由服务程序在当前活动session中以服务权限加载进程。
这几行代码根本算不上麻烦,而且一半以上是写错误日志的。另外,这段代码并不完整,句柄都没有关,还有,这段代码没有体现出在什么时候执行,如果把相关代码补充上,比这一段还要长。
[/Quote]
也就是说,由服务程序在当前活动session中以服务权限加载进程的话并不能让此进程在用户登录之前完成它应该做的事情了?
danxuezx 2010-05-18
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 sanguomi 的回复:]
你APP里能执行的,你改到服务里 运气好一点没有,运气不好,也很多问题,特别是VISTA
一样要考虑 不同 session, 如果你只是运行一个可以运行的EXE,我觉得还是运行个EXE比较好
[/Quote]
服务不是运行在system账户下吗,这样的话应该与用户账户无关吧,如果是这样就不用考虑session的问题了
sanguomi 2010-05-18
  • 打赏
  • 举报
回复
你APP里能执行的,你改到服务里 运气好一点没有,运气不好,也很多问题,特别是VISTA
一样要考虑 不同 session, 如果你只是运行一个可以运行的EXE,我觉得还是运行个EXE比较好
danxuezx 2010-05-18
  • 打赏
  • 举报
回复
多谢5L朋友的指点。

[Quote=引用 4 楼 wangk 的回复:]
Vista以后版本服务是跑在session0,直接运行的话在当前活动的用户是看不到log.exe的界面,如果是有界面的话,那么让活动用户看到它的界面才是最主要的原因吧。
[/Quote]
刚看到一篇不错的文章,里面详细的讲解了这个问题。
Windows Vista 交互式服务编程

我的问题是这样产生的,本来我有一个驱动和一个配套的APP,驱动时开机加载的,APP需要开机启动。一开始是放在Run键下,后来发现有问题,所以准备做成服务。本来先前的app里做的事情完全可以在服务里完成而不需要和APP交互,只是我懒不想再驱动中再修改相应的代码,所以准备在服务里创建一个用户进程。
看了上面的文章,服务和APP的交互竟然如此麻烦,我还是在服务里把事情做完得了。

为啥我想偷个懒就这么难捏~~~~
加载更多回复(5)

16,472

社区成员

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

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

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