user-0 提问: MFC写了一个程序，现在怎么才能把他当做服务启动？

回复:
user: user-1
content: 解释一下为什么QQ不用服务？

user: user-2
content: 引用 25 楼 zhao4zhong1 的回复:[quote=引用 21 楼 my3439955 的回复:] 开发服务要按照服务的格式来做，不是所一个exe注册为服务就可以当做服务的。  另外，针对帖子中的一些观点：  1、服务是必要的，有存在的必要，并非是隐藏界面的exe程序可代替的。服务的优势在于自守护，权限高，开机前运行等  2、服务的扩展名并非是.sys。sys是内核驱动，可以以核心服务的形式加载，但用户态的服务还是exe程序 对于类似360、QQ、迅雷、……这些使用驱动＋隐藏窗口进程的软件系统来说，服务的优势（自守护，权限高，开机前运行等）都形同虚设。 当然我不是说服务一无是处。我只是强调隐藏窗口的进程更方便管理、调试、维护。 参考上面19楼我贴的调试服务的方法有多麻烦就略见一斑了。[/quote]  调试服务有什么麻烦的，无非就是挂接调试器。再说，开发阶段可以通过参数控制在用户态调试程序，发布的时候再用服务来发布即可。如果因此而放弃服务，那岂不是因噎废食吗

user: user-1
content: 引用 21 楼 my3439955 的回复:开发服务要按照服务的格式来做，不是所一个exe注册为服务就可以当做服务的。  另外，针对帖子中的一些观点：  1、服务是必要的，有存在的必要，并非是隐藏界面的exe程序可代替的。服务的优势在于自守护，权限高，开机前运行等  2、服务的扩展名并非是.sys。sys是内核驱动，可以以核心服务的形式加载，但用户态的服务还是exe程序 对于类似360、QQ、迅雷、……这些使用驱动＋隐藏窗口进程的软件系统来说，服务的优势（自守护，权限高，开机前运行等）都形同虚设。 当然我不是说服务一无是处。我只是强调隐藏窗口的进程更方便管理、调试、维护。 参考上面19楼我贴的调试服务的方法有多麻烦就略见一斑了。

user: user-0
content: 之前就是放在Run中了，每个用户登录的时候都启动一次。  加上这段代码应该可以只启动一次了，但是还是不如像服务那样可以不登陆就启动。不过还是很感谢，毕竟比原来进了一步    引用 9 楼 zhao4zhong1 的回复:改为放在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run下。 注意别被防火墙或杀毒软件屏蔽了。 使用临时文件跨进程锁演示： #include <io.h> #include <fcntl.h> #include <sys\stat.h> #include <share.h> #include <stdio.h> int main() {     int fh;     fh=_sopen("C:\\my_flag.txt",_O_CREAT|_O_TEMPORARY,_SH_DENYRW,_S_IREAD | _S_IWRITE);     if (-1==fh) {         printf("ReEnter,Exit\n");         return 1;     }     printf("Enter\n");     getchar();     _close(fh);     printf("Leave\n");     return 0; }

user: user-3
content: 还有，你说的，和美国的一个映射磁盘文件同步，至少我没遇到过怎么高端的项目。井底之蛙的我就不做评论了

user: user-3
content: 不好意思，我也是激动了，除了1楼的回复外， 我不太赞同文件同步，除了速度外(毕竟要和存储IO打交道，相对于内存操作来说)，还有很多要考虑的因素。 如文件被误删了，或者其他需要访问的东西(杀软，搜索类东西（内容搜索）)等，甚至，内核层和应用层同步。 我举个例子 前段时间，写了个登录gina程序，需要硬件鉴定身份，登录后，需要检测硬件是否存在（硬件可能还不完善，已经被打开的情况下，再次打开，会卡住，其他公司的，只能反馈问题，无法修改硬件相关的驱动等）。这个时候，gina程序和检测程序，需要用一个同步的东西，用global\*的mutex或者其它的事件，信号，就可以了，也都很方便。如果用文件，就会麻烦很多（我的模块在system32下面，检测模块可能随安装包，在安装目录下面）。特别是到了win7下，(win7 已经不使用gina了，确切说是vista以后就不适用gina了)，权限很控制的更多了，比如，一个普通程序，访问windows/system32目录下的东西等等，反正限制多了

