服务控制管理器 (SCM, Service Control Manager),它在系统启动时自动启动,其主要作用是维护和管理一张服务信息表。

OpenSCManager() 介绍:
功能:建立了一个到服务控制管理器的连接,并打开指定的数据库。
函数原型:SC_HANDLE OpenSCManager(
                  LPCSTR lpMachineName,   // 指向零终止字符串,指定目标计算机的名称。  通常为 NULL。

LPCSTR lpDatabaseName, // 指向零终止字符串,指定将要打开的服务控制管理数据库的名称。通常为 NULL。

DWORD  dwDesiredAccess  // 指定服务访问控制管理器的权限。通常为 SC_MANAGER_ALL_ACCESS。
                  );
参数:
lpMachineName
指向零终止字符串,指定目标计算机的名称。
如果该指针为NULL ,或者它指向一个空字符串,那么该函数连接到本地计算机上的服务控制管理器。
lpDatabaseName
指向零终止字符串,指定将要打开的服务控制管理数据库的名称。
此字符串应被置为 SERVICES_ACTIVE_DATABASE。
如果该指针为NULL ,则打开默认的 SERVICES_ACTIVE_DATABASE 数据库。
dwDesiredAccess
指定服务访问控制管理器的权限。
在授予要求的权限前,系统会检查调用进程的权限令牌,该令牌针对与服务控制管理器相关的安全描述符的权限控制列表。
此外,该函数的调用将隐式地指定 SC_MANAGER_CONNECT 的访问权限。
此外,下列服务控制管理器对象的访问类型可以被指定:
SC_MANAGER_ALL_ACCESS 除了所有此表中列出的访问类型,还包括 STANDARD_RIGHTS_REQUIRED。
SC_MANAGER_CONNECT 可以连接到服务控制管理器。
SC_MANAGER_CREATE_SERVICE 使要求的 CreateService 函数创建一个服务对象,并将其添加到数据库中。
SC_MANAGER_ENUMERATE_SERVICE 使要求的 EnumServicesStatus 功能清单的服务,这是在数据库中。
SC_MANAGER_LOCK 使要求的 LockServiceDatabase 功能获得锁定数据库。
SC_MANAGER_QUERY_LOCK_STATUS 使要求的 QueryServiceLockStatus 检索功能锁定状态信息的数据库。
 
返回值
如果函数成功,返回值是一个指定的服务控制管理器数据库的句柄。如果函数失败,返回值为NULL 。
 
OpenService() 介绍:
功能:打开一个服务对象。
函数原型:SC_HANDLE OpenService(
                  SC_HANDLE hSCManager,   // 使用 OpenSCManager() 打开后返回的对象句柄。
                  LPCSTR  lpServiceName,      // 需要打开的服务的名称,其中不能出现斜杆。
                  DWORD  dwDesiredAccess   // 打开权限。通常为 SC_MANAGER_ALL_ACCESS。
                  );
参数:
lpServiceName
这是在创建服务对象时由 CreateService 函数的 lpServiceName 参数指定的名称,
而不是用户界面应用程序显示的用于标识服务的服务显示名称。
dwDesiredAccess
权限同上。
在授予请求的访问权限之前, 系统将根据与服务对象关联的安全描述符的自由访问控制列表检查调用进程的访问令牌。
返回值:如果函数成功, 则返回值是服务的句柄。如果函数失败,返回值为NULL 。

CreateService() 介绍:
功能:创建一个服务对象,并将其添加到指定的服务控制管理器数据库的函数。

