程序如何知道是否以服务运行

soliddream66 2009-10-28 02:58:39
程序有两种启动方式:
一种直接双击启动运行,另一种是以服务运行(服务运行要启动一个服务线程以便启动service main函数)

现在问题来了,程序如何知道是否以服务运行,以便在直接双击启动时候不启动服务线程,而以服务运行的时候启动服务线程。

目前我是在配置文件里面配置是否启动服务现成的,比较麻烦些,我想做的更智能一些。


我有个思路,就是获得process 的 user name信息,我看双击运行的时候,user name 为本地帐户,而服务运行的时候为local system,我将服务运行的获得的process user name与服务注册表的user name配置项比较下。


//
// GetProcessUsername()
//
// Get username and domain from a supplied process handle.
//
// phProcess : is a pointer to the process handle of which
// to get the username from. If phProcess is
// NULL the current process is used.
//
// bIncDomain : if true will prepend the DOMAIN and to
// the returned string.
//
// Returns a reference to a static string containing the
// username or NULL on error.
//
//
char *GetProcessUsername(HANDLE *phProcess, BOOL bIncDomain) {
static char sname[300];
HANDLE tok = 0;
HANDLE hProcess;
TOKEN_USER *ptu;
DWORD nlen, dlen;
char name[300], dom[300], tubuf[300], *pret = 0;
int iUse;

//if phProcess is NULL we get process handle of this
//process.
hProcess = phProcess?*phProcess:GetCurrentProcess();

//open the processes token
if (!OpenProcessToken(hProcess,TOKEN_QUERY,&tok)) goto ert;

//get the SID of the token
ptu = (TOKEN_USER*)tubuf;
if (!GetTokenInformation(tok,(TOKEN_INFORMATION_CLASS)1,ptu,300,&nlen)) goto ert;

//get the account/domain name of the SID
dlen = 300;
nlen = 300;
if (!LookupAccountSid(0, ptu->User.Sid, name, &nlen, dom, &dlen, (PSID_NAME_USE)&iUse)) goto ert;

//copy info to our static buffer
if (dlen && bIncDomain) {
strcpy(sname,dom);
strcat(sname,"");
strcat(sname,name);
} else {
strcpy(sname,name);
}
//set our return variable
pret = sname;

ert:
if (tok) CloseHandle(tok);
return pret;
}




...全文
135 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
fly4free 2009-10-28
  • 打赏
  • 举报
回复
入口不同,在ServiceMain中给一个标识变量,赋予特殊的值

在需要判断的地方,取这个值?

只运行一个实例:很好说。
运行多个实例:标识变量是 进程内的 ,其他进程的该变量相互不会影响……


或者,要想判断是否以 服务的权限运行??那就非查询令牌莫属了吧。
jyh_baoding 2009-10-28
  • 打赏
  • 举报
回复
帮顶
lsvine 2009-10-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 delphiwcdj 的回复:]
直接双击启动不是服务启动吧,把启动服务线程放在ServiceMain中不就可以了
[/Quote]
就这样
oyljerry 2009-10-28
  • 打赏
  • 举报
回复
放ServiceMain等启动,Run函数中再启动服务线程,正常双击,就走正常App启动流程...
delphiwcdj 2009-10-28
  • 打赏
  • 举报
回复
直接双击启动不是服务启动吧,把启动服务线程放在ServiceMain中不就可以了
MoXiaoRab 2009-10-28
  • 打赏
  • 举报
回复
但是以上问题存在于多个进程实例下,所以不够精确
你并没有说该进程只能运行一个实例,所以有如下方法

GetCurrentProcess()然后
GetTokenInformation获得自身权限令牌Token的信息,传入TokenUser功能号,获得一个缓冲区,里面有用户的SID


typedef struct _TOKEN_USER {
SID_AND_ATTRIBUTES User;
} TOKEN_USER, *PTOKEN_USER;

typedef struct _SID_AND_ATTRIBUTES {
PSID Sid; DWORD Attributes;
} SID_AND_ATTRIBUTES, *PSID_AND_ATTRIBUTES;


而Local System的SID是S-1-5-18,管理员的SID不是这个
soliddream66 2009-10-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 tr0j4n 的回复:]
运行的时候,获取如果是服务方式启动的服务名对应的服务的状态不就好了,发现服务不存在,那就是直接运行的。
[/Quote]

有道理
MoXiaoRab 2009-10-28
  • 打赏
  • 举报
回复
运行的时候,获取如果是服务方式启动的服务名对应的服务的状态不就好了,发现服务不存在,那就是直接运行的。

16,551

社区成员

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

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

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