user: user-2
content: 开发服务要按照服务的格式来做，不是所一个exe注册为服务就可以当做服务的。  另外，针对帖子中的一些观点：  1、服务是必要的，有存在的必要，并非是隐藏界面的exe程序可代替的。服务的优势在于自守护，权限高，开机前运行等  2、服务的扩展名并非是.sys。sys是内核驱动，可以以核心服务的形式加载，但用户态的服务还是exe程序

user: user-1
content: 引用 18 楼 user-3 的回复:有病吧，不和你一般见识 对不起！我刚才失态了。

user: user-1
content: 用调试器(OD,WINDBG等)调试服务程序 To debug the initialization code of a service application, the debugger must be attached when the service is started. This is accomplished by creating a registry key:  HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\ProgramName   The ProgramName is the image file for the service application you are debugging. Do not specify a path. For example, the ProgramName might look like MyService.exe.  Under this key create a string data value called Debugger. The value of this string should be set to the full path of the debugger that will be used. For example,  c:\Debuggers\windbg.exe    In addition to setting this registry key, the service application must be marked as "interactive". This allows your service to interact with the desktop, and allows the debugger window to appear on your desktop.  This again requires modifying a registry key: you must bitwise-or the type entry for your service with 0x100 (this is the value for SERVICE_INTERACTIVE_PROCESS according to Winnt.h). The exact location and name of this registry entry varies. For example:  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyServiceKey   Finally, you need to adjust the service application timeout. Otherwise, the service application will kill the debugger within 20 seconds after starting. Adjusting the timeout involves setting an entry in the following registry key:  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control   Under this key, create a DWORD data value called ServicesPipeTimeout. Set this entry to the amount of time in milliseconds that you want the service to wait before timing out. For example, 60,000 is one minute, while 86,400,000 is 24 hours.  设置ServicesPipeTimeout后需要重启系统才生效  Now, when the service is started, the debugger will also start. When the debugger starts, it will stop at the initial process breakpoint, before the service has begun running. This allows you to set breakpoints or otherwise configure your debugging session to let you monitor the startup of your service. Another option is to place calls to the DebugBreak function in your service from the point at which you would like to break into the debugger. (For more information, see DebugBreak in the Platform SDK documentation.)  If your service is running with other services in a Service Host Process, you may need to isolate the service into its own Service Host Process.

user: user-3
content: 有病吧，不和你一般见识

user: user-1
content: 你凭啥？ 骂你还不能指着你鼻子骂？那我指谁？指我自己鼻子？ 有本事你找版主或黑客把这个帖子删了！

user: user-3
content: 引用 15 楼 zhao4zhong1 的回复:[quote=引用 12 楼 user-3 的回复:] [quote=引用 11 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 user-3 的回复:] 看到上面的一些回复，我也想说两句 1、内核程序，和应用层服务，不一样(*.sys，*.exe) 2、楼主把程序，改成服务程序就好了 3、用文件同步，呵呵一下，那么多的同步方式！比如防止多次启动，用MUTEX，加上个“Global\*”，即可全局通用了 The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users.  Windows 2000:  If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character. The object can be created in a private namespace. For more information, see Object Namespaces [/quote] 引用我回复，要经过我批准的[/quote] 我引用的意思不是支持你，而是提醒你：Global\依赖Terminal Services才能跨多个用户。[/quote] 我不需要你提醒，不要乱引用我回复