函数原型:SC_HANDLE CreateService(
                  SC_HANDLE  hSCManager,    // 服务控制管理器数据库的句柄。
                  LPCSTR  lpServiceName,    // 要安装的服务的名称。
                  LPCSTR  lpDisplayName,  // 用户界面程序用来标识服务的显示名称。
                  DWORD  dwDesiredAccess, // 对服务的访问权限。通常为 SC_MANAGER_ALL_ACCESS。
                  DWORD  dwServiceType,  // 服务类型。 通常为 SERVICE_WIN32_OWN_PROCESS。
                  DWORD  dwStartType,   // "服务启动" 选项。通常为 SERVICE_AUTO_START。
                  DWORD  dwErrorControl, // 错误的严重性和所采取的操作。
                  LPCSTR  lpBinaryPathName,  // 服务二进制文件的完全限定路径。
                  LPCSTR  lpLoadOrderGroup,  // 通常不关心,设置为 NULL。
                  LPDWORD  lpdwTagId,  // 通常不关心,设置为 NULL。
                  LPCSTR lpDependencies,  // 通常不关心,设置为 NULL。
                  LPCSTR  lpServiceStartName,  // 通常不关心,设置为 NULL。
                  LPCSTR  lpPassword  // 通常不关心,设置为 NULL。
                  );

参数:

hSCManager

服务控制管理器数据库的句柄。此句柄由 OpenSCManager 函数返回,

并且必须具有 SC_MANAGER_CREATE_SERVICE 访问权限。

lpServiceName

要安装的服务的名称。最大字符串长度为256个字符。

服务控制管理器数据库保留字符的大小写, 但服务名称比较始终不区分大小写。正斜杠 (/) 和反斜线 () 不是有效的服务名称字符。

lpDisplayName

用户界面程序用来标识服务的显示名称。此字符串的最大长度为256个字符。

该名称在服务控制管理器中保留为 case。显示名称比较始终不区分大小写。

dwDesiredAccess

对服务的访问。在授予请求的访问权限之前, 系统将检查调用进程的访问令牌。值同 OpenSCManager() 的该参数。

dwServiceType

服务类型

含义
SERVICE_FILE_SYSTEM_DRIVER 文件系统驱动程序服务。
SERVICE_KERNEL_DRIVER 驱动程序服务。
SERVICE_WIN32_OWN_PROCESS 在其自己的进程中运行的服务。(常用的值)
SERVICE_USER_OWN_PROCESS 该服务在登录用户帐户下在其自己的进程中运行。

dwStartType

"服务启动" 选项

含义
SERVICE_AUTO_START  在系统启动期间, 服务控制管理器自动启动服务。(常用的值)
SERVICE_BOOT_START 由系统加载器启动的设备驱动程序。此值仅对驱动程序服务有效。
SERVICE_DEMAND_START 当进程调用 StartService 函数时, 由服务控制管理器启动的服务。
SERVICE_DISABLED 无法启动的服务。尝试启动服务会导致错误代码 ERROR_SERVICE_DISABLED。
SERVICE_SYSTEM_START 由 IoInitSystem 函数启动的设备驱动程序。此值仅对驱动程序服务有效。

dwErrorControl

错误的严重性和所采取的操作

含义
SERVICE_ERROR_CRITICAL 如果可能, 启动程序会在事件日志中记录错误。如果正在启动最后一次已知良好的配置, 则启动操作将失败。否则, 系统将以最后一次正确的配置重新启动。
SERVICE_ERROR_IGNORE 启动程序忽略错误并继续启动操作。
SERVICE_ERROR_NORMAL 启动程序在事件日志中记录错误, 但继续启动操作。
SERVICE_ERROR_SEVERE 启动程序在事件日志中记录错误。如果正在启动最后一次已知良好的配置, 则启动操作将继续进行。否则, 系统将以上次已知良好的配置重新启动。

lpBinaryPathName

服务二进制文件的完全限定路径。如果路径包含空格, 则必须引用它以使其正确解释。
该路径还可以包含自动启动服务的参数。例如, "d:\myshare\myservice.exe arg1 arg2"。这些参数被传递到服务入口点。
如果在另一台计算机上指定路径, 则该共享必须由本地计算机的计算机帐户访问, 因为这是远程调用中使用的安全上下文。

但是, 此要求允许远程计算机中的任何潜在漏洞影响本地计算机。因此, 最好使用本地文件。

