基于Visual C++之Windows核心编程代码分析(2)实现Windows用户管理

在Windows编程中间,我们经常需要添加用户,删除用户,添加用户组等等功能,那些功能如何实现呢,我们请见实现代码与注释分析

 

 

/* UNICODE */
#ifndef UNICODE
#define UNICODE
#endif
/* 头文件 */
#include <stdio.h>
#include <assert.h>
#include <windows.h> 
#include <lm.h>

/*************************************
* AddUser
* 功能	增加用户
* 参数	szServerName,主机名,如果为本机增加用户,设置为NULL
*			szUserName,用户名
*			szPassword,密码
**************************************/
int AddUser(LPWSTR szServerName, 
			LPWSTR szUserName,
			LPWSTR szPassword)
{
	USER_INFO_1 ui;
	DWORD dwLevel = 1;	// 使用 USER_INFO_1 作为参数
	DWORD dwError = 0;
	NET_API_STATUS nStatus;
	// 填充 USER_INFO_1
	ui.usri1_name = szUserName;	// 用户名
	ui.usri1_password = szPassword;	// 密码
	ui.usri1_priv = USER_PRIV_USER;	// privilege  
	ui.usri1_home_dir = NULL;
	ui.usri1_comment = NULL;
	ui.usri1_flags = UF_SCRIPT;
	ui.usri1_script_path = NULL;
	// 调用 NetUserAdd 增加用户
	nStatus = NetUserAdd(szServerName,
		dwLevel,
		(LPBYTE)&ui,
		&dwError);

	// 判断结果
	if (nStatus == NERR_Success)
	{
		wprintf(stderr, L"User %s has been successfully added on %s\n",
		szUserName, szServerName);
	}
	else
	{
		fprintf(stderr, "A system error has occurred: %d\n", nStatus);
	}
	return 0;
}

/*************************************
* AddUserToGroup
* 功能	为用户组增加用户
* 参数	szServerName,主机名,如果为本机,设置为NULL
*			szUserName,用户名
*			szGroup,用户组名
**************************************/
int AddUserToGroup(LPWSTR szServerName, 
				   LPWSTR szUserName,  
				   LPWSTR szGroup)
{
	NET_API_STATUS nStatus;
	// 调用 NetGroupAddUser
	nStatus =  NetGroupAddUser(
		szServerName,
		szGroup,
		szUserName
		);

	// 判断结果
	if (nStatus == NERR_Success)
		fwprintf(stderr, L"User %s has been successfully added on %s\n",
		szUserName, szServerName);

	else
		fprintf(stderr, "NetGroupAddUser A system error has occurred: %d\n", nStatus);
	return 0;
}

/*************************************
* DelUser
* 功能	删除用户
* 参数	szServerName,主机名,如果为本机,设置为NULL
*			szUserName,用户名
**************************************/
int DelUser(LPWSTR szServerName, LPWSTR szUserName)
{
	DWORD dwError = 0;
	NET_API_STATUS nStatus;

	// 调用 NetUserDel 删除用户
	nStatus = NetUserDel(szServerName, szUserName);
	// 判断并显示结果
	if (nStatus == NERR_Success)
		fwprintf(stderr, L"User %s has been successfully deleted on %s\n",
		szUserName, szServerName);
	else
		fprintf(stderr, "A system error has occurred: %d\n", nStatus);

	return 0;

}

/*************************************
* int ListUsers(LPWSTR pszServerName)
* 功能	列举用户
* 参数	szServerName,主机名,如果为本机,设置为NULL
**************************************/
int ListUsers(LPWSTR pszServerName)
{
	LPUSER_INFO_0 pBuf = NULL;
	LPUSER_INFO_0 pTmpBuf;
	DWORD dwLevel = 0;
	DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
	DWORD dwEntriesRead = 0;
	DWORD dwTotalEntries = 0;
	DWORD dwResumeHandle = 0;
	DWORD i;
	DWORD dwTotalCount = 0;
	NET_API_STATUS nStatus;

	// 循环,直到可以成功调用 NetUserEnum
	do 
	{
		// 调用NetUserEnum函数
		nStatus = NetUserEnum(pszServerName,
			dwLevel,// 这里设置为0,使用 LPUSER_INFO_0 返回结果
			FILTER_NORMAL_ACCOUNT, // 只列举“正常”类型的用户
			(LPBYTE*)&pBuf,// LPUSER_INFO_0 保存返回结果
			// MAX_PREFERRED_LENGTH,内存由API分配,需要在之后调用NetApiBufferFree释放
			dwPrefMaxLen,
			&dwEntriesRead,// 读了的 Entries
			&dwTotalEntries,// 一共的 Entries
			&dwResumeHandle);
		// 判断是否成功
		if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
		{
			if ((pTmpBuf = pBuf) != NULL)
			{
				// 循环读取用户信息
				for (i = 0; (i < dwEntriesRead); i++)
				{
					assert(pTmpBuf != NULL);

					if (pTmpBuf == NULL)
					{
						fprintf(stderr, "An access violation has occurred\n");
						break;
					}
					// 输出
					wprintf(L"\t-- %s\n", pTmpBuf->usri0_name);
					// 下一个
					pTmpBuf++;
					dwTotalCount++;
				}
			}
		}
		else
			fprintf(stderr, "A system error has occurred: %d\n", nStatus);
		// 释放内存
		if (pBuf != NULL)
		{
			NetApiBufferFree(pBuf);
			pBuf = NULL;
		}
	}
	while (nStatus == ERROR_MORE_DATA); // end do

	// 释放内存
	if (pBuf != NULL)
		NetApiBufferFree(pBuf);

	fprintf(stderr, "Total of %d users\n\n", dwTotalCount);

	return 0;
}

