service安装问题

token_lys 2004-12-08 04:15:57
我要用CreateService安装一个服务,但是OpenSCManager没有成功,谁能给点提示

OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS)返回NULL,GetLastError返回5拒绝访问,登陆帐户有管理员权限,在windows登陆后运行的GUI程序调用的。

进程的权限应该和登陆帐户相同,对吗?
...全文
151 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
token_lys 2004-12-11
  • 打赏
  • 举报
回复
我忘了说,我在一个dll的export函数里调用OpenSCManager和CreateService,然后外边一个mfc单文档界面进程调用dll的export函数,这样和exe程序直接调用OpenSCManager和CreateService是一样的吧
aoosang 2004-12-08
  • 打赏
  • 举报
回复
要不要我给你发个demo,如果需要,给我发消息
aoosang 2004-12-08
  • 打赏
  • 举报
回复
我也没有做什么初始化的工作啊,再说了,这个函数是main函数直接调用的啊
yanw0212 2004-12-08
  • 打赏
  • 举报
回复
void __fastcall CServerCallDlg::StartBtnClick()
{
m_scm=OpenSCManager(
NULL,
NULL,
SC_MANAGER_CONNECT//允许连接到service control manager database
);
if (m_scm!=NULL)
{
m_svc=OpenService(
m_scm,
"AccessControlService",
SERVICE_START //Enables calling of the StartService function to start the service.
);
if (m_svc!=NULL)
{
//开始Service
StartService ( m_svc, //为指向Service的句柄,由OpenService返回
0, //为启动服务所需的参数的个数
NULL //为 启 动 服务所需的参数
);
CloseServiceHandle(m_svc);
CloseServiceHandle(m_scm);
GetDlgItem(IDB_STR)->EnableWindow(FALSE);
GetDlgItem(IDB_STOP)->EnableWindow(TRUE);
MessageBox("START SERVICE SUCCEEDS !");

}
else
{
DWORD error = GetLastError();
CString errcode ;
errcode.Format("启动服务错误,错误的类型识:%d",(int)error);
AfxMessageBox(errcode);
}
}


}

void __fastcall CServerCallDlg::StopBtnClick()
{
//LPSERVICE_STATUS ServiceStatus ;
m_scm=OpenSCManager(
NULL,
NULL,
SC_MANAGER_ALL_ACCESS//取得所有的权限
);

if (m_scm!=NULL) //1st if
{
m_svc=OpenService(
m_scm,
"AccessControlService",
//Enables calling of the ControlService function to stop the service
//Enables calling of the QueryServiceStatus function to query the status of the service.
SERVICE_STOP|SERVICE_QUERY_STATUS
);
if (m_svc!=NULL)//2st if
{
QueryServiceStatus(m_svc,&m_ServiceStatus);//查询server的状态
if (m_ServiceStatus.dwCurrentState==SERVICE_RUNNING)//3st if
{
ControlService(m_svc,SERVICE_CONTROL_STOP,&m_ServiceStatus);
MessageBox("STOP SERVVICE SUCCEEDS !");

}//end 3st if
CloseServiceHandle(m_svc);
}//end of 2st if
CloseServiceHandle(m_scm);
}//end 1st if
GetDlgItem(IDB_STR)->EnableWindow(TRUE);
GetDlgItem(IDB_STOP)->EnableWindow(FALSE);
}
yanw0212 2004-12-08
  • 打赏
  • 举报
回复
void __fastcall CServerCallDlg::CreateBtnClick()
{

UpdateData(true);
m_scm=OpenSCManager(
NULL, // 指定计算机名为本机
NULL, // 指定要打开的service control managerdatabase名, 默认为空
SC_MANAGER_CREATE_SERVICE // 允许创建服务对象并把它加入database
);
if (m_scm!=NULL)//if open server database succeeds
{
/*SC_HANDLE*/m_svc=CreateService(
m_scm, // server database 的句柄
"AccessControlService", // Service名字
"AccessControlService", // 为Service显示用名
SERVICE_ALL_ACCESS, // 指定server的使用权限,可使用所有的权限
// 指定server的类型,
// Service that runs in its own process
// The service can interact with the desktop
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START, // 以自动方式开始
SERVICE_ERROR_IGNORE, //说明当Service在启动中出错时采取什么动作
m_ExeFile,
NULL,NULL,NULL,NULL,NULL
);
if (m_svc!=NULL)
{
MessageBox("CREATE SERVIVR SUCCEEDS ! ");
}
else
{
MessageBox("CREATE SERVIVR FAILED") ;
}

GetDlgItem(IDB_CREATE)->EnableWindow(FALSE); // 将“CreateServer”按扭失效
GetDlgItem(IDB_DEL)->EnableWindow(TRUE); // 将“DeleteServer”按扭生效
GetDlgItem(IDB_STR)->EnableWindow(TRUE);

CloseServiceHandle(m_svc);
CloseServiceHandle(m_scm);
}//end of if
}