user: user-1
content: 引用 12 楼 user-3 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] [quote=引用 10 楼 user-3 的回复:] 看到上面的一些回复，我也想说两句 1、内核程序，和应用层服务，不一样(*.sys，*.exe) 2、楼主把程序，改成服务程序就好了 3、用文件同步，呵呵一下，那么多的同步方式！比如防止多次启动，用MUTEX，加上个“Global\*”，即可全局通用了 The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users.  Windows 2000:  If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character. The object can be created in a private namespace. For more information, see Object Namespaces [/quote] 引用我回复，要经过我批准的[/quote] 我引用的意思不是支持你，而是提醒你：Global\依赖Terminal Services才能跨多个用户。

user: user-1
content: 共享临时文本文件这种进程之间的通讯方法相比其它方法的优点有很多，下面仅列出我现在能想到的： ·进程之间松耦合 ·进程可在同一台机器上，也可跨机，跨操作系统，跨硬件平台，甚至跨国。 ·方便调试和监视，只需让第三方或人工查看该临时文本文件即可。 ·方便在线开关服务，只需删除或创建该临时文本文件即可。 ·方便实现分布式和负载均衡。 ·方便队列化提供服务，而且几乎不可能发生队列满的情况（除非硬盘空间满） ·……

user: user-1
content: 我不认为用Mutex比用文件同步更方便、更靠谱、更跨平台，跨机器、跨网络（别忘了映射网络驱动器可以在中国映射在美国的另一台机器上的文件，Mutex能吗？！）。  欢迎拍砖！

user: user-3
content: 引用 11 楼 zhao4zhong1 的回复:[quote=引用 10 楼 user-3 的回复:] 看到上面的一些回复，我也想说两句 1、内核程序，和应用层服务，不一样(*.sys，*.exe) 2、楼主把程序，改成服务程序就好了 3、用文件同步，呵呵一下，那么多的同步方式！比如防止多次启动，用MUTEX，加上个“Global\*”，即可全局通用了 The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users.  Windows 2000:  If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character. The object can be created in a private namespace. For more information, see Object Namespaces [/quote] 引用我回复，要经过我批准的

user: user-1
content: 引用 10 楼 user-3 的回复:看到上面的一些回复，我也想说两句 1、内核程序，和应用层服务，不一样(*.sys，*.exe) 2、楼主把程序，改成服务程序就好了 3、用文件同步，呵呵一下，那么多的同步方式！比如防止多次启动，用MUTEX，加上个“Global\*”，即可全局通用了 The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space. The remainder of the name can contain any character except the backslash character (\). For more information, see Kernel Object Namespaces. Fast user switching is implemented using Terminal Services sessions. The first user to log on uses session 0, the next user to log on uses session 1, and so on. Kernel object names must follow the guidelines outlined for Terminal Services so that applications can support multiple users.  Windows 2000:  If Terminal Services is not running, the "Global\" and "Local\" prefixes are ignored. The remainder of the name can contain any character except the backslash character. The object can be created in a private namespace. For more information, see Object Namespaces

user: user-3
content: 看到上面的一些回复，我也想说两句 1、内核程序，和应用层服务，不一样(*.sys，*.exe) 2、楼主把程序，改成服务程序就好了 3、用文件同步，呵呵一下，那么多的同步方式！比如防止多次启动，用MUTEX，加上个“Global\*”，即可全局通用了

user: user-1
content: 要添加代码。 《Windows核心编程》

user: user-0
content: 请教一下，这个“使用一个临时文件或跨用户锁对象避免重入”具体要怎么做？ 不会是要在程序中添加代码吧，谢谢  引用 4 楼 zhao4zhong1 的回复:[quote=引用 3 楼 wangch 的回复:] 我想让我的程序开机就启动，而且不管几个账号登陆，只启动一次，除了服务我不知道还有啥好办法  之前写注册表了，开机就启动，但是每个用户登陆都启动一份程序，不符合初衷，所以才想到的注册为服务   [quote=引用 2 楼 zhao4zhong1 的回复:] 建议不要使用服务。用隐藏窗口的进程代替。 理由参考http://bbs.csdn.net/topics/390759229[/quote] 将你的程序的启动命令行放在注册表项HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce中，并使用一个临时文件或跨用户锁对象避免重入即可。[/quote]