/*************************************
* int ListGroup(LPWSTR pszServerName)
* 功能	列举用户组
* 参数	szServerName,主机名,如果为本机,设置为NULL
**************************************/
int ListGroup(LPWSTR pszServerName)
{

	DWORD dwLevel = 0;
	DWORD dwPrefMaxLen = MAX_PREFERRED_LENGTH;
	DWORD dwEntriesRead = 0;
	DWORD dwTotalEntries = 0;
	DWORD dwResumeHandle = 0;
	DWORD i;
	DWORD dwTotalCount = 0;
	NET_API_STATUS nStatus;


	LPLOCALGROUP_INFO_0 pBuf = NULL;
	LPLOCALGROUP_INFO_0 pTmpBuf;

	do // begin do
	{
		// 调用NetLocalGroupEnum 参数设置与NetLocalGroup类似
		nStatus = NetLocalGroupEnum(
			pszServerName,
			0,
			(LPBYTE*)&pBuf,
			dwPrefMaxLen,
			&dwEntriesRead,
			&dwTotalEntries,
			&dwResumeHandle);
		// 判断结果
		if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA))
		{
			if ((pTmpBuf = pBuf) != NULL)
			{
				// 循环输出
				for (i = 0; (i < dwEntriesRead); i++)
				{
					assert(pTmpBuf != NULL);

					if (pTmpBuf == NULL)
					{
						fprintf(stderr, "An access violation has occurred\n");
						break;
					}

					wprintf(L"\t-- %s\n", pTmpBuf->lgrpi0_name);
					pTmpBuf++;
					dwTotalCount++;
				}
			}
		}

		else
			fprintf(stderr, "A system error has occurred: %d\n", nStatus);
		// 释放内存
		if (pBuf != NULL)
		{
			NetApiBufferFree(pBuf);
			pBuf = NULL;
		}
	}

	while (nStatus == ERROR_MORE_DATA); // end do

	if (pBuf != NULL)
		NetApiBufferFree(pBuf);

	fprintf(stderr, "Total of %d groups\n\n", dwTotalCount);

	return 0;
}

/*************************************
* ShowUsersInfo
* 功能	显示指定用户的信息
* 参数	szServerName,主机名,如果为本机,设置为NULL
*			pszUserName,用户名
**************************************/
int ShowUsersInfo(LPWSTR pszServerName,LPWSTR pszUserName)
{

	DWORD dwLevel = 4;// 使用 LPUSER_INFO_4 返回结果
	LPUSER_INFO_4 pBuf = NULL;
	NET_API_STATUS nStatus;

	nStatus = NetUserGetInfo(pszServerName,
		pszUserName,
		dwLevel,	// pBuf参数类型
		(LPBYTE *)&pBuf);
	
	// 判断并输出结果
	if (nStatus == NERR_Success)
	{
		if (pBuf != NULL)
		{
			wprintf(L"\n\tAccount:      %s\n", pBuf->usri4_name);
			wprintf(L"\tComment:      %s\n", pBuf->usri4_comment);
			wprintf(L"\tUser comment: %s\n", pBuf->usri4_usr_comment);
			wprintf(L"\tFull name:    %s\n", pBuf->usri4_full_name);
			wprintf(L"\tpriv:    %d\n", pBuf->usri4_priv);
		}
	}

	else
		fprintf(stderr, "A system error has occurred: %d\n", nStatus);
	// 释放内存
	if (pBuf != NULL)
		NetApiBufferFree(pBuf);
	return 0;

}