void __fastcall CServerCallDlg::DeleteBtnClick()
{
m_scm=OpenSCManager (
NULL,
NULL,
SC_MANAGER_CONNECT//允许连接到service control manager database
);

if (m_scm!=NULL)// 1st if
{
m_svc = OpenService (
m_scm,
"AccessControlService",
SERVICE_ALL_ACCESS
);

if (m_svc!=NULL)//2st if
{
//查询servers数据库的状态
QueryServiceStatus(m_svc,&m_ServiceStatus);

//删除前,先停止此Service.
if (m_ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
ControlService(m_svc,SERVICE_CONTROL_STOP,&m_ServiceStatus);
}
DeleteService(m_svc);

CloseServiceHandle(m_svc); //删除Service后,最好再调用CloseServiceHandle,以便立即从数据库中移走此条目。
}
CloseServiceHandle(m_scm);
}

GetDlgItem(IDB_DEL)->EnableWindow(FALSE); // 将“DeleteServer”按扭失效
GetDlgItem(IDB_CREATE)->EnableWindow(TRUE); // 将“CreateServer”按扭失效
GetDlgItem(IDB_STR)->EnableWindow(FALSE);
GetDlgItem(IDB_STOP)->EnableWindow(FALSE);

MessageBox("DELETE SERVICE SUCCEEDS !");
}
token_lys 2004-12-08
  • 打赏
  • 举报
回复
我除了没有调用GetModuleFileName( NULL, szPath, 512 )之外,和你完全一样。

前面为OpenSCManager做过什么初始化工作吗?
aoosang 2004-12-08
  • 打赏
  • 举报
回复
提供一段代码,安装服务,,我这么做就没有问题
void CmdInstallService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;

TCHAR szPath[512];
//得到程序磁盘文件的路径
if ( GetModuleFileName( NULL, szPath, 512 ) == 0 )
{
_tprintf(TEXT("Unable to install %s - %s\n"), TEXT(SZSERVICEDISPLAYNAME), GetLastErrorText(szErr, 256));
return;
}

//打开服务管理数据库
//对于一个已安装的服务程序,可以调用系统函数 OpenService 来获取服务程序的句柄
//
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS // access required
);
if ( schSCManager )
{ //登记服务程序
schService = CreateService(
schSCManager, //服务管理数据库句柄
TEXT(SZSERVICENAME), //服务名
TEXT(SZSERVICEDISPLAYNAME), //用于显示服务的标识
SERVICE_ALL_ACCESS, // //响应所有的访问请求
SERVICE_WIN32_OWN_PROCESS, //服务类型
SERVICE_AUTO_START, //启动类型
SERVICE_ERROR_NORMAL, //错误控制类型
szPath, //服务程序磁盘文件的路径
NULL, //服务不属于任何组
NULL, //没有tag标识符
TEXT(SZDEPENDENCIES), //启动服务所依赖的服务或服务组,这里仅仅是一个空字符串
NULL, //LocalSystem 帐号
NULL);

if ( schService )
{
_tprintf(TEXT("%s installed.\n"), TEXT(SZSERVICEDISPLAYNAME) );
CloseServiceHandle(schService);
}
else
{
_tprintf(TEXT("CreateService failed - %s\n"), GetLastErrorText(szErr, 256));
}

//用CreateService 或OpenService 打开的服务程序句柄使用完毕后必须用CloseServiceHandle 关闭。
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s\n"), GetLastErrorText(szErr,256));
}
token_lys 2004-12-08
  • 打赏
  • 举报
回复
error code 5 or "access denied" is returned
我就是搞不清楚为什么要deny,我的登陆帐户有管理员权限
kingzai 2004-12-08
  • 打赏
  • 举报
回复
Windows NT Services are securable objects in that they are associated with a Security Descriptor and a Discretionary Access Control List (DACL). The DACL associated with the Service has sole control over access to the Service. No special user rights or privileges are needed to manipulate a Service. An application requests a handle to a Service via the OpenService or CreateService API. If the user has the requested access to the Service object, a valid handle is returned. If the requested access is denied by the system, an error code 5 or "access denied" is returned.
sample code:
#include <windows.h>
#include <aclapi.h>
#include <stdio.h>
#include <tchar.h>

