需要将自己写的一个MFC程序添加成开机自动启动的系统服务
按照网上写的
加了以下注册表
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\程序名\DisplayName
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\程序名\Description
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\程序名\ImagePath
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\程序名\ObjectName
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\程序名\ErrorControl
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\程序名\Start
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\程序名\Type
的确成功地添加到了控制面板的系统服务中
但是每次启动服务的时候,总是告诉我超时
哪里弄错了?
41 个解决方案
#1
超时 ?什么意思?可以详细点么
RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序。RunServicesOnce注册键的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce
RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序。RunServicesOnce注册键的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce
#2
RunServices注册键指定的程序紧接RunServicesOnce指定的程序之后运行,但两者都在用户登录之前。RunServices的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices。
#3
一个服务程序还要 注册一个控制函数,和事年接收函数
上面是大概的代码
onst char csServerNameInner[] = "xxxxxxxxxxx";
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ csServerNameInner, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL }
};
void winmain()
{
Init();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
return;
}
}
//初始化状态
void Init()
{
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
}
//服务主函数
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
//注册服务控制
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
if(g_hEvent != NULL)
{
//启动你的线程,并等待结束
}
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
//服务控制函数
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(hServiceStatus, &status);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
}
上面是大概的代码
#4
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
SERVICE_STATUS status;
#5
关注。。。up
#6
先回1楼的
详细错误是
error 1053
没有在指定时间内应答
to:fairyprince
你说的这些代码,添加在哪里?
我写的是MFC的一个程序。。。。。。
详细错误是
error 1053
没有在指定时间内应答
to:fairyprince
你说的这些代码,添加在哪里?
我写的是MFC的一个程序。。。。。。
#7
void winmain()
代表你的主函数,例:如果是对话框程序就将其中代码放到 InitInstance(),其它函数只要能放到能找到的地方就能
其实这段代码就是启动一个服务,你可以将它们放到你相放的任何地方
Init();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
return;
}
最后建议最好用 win32 程序不要用 MFC
代表你的主函数,例:如果是对话框程序就将其中代码放到 InitInstance(),其它函数只要能放到能找到的地方就能
其实这段代码就是启动一个服务,你可以将它们放到你相放的任何地方
Init();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
return;
}
最后建议最好用 win32 程序不要用 MFC
#8
感谢fairyprince
我先去试试
不过基本框架肯定要用MFC的说
框架问题,没办法更改。。。。。。
我先去试试
不过基本框架肯定要用MFC的说
框架问题,没办法更改。。。。。。
#9
不好意思,再问一下fairyprince
if(g_hEvent != NULL)
中的g_hEvent,什么类型?在哪里声明?
if(g_hEvent != NULL)
中的g_hEvent,什么类型?在哪里声明?
#10
那个去掉就行
,没用,是多写的
,没用,是多写的
#11
3楼正解
#12
3楼正解,楼主应该在网上搜下怎样把可执行文件写成服务的文章。
#13
服务程序要做一些服务方面的处理,不是随便一个程序安装成服务就可以的。在初始化时需要调用StartServiceCtrlDispatcher函数,在ServiceMain中调用RegisterServiceCtrlHandler,并调用SetServiceStatus将服务状态设置为SERVICE_RUNNING。MFC修改成服务有点麻烦,建议你用一个Win32程序做服务,在该程序中加载MFC程序。
#14
按照楼上各位
新建了一个win32程序
但是运行到
StartServiceCtrlDispatcher(dispatchTable)
一直报错
用getlasterror得到error code 1063
继续发问。。。。。。
新建了一个win32程序
但是运行到
StartServiceCtrlDispatcher(dispatchTable)
一直报错
用getlasterror得到error code 1063
继续发问。。。。。。
#15
代码怎么写的?
#16
基本就是和3楼一样
#17
是否正确的报告了service的状态
SetServiceStatus
SetServiceStatus
#18
我的代码(基本就是3楼的copoy)
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
InitService();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
DWORD dwErrorCode = GetLastError();
return 0;
}
return 0;
}
void InitService()
{
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(hServiceStatus, &status);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
InitService();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
DWORD dwErrorCode = GetLastError();
return 0;
}
return 0;
}
void InitService()
{
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(hServiceStatus, &status);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
}
#19
dispatchTable怎么初始化的?服务名称与安装的服务一致吗?
#20
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
//这里要自已做一个等待,待你目标程序完成,否则你的服务在启动上面程序后会立即结束(即出了 ServiceMain(),你的服务也就结束了)
dispatchTable 表中的名字和你注册表中的"程序名"要一致
//这里要自已做一个等待,待你目标程序完成,否则你的服务在启动上面程序后会立即结束(即出了 ServiceMain(),你的服务也就结束了)
dispatchTable 表中的名字和你注册表中的"程序名"要一致
#21
你是直接用VC调试运行的吧?服务程序不能直接运行,要通过服务管理器加载才行。
#22
TO:楼上的各位大侠
dispatchTable的初始化也和fairyprince写的一样
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ csServerNameInner, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL }
};
无论是用vc调试还是用通过控制面板里的service启动
都会启动失败
dispatchTable 表中的名字和注册表中的"程序名"也一样
等下确认一下,加一个等待是否能正常运行
还是多谢各位
dispatchTable的初始化也和fairyprince写的一样
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ csServerNameInner, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL }
};
无论是用vc调试还是用通过控制面板里的service启动
都会启动失败
dispatchTable 表中的名字和注册表中的"程序名"也一样
等下确认一下,加一个等待是否能正常运行
还是多谢各位
#23
你的serviceMain中应该有一个无限循环... while(1)。只有到你退出的条件满足了
然后你才应该跳出while循环,服务也结束了
然后你才应该跳出while循环,服务也结束了
#24
你的serviceMain中应该有一个无限循环... while(1)。只有到你退出的条件满足了
然后你才应该跳出while循环,服务也结束了
然后你才应该跳出while循环,服务也结束了
#25
在::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL)
之后加了一个sleep
果然可以成功启动服务了
不过又有了新的问题
通过服务所启动的那个mfc程序,也就是aaaa.exe
虽然在TaskManager里有
但没有显示界面......
之后加了一个sleep
果然可以成功启动服务了
不过又有了新的问题
通过服务所启动的那个mfc程序,也就是aaaa.exe
虽然在TaskManager里有
但没有显示界面......
#26
什么操作系统?注册表里添加与用户交互的键值了吗?
#27
因为不在一个"桌面上"
你要切换到用户桌面
你要切换到用户桌面
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//你的代码
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#28
好象是type要“或”0x100。
#29
TO:fairyprince
也可能是我添加错误,
代码追加了还是没有用
确认一下,您的意思是
在winapi32的WinExc(。。。。)
前追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
然后在MFC程序里追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#估计是我理解错了,望指正
TO:cnzdgs
你说的是哪个type?
显示mode么?
貌似我或上了0x100也还是没有用处。。。。。
也可能是我添加错误,
代码追加了还是没有用
确认一下,您的意思是
在winapi32的WinExc(。。。。)
前追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
然后在MFC程序里追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#估计是我理解错了,望指正
TO:cnzdgs
你说的是哪个type?
显示mode么?
貌似我或上了0x100也还是没有用处。。。。。
#30
先说说是什么操作系统。
#31
Windows XP
#32
Windows XP
#33
学习
#34
mfc 不用添代码
只在服务程序里加就行
以下代码应该在一个子线程中,独立于你的服务主线程
只在服务程序里加就行
以下代码应该在一个子线程中,独立于你的服务主线程
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//你的代码 WinExc(。。。。)
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#35
XP系统不必设置桌面,这样就可以:
服务type加上0x100标志。
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
WinExec("C:\\Program Files\\aaaa.exe", SW_SHOWNORMAL);
}
SERVICE_TABLE_ENTRY ServiceTableEntry[] = {
{"服务名称", ServiceMain},
{NULL, NULL}
};
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
StartServiceCtrlDispatcher(ServiceTableEntry);
return 0;
}
服务type加上0x100标志。
#36
你要写成 ATL Server exe 程序
#37
TO:fairyprince
按照您的方法
将代码修改如下,但是貌似还是MFC窗口还是没有显示出来
static UINT __stdcall ThreadFunc(LPVOID pParam)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
return TRUE;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
int nLpvoid = 1;
DWORD dwThreadID;
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)&nLpvoid,0,&dwThreadID);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
TO:cnzdgs
您是说在注册表中的type再加上0x100?
好像也没用的说。。。。
按照您的方法
将代码修改如下,但是貌似还是MFC窗口还是没有显示出来
static UINT __stdcall ThreadFunc(LPVOID pParam)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
return TRUE;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
int nLpvoid = 1;
DWORD dwThreadID;
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)&nLpvoid,0,&dwThreadID);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
TO:cnzdgs
您是说在注册表中的type再加上0x100?
好像也没用的说。。。。
#38
学习
#39
继续自己顶
#40
呵呵
#41
Createservice的Service_own_process后面还要或一个允许交互的参数
#1
超时 ?什么意思?可以详细点么
RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序。RunServicesOnce注册键的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce
RunServicesOnce注册键用来启动服务程序,启动时间在用户登录之前,而且先于其他通过注册键启动的程序。RunServicesOnce注册键的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServicesOnce,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServicesOnce
#2
RunServices注册键指定的程序紧接RunServicesOnce指定的程序之后运行,但两者都在用户登录之前。RunServices的位置是:HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunServices,和HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunServices。
#3
一个服务程序还要 注册一个控制函数,和事年接收函数
上面是大概的代码
onst char csServerNameInner[] = "xxxxxxxxxxx";
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ csServerNameInner, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL }
};
void winmain()
{
Init();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
return;
}
}
//初始化状态
void Init()
{
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
}
//服务主函数
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
//注册服务控制
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
if(g_hEvent != NULL)
{
//启动你的线程,并等待结束
}
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
//服务控制函数
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(hServiceStatus, &status);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
}
上面是大概的代码
#4
SERVICE_STATUS_HANDLE hServiceStatus;
SERVICE_STATUS status;
SERVICE_STATUS status;
#5
关注。。。up
#6
先回1楼的
详细错误是
error 1053
没有在指定时间内应答
to:fairyprince
你说的这些代码,添加在哪里?
我写的是MFC的一个程序。。。。。。
详细错误是
error 1053
没有在指定时间内应答
to:fairyprince
你说的这些代码,添加在哪里?
我写的是MFC的一个程序。。。。。。
#7
void winmain()
代表你的主函数,例:如果是对话框程序就将其中代码放到 InitInstance(),其它函数只要能放到能找到的地方就能
其实这段代码就是启动一个服务,你可以将它们放到你相放的任何地方
Init();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
return;
}
最后建议最好用 win32 程序不要用 MFC
代表你的主函数,例:如果是对话框程序就将其中代码放到 InitInstance(),其它函数只要能放到能找到的地方就能
其实这段代码就是启动一个服务,你可以将它们放到你相放的任何地方
Init();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
return;
}
最后建议最好用 win32 程序不要用 MFC
#8
感谢fairyprince
我先去试试
不过基本框架肯定要用MFC的说
框架问题,没办法更改。。。。。。
我先去试试
不过基本框架肯定要用MFC的说
框架问题,没办法更改。。。。。。
#9
不好意思,再问一下fairyprince
if(g_hEvent != NULL)
中的g_hEvent,什么类型?在哪里声明?
if(g_hEvent != NULL)
中的g_hEvent,什么类型?在哪里声明?
#10
那个去掉就行
,没用,是多写的
,没用,是多写的
#11
3楼正解
#12
3楼正解,楼主应该在网上搜下怎样把可执行文件写成服务的文章。
#13
服务程序要做一些服务方面的处理,不是随便一个程序安装成服务就可以的。在初始化时需要调用StartServiceCtrlDispatcher函数,在ServiceMain中调用RegisterServiceCtrlHandler,并调用SetServiceStatus将服务状态设置为SERVICE_RUNNING。MFC修改成服务有点麻烦,建议你用一个Win32程序做服务,在该程序中加载MFC程序。
#14
按照楼上各位
新建了一个win32程序
但是运行到
StartServiceCtrlDispatcher(dispatchTable)
一直报错
用getlasterror得到error code 1063
继续发问。。。。。。
新建了一个win32程序
但是运行到
StartServiceCtrlDispatcher(dispatchTable)
一直报错
用getlasterror得到error code 1063
继续发问。。。。。。
#15
代码怎么写的?
#16
基本就是和3楼一样
#17
是否正确的报告了service的状态
SetServiceStatus
SetServiceStatus
#18
我的代码(基本就是3楼的copoy)
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
InitService();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
DWORD dwErrorCode = GetLastError();
return 0;
}
return 0;
}
void InitService()
{
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(hServiceStatus, &status);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
InitService();
if (!::StartServiceCtrlDispatcher(dispatchTable))
{
DWORD dwErrorCode = GetLastError();
return 0;
}
return 0;
}
void InitService()
{
hServiceStatus = NULL;
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
status.dwCurrentState = SERVICE_STOPPED;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
status.dwWin32ExitCode = 0;
status.dwServiceSpecificExitCode = 0;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
void WINAPI ServiceStrl(DWORD dwOpcode)
{
switch (dwOpcode)
{
case SERVICE_CONTROL_STOP:
status.dwCurrentState = SERVICE_STOP_PENDING;
::SetServiceStatus(hServiceStatus, &status);
break;
case SERVICE_CONTROL_PAUSE:
break;
case SERVICE_CONTROL_CONTINUE:
break;
case SERVICE_CONTROL_INTERROGATE:
break;
case SERVICE_CONTROL_SHUTDOWN:
break;
default:
break;
}
}
#19
dispatchTable怎么初始化的?服务名称与安装的服务一致吗?
#20
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
//这里要自已做一个等待,待你目标程序完成,否则你的服务在启动上面程序后会立即结束(即出了 ServiceMain(),你的服务也就结束了)
dispatchTable 表中的名字和你注册表中的"程序名"要一致
//这里要自已做一个等待,待你目标程序完成,否则你的服务在启动上面程序后会立即结束(即出了 ServiceMain(),你的服务也就结束了)
dispatchTable 表中的名字和你注册表中的"程序名"要一致
#21
你是直接用VC调试运行的吧?服务程序不能直接运行,要通过服务管理器加载才行。
#22
TO:楼上的各位大侠
dispatchTable的初始化也和fairyprince写的一样
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ csServerNameInner, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL }
};
无论是用vc调试还是用通过控制面板里的service启动
都会启动失败
dispatchTable 表中的名字和注册表中的"程序名"也一样
等下确认一下,加一个等待是否能正常运行
还是多谢各位
dispatchTable的初始化也和fairyprince写的一样
SERVICE_TABLE_ENTRY dispatchTable[] =
{
{ csServerNameInner, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{ NULL, NULL }
};
无论是用vc调试还是用通过控制面板里的service启动
都会启动失败
dispatchTable 表中的名字和注册表中的"程序名"也一样
等下确认一下,加一个等待是否能正常运行
还是多谢各位
#23
你的serviceMain中应该有一个无限循环... while(1)。只有到你退出的条件满足了
然后你才应该跳出while循环,服务也结束了
然后你才应该跳出while循环,服务也结束了
#24
你的serviceMain中应该有一个无限循环... while(1)。只有到你退出的条件满足了
然后你才应该跳出while循环,服务也结束了
然后你才应该跳出while循环,服务也结束了
#25
在::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL)
之后加了一个sleep
果然可以成功启动服务了
不过又有了新的问题
通过服务所启动的那个mfc程序,也就是aaaa.exe
虽然在TaskManager里有
但没有显示界面......
之后加了一个sleep
果然可以成功启动服务了
不过又有了新的问题
通过服务所启动的那个mfc程序,也就是aaaa.exe
虽然在TaskManager里有
但没有显示界面......
#26
什么操作系统?注册表里添加与用户交互的键值了吗?
#27
因为不在一个"桌面上"
你要切换到用户桌面
你要切换到用户桌面
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//你的代码
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#28
好象是type要“或”0x100。
#29
TO:fairyprince
也可能是我添加错误,
代码追加了还是没有用
确认一下,您的意思是
在winapi32的WinExc(。。。。)
前追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
然后在MFC程序里追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#估计是我理解错了,望指正
TO:cnzdgs
你说的是哪个type?
显示mode么?
貌似我或上了0x100也还是没有用处。。。。。
也可能是我添加错误,
代码追加了还是没有用
确认一下,您的意思是
在winapi32的WinExc(。。。。)
前追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
然后在MFC程序里追加
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#估计是我理解错了,望指正
TO:cnzdgs
你说的是哪个type?
显示mode么?
貌似我或上了0x100也还是没有用处。。。。。
#30
先说说是什么操作系统。
#31
Windows XP
#32
Windows XP
#33
学习
#34
mfc 不用添代码
只在服务程序里加就行
以下代码应该在一个子线程中,独立于你的服务主线程
只在服务程序里加就行
以下代码应该在一个子线程中,独立于你的服务主线程
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
//你的代码 WinExc(。。。。)
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
#35
XP系统不必设置桌面,这样就可以:
服务type加上0x100标志。
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
WinExec("C:\\Program Files\\aaaa.exe", SW_SHOWNORMAL);
}
SERVICE_TABLE_ENTRY ServiceTableEntry[] = {
{"服务名称", ServiceMain},
{NULL, NULL}
};
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
StartServiceCtrlDispatcher(ServiceTableEntry);
return 0;
}
服务type加上0x100标志。
#36
你要写成 ATL Server exe 程序
#37
TO:fairyprince
按照您的方法
将代码修改如下,但是貌似还是MFC窗口还是没有显示出来
static UINT __stdcall ThreadFunc(LPVOID pParam)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
return TRUE;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
int nLpvoid = 1;
DWORD dwThreadID;
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)&nLpvoid,0,&dwThreadID);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
TO:cnzdgs
您是说在注册表中的type再加上0x100?
好像也没用的说。。。。
按照您的方法
将代码修改如下,但是貌似还是MFC窗口还是没有显示出来
static UINT __stdcall ThreadFunc(LPVOID pParam)
{
DWORD dwThreadId;
HWINSTA hwinstaSave;
HDESK hdeskSave;
HWINSTA hwinstaUser;
HDESK hdeskUser;
// Ensure connection to service window station and desktop, and
// save their handles.
GetDesktopWindow();
hwinstaSave = GetProcessWindowStation();
dwThreadId = GetCurrentThreadId();
hdeskSave = GetThreadDesktop(dwThreadId);
// Impersonate the client and connect to the User's
// window station and desktop.
hwinstaUser = ::OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED);
if (hwinstaUser == NULL)
{
return 0;
}
SetProcessWindowStation(hwinstaUser);
hdeskUser = ::OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED);
if (hdeskUser == NULL)
{
SetProcessWindowStation(hwinstaSave);
CloseWindowStation(hwinstaUser);
return 0;
}
SetThreadDesktop(hdeskUser);
::WinExec("C:\\Program Files\\aaaa.exe",SW_SHOWNORMAL);
//Restore window station and desktop.
SetThreadDesktop(hdeskSave);
SetProcessWindowStation(hwinstaSave);
CloseDesktop(hdeskUser);
CloseWindowStation(hwinstaUser);
return TRUE;
}
void WINAPI ServiceMain()
{
status.dwCurrentState = SERVICE_START_PENDING;
status.dwControlsAccepted = SERVICE_ACCEPT_STOP;
hServiceStatus = ::RegisterServiceCtrlHandler(csServerNameInner, ServiceStrl);
if (hServiceStatus == NULL)
{
return;
}
::SetServiceStatus(hServiceStatus, &status);
status.dwWin32ExitCode = S_OK;
status.dwCheckPoint = 0;
status.dwWaitHint = 0;
status.dwCurrentState = SERVICE_RUNNING;
::SetServiceStatus(hServiceStatus, &status);
int nLpvoid = 1;
DWORD dwThreadID;
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunc,(LPVOID)&nLpvoid,0,&dwThreadID);
status.dwCurrentState = SERVICE_STOPPED;
::SetServiceStatus(hServiceStatus, &status);
}
TO:cnzdgs
您是说在注册表中的type再加上0x100?
好像也没用的说。。。。
#38
学习
#39
继续自己顶
#40
呵呵
#41
Createservice的Service_own_process后面还要或一个允许交互的参数