/*************************************
* wmain
* 功能	入口函数,根据参数判断需要调用的功能函数
* 参数	参见usage输出
**************************************/
int __cdecl wmain(int ac, wchar_t * av[])
{

	if (ac == 4 && lstrcmpW( av[1], L"-a") == 0)
	{
		AddUser(NULL, av[2], av[3]);
	}

	else if (ac == 4 && lstrcmpW( av[1], L"-g") == 0)
	{
		AddUserToGroup(NULL, av[2], av[3]);
	}
	else 	if (ac == 3 && lstrcmpW( av[1], L"-i") == 0)
	{
		ShowUsersInfo(NULL, av[2]);
	}
	else 	if (ac == 2 && lstrcmpW( av[1], L"-i") == 0)
	{
		ListUsers(NULL);
		ListGroup(NULL);
	}
	else	if (ac == 3 && lstrcmpW( av[1], L"-d") == 0)
	{
		DelUser(NULL, av[2]);
	}
	else
	{
		printf("usage: \n"
			"\t %ws -a <username> <password> to add a user\n"
			"\t %ws -g <username> <group> add a user to a group"
			"\t %ws -i <username> to show user info\n"
			"\t %ws -d <username> to del a user\n", 
			av[0], av[0], av[0], av[0]);
	}
	return 0;
}


 

很高兴能够回答你的问题。首先,让我们来了解一下Windows服务是什么。 Windows服务是在Windows操作系统中以后台方式运行的应用程序。服务的主要作用是在系统启动时自动启动,并在后台持续运行以提供某种特定的功能或服务。Windows服务可以通过Windows服务管理器进行管理和控制。 接下来,我们来看一下如何实现一个Windows服务并进行安装和控制。 1. 创建Windows服务项目 首先,我们需要使用Visual Studio创建一个Windows服务项目。在Visual Studio中选择“新建项目”->“Visual C++”->“Windows Desktop”->“Windows服务”,然后命名项目并选择保存路径即可。 2. 编写服务代码 在服务项目中,我们需要编写服务代码。这些代码包括服务的启动、停止、暂停、恢复等功能。下面是一个示例代码: ``` #include "stdafx.h" #include "MyService.h" #include <iostream> using namespace std; #define SERVICE_NAME "MyService" SERVICE_STATUS ServiceStatus; SERVICE_STATUS_HANDLE hServiceStatusHandle; void WINAPI ServiceMain(DWORD argc, LPTSTR *argv); void WINAPI ServiceCtrlHandler(DWORD); int _tmain(int argc, _TCHAR* argv[]) { SERVICE_TABLE_ENTRY ServiceTable[] = { {SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain}, {NULL, NULL} }; if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) { cout << "StartServiceCtrlDispatcher failed" << endl; return GetLastError(); } return 0; } void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) { hServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler); if (hServiceStatusHandle == NULL) { cout << "RegisterServiceCtrlHandler failed" << endl; return; } ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS; ServiceStatus.dwCurrentState = SERVICE_START_PENDING; ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; ServiceStatus.dwWin32ExitCode = NO_ERROR; ServiceStatus.dwServiceSpecificExitCode = 0; ServiceStatus.dwCheckPoint = 0; ServiceStatus.dwWaitHint = 0; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } ServiceStatus.dwCurrentState = SERVICE_RUNNING; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) { // Do something here } return; } void WINAPI ServiceCtrlHandler(DWORD dwCtrl) { switch (dwCtrl) { case SERVICE_CONTROL_PAUSE: ServiceStatus.dwCurrentState = SERVICE_PAUSE_PENDING; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } ServiceStatus.dwCurrentState = SERVICE_PAUSED; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } break; case SERVICE_CONTROL_CONTINUE: ServiceStatus.dwCurrentState = SERVICE_CONTINUE_PENDING; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } ServiceStatus.dwCurrentState = SERVICE_RUNNING; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } break; case SERVICE_CONTROL_STOP: ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } ServiceStatus.dwCurrentState = SERVICE_STOPPED; if (SetServiceStatus(hServiceStatusHandle, &ServiceStatus) == FALSE) { cout << "SetServiceStatus failed" << endl; return; } break; default: break; } } ``` 这是一个简单的示例代码,其中包含了服务的启动、停止、暂停和恢复功能。我们可以将服务的具体功能实现放在while循环中。 3. 安装服务 在编写完服务代码后,我们需要将服务安装到系统中。可以使用命令行工具“sc.exe”来进行安装。打开命令提示符窗口,输入以下命令: ``` sc create MyService binPath= "C:\MyService.exe" ``` 其中,MyService是服务的名称,C:\MyService.exe是服务的可执行文件路径。 4. 启动、停止、暂停和恢复服务 在服务安装成功后,我们可以使用Windows服务管理器来启动、停止、暂停和恢复服务。打开Windows服务管理器,找到MyService服务,右键单击服务并选择相应的选项即可。 除此之外,我们也可以使用命令行工具“sc.exe”来进行控制。以下是一些常用的命令: ``` sc start MyService sc stop MyService sc pause MyService sc continue MyService ``` 这些命令可以在命令提示符窗口中直接执行。 总结 通过以上步骤,我们可以成功地实现一个Windows服务,并进行安装和控制。请注意,在实现服务时,我们需要注意服务的生命周期、状态转换、错误处理等方面。希望这篇文章能够帮助你更好地理解Windows服务的实现和控制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尹成

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值