void DisplayError(DWORD dwError, LPTSTR pszAPI)
{
LPVOID lpvMessageBuffer;

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dwError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&lpvMessageBuffer, 0, NULL);

//Now display this string.
_tprintf(TEXT("ERROR: API = %s.\n"), pszAPI);
_tprintf(TEXT(" error code = %u.\n"), dwError);
_tprintf(TEXT(" message = %s.\n"),
(LPTSTR)lpvMessageBuffer);

// Free the buffer allocated by the system.
LocalFree(lpvMessageBuffer);

ExitProcess(dwError);
}

void _tmain(int argc, TCHAR *argv[])
{
BOOL bDaclPresent = FALSE;
BOOL bDaclDefaulted = FALSE;
DWORD dwError = 0;
DWORD dwSize = 0;
EXPLICIT_ACCESS ea;
PACL pacl = NULL;
PACL pNewAcl = NULL;
PSECURITY_DESCRIPTOR psd;
SC_HANDLE schManager = NULL;
SC_HANDLE schService = NULL;
SECURITY_DESCRIPTOR sd;

if (argc != 2){
_tprintf(TEXT("Usage: %s [service name]\n"), argv[0]);
return;
}

//
// Obtain a handle to the Service Controller.
//
schManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
if (schManager == NULL)
DisplayError(GetLastError(), TEXT("OpenSCManager"));

//
// Obtain a handle to the service.
//
schService = OpenService(schManager, argv[1],
READ_CONTROL | WRITE_DAC);
if (schService == NULL)
DisplayError(GetLastError(), TEXT("OpenService"));

//
// Get the current security descriptor.
//
if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, psd, 0, &dwSize)){
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER){
psd = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY, dwSize);
if (psd == NULL){
DisplayError(0, TEXT("HeapAlloc"));
// note HeapAlloc does not support GetLastError()
}

if (!QueryServiceObjectSecurity(schService,
DACL_SECURITY_INFORMATION, psd, dwSize, &dwSize))
DisplayError(GetLastError(),
TEXT("QueryServiceObjectSecurity"));
}
else
DisplayError(GetLastError(),
TEXT("QueryServiceObjectSecurity"));
}

//
// Get the DACL.
//
if (!GetSecurityDescriptorDacl(psd, &bDaclPresent, &pacl,
&bDaclDefaulted))
DisplayError(GetLastError(), TEXT("GetSecurityDescriptorDacl"));

//
// Build the ACE.
//
BuildExplicitAccessWithName(&ea, TEXT("GUEST"),
SERVICE_START | SERVICE_STOP | READ_CONTROL | DELETE,
SET_ACCESS, NO_INHERITANCE);

dwError = SetEntriesInAcl(1, &ea, pacl, &pNewAcl);
if (dwError != ERROR_SUCCESS)
DisplayError(dwError, TEXT("SetEntriesInAcl"));

//
// Initialize a NEW Security Descriptor.
//
if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
DisplayError(GetLastError(),
TEXT("InitializeSecurityDescriptor"));

//
// Set the new DACL in the Security Descriptor.
//
if (!SetSecurityDescriptorDacl(&sd, TRUE, pNewAcl, FALSE))
DisplayError(GetLastError(), TEXT("SetSecurityDescriptorDacl"));

//
// Set the new DACL for the service object.
//
if (!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION,
&sd))
DisplayError(GetLastError(), TEXT("SetServiceObjectSecurity"));

//
// Close the handles.
//
if (!CloseServiceHandle(schManager))
DisplayError(GetLastError(), TEXT("CloseServiceHandle"));

if (!CloseServiceHandle(schService))
DisplayError(GetLastError(), TEXT("CloseServiceHandle"));

//
// Free buffers.
//
LocalFree((HLOCAL)pNewAcl);
HeapFree(GetProcessHeap(), 0, (LPVOID)psd);
}

for more,see
HOWTO: Control Access to a Windows NT Service

Q180116

token_lys 2004-12-08
  • 打赏
  • 举报
回复
我的测试程序是一个很简单的mfc单稳当界面程序,代码都没有几行,肯定没有多次调用OpenSCManager,也不可能调用了ImpersonateLoggedOnUser,mfc的framework不会调用这些函数把
danyueer 2004-12-08
  • 打赏
  • 举报
回复
一般情况下进程的权限应该和登陆帐户相同,你这里可能有两种原因:
1 你之前调用了OpenSCManager,但是后来没有CloseServiceHandle;
2 你的进程在某个非管理员账号的权限下运行,比如调用了ImpersonateLoggedOnUser。

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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