返回值:如果函数成功, 则返回值是服务的句柄。如果函数失败, 返回值为 NULL。

StartService() 介绍:
功能:启动服务。

函数原型:BOOL StartService(
                  SC_HANDLE hService,

//此句柄由 OpenService 或 CreateService 函数返回, 并且必须具有 SERVICE_START 访问权限。
                  DWORD     dwNumServiceArgs,  //  通常不关心,设置为 NULL。
                  LPCSTR    *lpServiceArgVectors  //  通常不关心,设置为 NULL。
                  );

返回值:非零表示成功,零表示失败。

QueryServiceStatus() 介绍:

功能:检索指定服务的当前状态。

函数原型:BOOL QueryServiceStatus(
                  SC_HANDLE   hService,

// 此句柄由 OpenService 或 CreateService 函数返回, 并且必须具有 SERVICE_START 访问权限。
                  LPSERVICE_STATUS  lpServiceStatus // 指向接收状态信息的 SERVICE_STATUS 结构的指针。
                  );

返回值:非零表示成功,零表示失败。

ControlService() 介绍:

功能:向服务发送控制代码。

函数原型:BOOL ControlService(
                  SC_HANDLE   hService,

// 此句柄由 OpenService 或 CreateService 函数返回, 并且必须具有 SERVICE_START 访问权限。
                  DWORD   dwControl,   // 控制代码。
                  LPSERVICE_STATUS  lpServiceStatus  // 指向接收最新服务状态信息的 SERVICE_STATUS 结构的指针。
                  );

参数

dwControl

控制代码 含义
SERVICE_CONTROL_CONTINUE 通知暂停的服务应恢复。hService 句柄必须具有 SERVICE_PAUSE_CONTINUE 访问权限。
SERVICE_CONTROL_INTERROGATE 通知服务应将其当前状态信息报告给服务控制管理器。hService 句柄必须具有 SERVICE_INTERROGATE 访问权限。
SERVICE_CONTROL_NETBINDADD 通知网络服务有一个用于绑定的新组件。hService 句柄必须具有 SERVICE_PAUSE_CONTINUE 访问权限。
SERVICE_CONTROL_NETBINDDISABLE 通知网络服务其中一个绑定已被禁用。hService 句柄必须具有 SERVICE_PAUSE_CONTINUE 访问权限。
SERVICE_CONTROL_NETBINDENABLE 通知网络服务已启用已禁用的绑定。hService 句柄必须具有 SERVICE_PAUSE_CONTINUE 访问权限。
SERVICE_CONTROL_NETBINDREMOVE 通知网络服务已删除绑定的组件。hService 句柄必须具有 SERVICE_PAUSE_CONTINUE 访问权限。
SERVICE_CONTROL_PARAMCHANGE 通知服务其启动参数已更改。hService 句柄必须具有 SERVICE_PAUSE_CONTINUE 访问权限。
SERVICE_CONTROL_PAUSE 通知服务应暂停。hService 句柄必须具有 SERVICE_PAUSE_CONTINUE 访问权限。
SERVICE_CONTROL_STOP 通知服务应停止。hService 句柄必须具有 SERVICE_STOP 访问权限。

返回值:非零表示成功,零表示失败。

DeleteService() 介绍:

功能:将指定的服务标记为从服务控制管理器数据库中删除。

函数原型:BOOL DeleteService(
                  SC_HANDLE hService // 此句柄由 OpenService 或 CreateService 函数返回, 并且必须具有 "删除" 访问权限。
                  );

返回值:非零表示成功,零表示失败。

CloseServiceHandle() 介绍:

功能:关闭服务控制管理器或服务对象的句柄。

函数原型:BOOL CloseServiceHandle(
                  SC_HANDLE hSCObject  // 要关闭的服务控件管理器对象或服务对象的句柄。
                  );

参数

hSCObject

要关闭的服务控件管理器对象或服务对象的句柄。

服务控制管理器对象的句柄由 OpenSCManager 函数返回, 并且服务对象的句柄由 OpenService 或 CreateService 函数返回。

返回值:非零表示成功,零表示失败。

DemoCode: 

#include<stdio.h>
#include<Windows.h>
#include<winsock.h>
#pragma comment(lib, "Advapi32")
#pragma comment(lib,"ws2_32")
#define MYPORT 1234
#define BACKLOG 10
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
SC_HANDLE SCManager;
SC_HANDLE SCService;
void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv);
void WINAPI ServiceHandler(DWORD fdwControl);
void InstallService();
void StartService0();
void StopService();
void UnInstallService();
void MyWork(); // 自定义特定功能的函数。本打算用线程调用完成的,简单起见就这样吧。
//DWORD WINAPI MyWork(LPVOID lpParam); 该函数涉及到线程,先放这里。
int main(void)
{
SERVICE_TABLE_ENTRY ServTable[];
ServTable[].lpServiceName = (LPSTR)"Test";
ServTable[].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServTable[].lpServiceName = NULL;
ServTable[].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServTable);
InstallService();
StartService0();
return ;
} void WINAPI ServiceMain(DWORD dwArgc, LPSTR *lpszArgv)
{
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = ;
ServiceStatus.dwCheckPoint = ;
ServiceStatus.dwServiceSpecificExitCode = ;
ServiceStatus.dwWaitHint = ;
hStatus = RegisterServiceCtrlHandler("BackDoor",
(LPHANDLER_FUNCTION)ServiceHandler);
if (!hStatus)
{
printf("Register Service Error!\n");
system("pause");
return;
}
SetServiceStatus(hStatus, &ServiceStatus);
if (GetLastError() != NO_ERROR)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = ;
ServiceStatus.dwWaitHint = ;
SetServiceStatus(hStatus, &ServiceStatus);
printf("Start Error!\n");
system("pause");
return;
}
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = ;
ServiceStatus.dwWaitHint = ;
SetServiceStatus(hStatus, &ServiceStatus);
// 从这里开始可以放入你想服务为你做的事情。
/*
HANDLE hThread = CreateThread(NULL, 0, MyWork, NULL, 0, NULL);
if (hThread = NULL)
return;
*/
MyWork();
return;
} void WINAPI ServiceHandler(DWORD fdwControl)
{
switch (fdwControl)
{
case SERVICE_CONTROL_PAUSE:
ServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwCheckPoint = ;
ServiceStatus.dwWaitHint = ;
SetServiceStatus(hStatus, &ServiceStatus);
StopService();
UnInstallService();
return;
default:
break;
}
SetServiceStatus(hStatus, &ServiceStatus);
return;
} void InstallService()
{
char PathName[MAX_PATH];
char SysName[MAX_PATH];
GetModuleFileName(NULL, PathName, MAX_PATH);
GetSystemDirectory(SysName, MAX_PATH);
wsprintf(SysName, "%s\\Test.exe", SysName);
if (!MoveFile(PathName, SysName))
{
printf(" Move File Error!\n");
system("pause");
return;
}
SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCManager == NULL)
{
printf("OpenSCManager Error!\n");
system("pause");
return;
}
SCService = CreateService(
SCManager,
"BackDoor",
"Service32",
SC_MANAGER_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_IGNORE,
SysName,
NULL, NULL, NULL, NULL, NULL);
if (SCService == NULL)
{
printf("CreateService Error!\n");
CloseServiceHandle(SCManager);
system("pause");
return;
}
printf("Create Service Succeed!\n");
CloseServiceHandle(SCService);
CloseServiceHandle(SCManager);
return;
} void StartService0()
{
SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCManager == NULL)
{
printf("OpenSCManager Error!\n");
system("pause");
return;
}
SCService = OpenService(SCManager, "BackDoor", SC_MANAGER_ALL_ACCESS);
if(SCService == NULL)
{
printf("OpenService Error!\n");
CloseServiceHandle(SCManager);
system("pause");
return;
}
if (StartService(SCService, NULL, NULL))
{
while (QueryServiceStatus(SCService,&ServiceStatus))
{
if (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
break;
else
Sleep();
}
printf("Service Start Succeed!\n");
}
CloseServiceHandle(SCService);
CloseServiceHandle(SCManager);
return;
} void StopService()
{
SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCManager == NULL)
{
printf("OpenSCManager Error!\n");
system("pause");
return;
}
SCService = OpenService(SCManager, "BackDoor", SC_MANAGER_ALL_ACCESS);
if (SCService == NULL)
{
printf("Open Service Error!\n");
CloseServiceHandle(SCManager);
system("pause");
return;
}
if (ControlService(SCService, SERVICE_CONTROL_STOP, &ServiceStatus))
{
while (QueryServiceStatus(SCService, &ServiceStatus))
{
if (ServiceStatus.dwCurrentState == SERVICE_STOPPED)
break;
else
Sleep();
}
printf("Service Stop Succeed!\n");
}
CloseServiceHandle(SCService);
CloseServiceHandle(SCManager);
return;
} void UnInstallService()
{
SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (SCManager == NULL)
{
printf("OpenSCManager Error!\n");
system("pause");
return;
}
SCService = OpenService(SCManager, "BackDoor", SC_MANAGER_ALL_ACCESS);
if (SCService == NULL)
{
printf("Open Service Error!\n");
CloseServiceHandle(SCManager);
system("pause");
return;
}
if (DeleteService(SCService))
printf("Uninstall Service Succeed!\n");
else
printf("Unistall Service Error!\n");
CloseServiceHandle(SCService);
CloseServiceHandle(SCManager);
return;
} void MyWork()
{
SOCKET sockfd, new_fd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size = sizeof(struct sockaddr_in);
WSADATA ws;
if (WSAStartup(MAKEWORD(, ), &ws) != )
{
printf("WSAStart up Error!\n");
WSACleanup();
system("pause");
exit();
}
if ((sockfd = socket(AF_INET, SOCK_STREAM, )) == INVALID_SOCKET)
{
printf("Socket Error!\n");
system("pause");
exit();
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(MYPORT);
my_addr.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -)
{
printf("Bind Error!\n");
closesocket(sockfd);
system("pause");
exit();
}
if (listen(sockfd, BACKLOG) == SOCKET_ERROR)
{
printf("Listen Error!\n");
closesocket(sockfd);
system("pause");
exit();
}
if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == INVALID_SOCKET)
{
printf("Accept Error!\n");
closesocket(sockfd);
exit();
}
closesocket(sockfd);
closesocket(new_fd);
WSACleanup();
return;
} /*
DWORD WINAPI MyWork(LPVOID lpParam)
{
return 0;
}
*/

这个程序需要用管理员身份运行,运行结果如下图:

Windows 服务程序(二)的更多相关文章

  1. Windows服务二:测试新建的服务、调试Windows服务

    一.测试Windows服务 为了使Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点.像其他应用程序一样,Windows服务也是在Program.cs的Main ...

  2. Windows服务程序和安装程序制作

    转:http://www.cr173.com/html/15350_1.html 本文介绍了如何用C#创建.安装.启动.监控.卸载简单的Windows Service 的内容步骤和注意事项. 一.创建 ...

  3. .net Windows服务程序和安装程序制作图解 及 VS 2010创建、安装、调试 windows服务(windows service)

    .net Windows服务程序和安装程序制作 最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作 ...

  4. 创建一个Windows服务程序与实现定时器效果

    1.创建一个Windows服务程序 一.   新建Window服务项目 二.   添加安装程序 三.   配置服务属性 四.   编写定时器代码 publicpartialclassService1 ...

  5. 如何在Windows服务程序中添加U盘插拔的消息

    研究了下这个问题,主要要在一般的windows服务程序中修改两个地方: 一.调用RegisterServiceCtrlHandlerEx VOID WINAPI SvcMain( DWORD dwAr ...

  6. 用Visual C#创建Windows服务程序

    一.Windows服务介绍: Windows服务以前被称作NT服务,是一些运行在Windows NT.Windows 2000和Windows XP等操作系统下用户环境以外的程序.在以前,编写Wind ...

  7. .NET 跨平台RPC框架DotNettyRPC Web后台快速开发框架(.NET Core) EasyWcf------无需配置,无需引用,动态绑定,轻松使用 C# .NET 0配置使用Wcf(半成品) C# .NET Socket 简单实用框架 C# .NET 0命令行安装Windows服务程序

    .NET 跨平台RPC框架DotNettyRPC   DotNettyRPC 1.简介 DotNettyRPC是一个基于DotNetty的跨平台RPC框架,支持.NET45以及.NET Standar ...

  8. 用C/C++创建windows服务程序

    转载:https://blog.csdn.net/chenyujing1234/article/details/8023816 一.演示过程下方代码演示了如何使用vs(C/C++)创建windows服 ...

  9. WCF学习之旅—WCF服务的Windows 服务程序寄宿(十一)

    上接    WCF学习之旅—WCF服务部署到IIS7.5(九) WCF学习之旅—WCF服务部署到应用程序(十) 七 WCF服务的Windows 服务程序寄宿 这种方式的服务寄宿,和IIS一样有一个一样 ...

随机推荐

  1. python串口工具的使用!!!!一定要加timeout=!!!!

    不指定timeout参数的话,就各种报错,如下: 而前面的串口,波特率则不需要指明.

  2. PyTorch在笔记本上实现CUDA加速

    最近刚开始学习深度学习,参考了一篇深度学习的入门文章,原文链接:https://medium.freecodecamp.org/everything-you-need-to-know-to-maste ...

  3. FreeSql (四)实体特性 Fluent Api

    FreeSql 提供使用 Fluent Api, 在外部配置实体的数据库特性,Fluent Api 的方法命名与特性名保持一致,如下: fsql.CodeFirst .ConfigEntity< ...

  4. FreeSql (二十一)查询返回数据

    FreeSql 采用 ExpressionTree 优化读取速读,如果懂技术的你一定知道 .NETCore 技术下除了原生代码,最快就是 Emit 和 ExpressionTree. 项目在初期使用的 ...

  5. 错误:java.lang.Exception: No tests found matching Method testPrePage1(egou_manager_web.TestEBrand) from org.junit.internal.requests.ClassRequest@4f3cc73c

    今天测试分页时出现以下错误: java.lang.Exception: No tests found matching Method testPrePage1(egou_manager_web.Tes ...

  6. Android开发教程:开发框架基本原理

    1.提供应用程序框架(Framework) 开发者可以遵照这些框架搭建应用程序读者可以结合J2SE平台的Applet框架或J2ME平台的移动信息设备套件框架来理解Android平台的应用程序框架. 每 ...

  7. Redis常用命令(key、string、List)

    1.Key 1.keys *   查询所有数据 2.exists key名   判断key名是否存在 3.move key名  数据库号(0-15)  移动数据key名到相应的数据库 4.expire ...

  8. Day 5文件管理—三剑客的了解

    文件的下载 wget curl 1.文件的上传 rz sz #不支持拷贝文件夹 文件内容进行 排序 sort ,去重uniq, 统计 文件的截取 cut awk sed .... | ######3. ...

  9. 006:CSS高级技巧

    目录 前言 理论 CSS高级技巧 一:元素的显示与隐藏 在CSS中有三个显示和隐藏的单词比较常见,我们要区分开,他们分别是 display visibility 和 overflow. 他们的主要目的 ...

  10. Django-官网查询部分翻译(1.11版本文档)-QuerySet-字段查找-06

    目录 Making queries 进行查询 创建一个对象(一条数据记录) 保存修改的表对象 保存外键字段或多对多字段(ForeignKey or ManyToManyField fields) Re ...