1. 程式人生 > >[Win32] SCManager 服務控制管理器API(2)

[Win32] SCManager 服務控制管理器API(2)

在上一篇博文“[Win32] SCManager 服務控制管理器API(1)”中(地址:http://blog.csdn.net/zuishikonghuan/article/details/47803033),講到了開啟服務控制管理器、建立服務、開啟服務、刪除服務、獲取服務狀態、啟動服務、傳送控制碼,這一篇繼續。

9。EnumServicesStatus 列舉服務

BOOL WINAPI EnumServicesStatus(
  _In_        SC_HANDLE             hSCManager,
  _In_        DWORD                 dwServiceType,
  _In_        DWORD                 dwServiceState,
  _Out_opt_   LPENUM_SERVICE_STATUS lpServices,
  _In_        DWORD                 cbBufSize,
  _Out_       LPDWORD               pcbBytesNeeded,
  _Out_       LPDWORD               lpServicesReturned,
  _Inout_opt_ LPDWORD               lpResumeHandle
);

hSCManager:服務控制管理器控制代碼。此控制代碼是OpenSCManager函式返回的,並且必須具有 SC_MANAGER_ENUMERATE_SERVICE 訪問許可權。

dwServiceType:要列舉的服務型別。

SERVICE_DRIVER:SERVICE_KERNEL_DRIVER 和 SERVICE_FILE_SYSTEM_DRIVER。

SERVICE_FILE_SYSTEM_DRIVER:檔案系統驅動程式服務。

SERVICE_KERNEL_DRIVER:驅動程式服務。

SERVICE_WIN32:SERVICE_WIN32_OWN_PROCESS 和 SERVICE_WIN32_SHARE_PROCESS。

SERVICE_WIN32_OWN_PROCESS:在他們自己的程序中執行的服務。

SERVICE_WIN32_SHARE_PROCESS:與一個或多個其他服務共享一個程序的服務。
一般為SERVICE_WIN32

dwServiceState:服務要列舉的狀態。此引數可以是下列值之一:

SERVICE_ACTIVE:列舉是處於以下狀態的服務: SERVICE_START_PENDING、 SERVICE_STOP_PENDING、 SERVICE_RUNNING、SERVICE_CONTINUE_PENDING、 SERVICE_PAUSE_PENDING 和 SERVICE_PAUSED。

SERVICE_INACTIVE:列舉服務處於 SERVICE_STOPPED 狀態。

SERVICE_STATE_ALL:SERVICE_ACTIVE 和 SERVICE_INACTIVE。

lpServices:指向包含陣列的 ENUM_SERVICE_STATUS 結構,它接收名稱服務資料庫中的每個服務的狀態資訊的緩衝區的指標。緩衝區必須足夠大以容納結構,再加上他們的成員所指向的字串。此陣列的最大大小為 256 K 位元組。若要確定所需的大小,請為此引數與 cbBufSize 引數置 0。該函式將失敗,時出錯將返回 ERROR_INSUFFICIENT_BUFFER。PcbBytesNeeded 引數將收到所需的大小。

ENUM_SERVICE_STATUS 結構:

typedef struct _ENUM_SERVICE_STATUS {
  LPTSTR         lpServiceName;
  LPTSTR         lpDisplayName;
  SERVICE_STATUS ServiceStatus;
} ENUM_SERVICE_STATUS, *LPENUM_SERVICE_STATUS;

lpServiceName:服務名稱

lpDisplayName:顯示名稱

ServiceStatus:服務狀態

cbBufSize:以位元組為單位所指向的緩衝區的大小

pcbBytesNeeded:如果緩衝區太小,指向接收的需要返回剩餘的服務條目的位元組數的變數的指標。

lpServicesReturned:指向一個變數來接收服務項數返回的指標。

lpResumeHandle:一個指標指向的變數的輸入,指定列舉的起始點。你必須第一次呼叫此函式設定此值為零。

返回值:如果此函式成功,返回值不為零。如果函式失敗,返回值為零。

10。QueryServiceConfig 獲取服務配置引數

BOOL WINAPI QueryServiceConfig(
  _In_      SC_HANDLE              hService,
  _Out_opt_ LPQUERY_SERVICE_CONFIG lpServiceConfig,
  _In_      DWORD                  cbBufSize,
  _Out_     LPDWORD                pcbBytesNeeded
);

hService:務的控制代碼。此控制代碼是OpenService 或 CreateService函式返回的,並且它必須具有 SERVICE_QUERY_CONFIG 訪問許可權。

lpServiceConfig:指向接收服務配置資訊的緩衝區的指標。資料的格式是一個 QUERY_SERVICE_CONFIG 結構。

QUERY_SERVICE_CONFIG結構:

typedef struct _QUERY_SERVICE_CONFIG {
  DWORD  dwServiceType;
  DWORD  dwStartType;
  DWORD  dwErrorControl;
  LPTSTR lpBinaryPathName;
  LPTSTR lpLoadOrderGroup;
  DWORD  dwTagId;
  LPTSTR lpDependencies;
  LPTSTR lpServiceStartName;
  LPTSTR lpDisplayName;
} QUERY_SERVICE_CONFIG, *LPQUERY_SERVICE_CONFIG;

dwServiceType:見上一篇中對”Createservice“的介紹。(傳送門

dwStartType:見上一篇中對”Createservice“的介紹。(傳送門

dwErrorControl:見上一篇中對”Createservice“的介紹。(傳送門

lpBinaryPathName:見上一篇中對”Createservice“的介紹。(傳送門

lpLoadOrderGroup:見上一篇中對”Createservice“的介紹。(傳送門

dwTagId:見上一篇中對”Createservice“的介紹。(傳送門

lpDependencies:見上一篇中對”Createservice“的介紹。(傳送門

lpServiceStartName:如果服務型別為 SERVICE_WIN32_OWN_PROCESS 或 SERVICE_WIN32_SHARE_PROCESS,此成員是帳戶的服務程序將登入作為執行時的名稱。此名稱可以是Domain\UserName。如果該帳戶屬於內建域,名稱可以是.\UserName。如果程序執行在本地系統帳戶下,名稱也可以"LocalSystem"。
如果服務型別為 SERVICE_KERNEL_DRIVER 或 SERVICE_FILE_SYSTEM_DRIVER,此成員是驅動程式物件名稱 (即,\FileSystem\Rdr 或 \Driver\Xns),輸入和輸出 (I/O) 系統使用載入裝置驅動程式。如果此成員為 NULL,驅動程式是由 I/O 系統,根據服務名稱建立的預設物件名稱執行。

lpDisplayName:服務描述。能超過型別為 REG_SZ 登錄檔值的大小。也可以指定為這樣:@[path\]dllname,-strID。請參見MSDN文件的RegLoadMUIString

cbBufSize:以位元組為單位的緩衝區的大小

pcbBytesNeeded:如果緩衝區太小,指向接收的需要返回剩餘的服務條目的位元組數的變數的指標。

返回值:如果此函式成功,返回值不為零。如果函式失敗,返回值為零。

11。QueryServiceConfig2 獲取服務配置可選引數
BOOL WINAPI QueryServiceConfig2(
  _In_      SC_HANDLE hService,
  _In_      DWORD     dwInfoLevel,
  _Out_opt_ LPBYTE    lpBuffer,
  _In_      DWORD     cbBufSize,
  _Out_     LPDWORD   pcbBytesNeeded
);

hService:服務控制代碼。此控制代碼是 OpenService 或 CreateService 函式返回的,並且它必須具有 SERVICE_QUERY_CONFIG 訪問許可權。

dwInfoLevel:要查詢的配置資訊。此引數可以是下列值之一:

SERVICE_CONFIG_DELAYED_AUTO_START_INFO:LpInfo 引數是指向 SERVICE_DELAYED_AUTO_START_INFO 結構的指標。Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONFIG_DESCRIPTION:緩衝區引數是指向 SERVICE_DESCRIPTION 結構的指標。

SERVICE_CONFIG_FAILURE_ACTIONS:緩衝區引數是指向 SERVICE_FAILURE_ACTIONS 結構的指標。

SERVICE_CONFIG_FAILURE_ACTIONS_FLAG:LpInfo 引數是指向 SERVICE_FAILURE_ACTIONS_FLAG 結構的指標。Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONFIG_PREFERRED_NODE:LpInfo 引數是指向 SERVICE_PREFERRED_NODE_INFO 結構的指標。Windows Server 2008、 Windows Vista、 Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONFIG_PRESHUTDOWN_INFO:LpInfo 引數是指向 SERVICE_PRESHUTDOWN_INFO 結構的指標。Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONFIG_REQUIRED_PRIVILEGES_INFO:LpInfo 引數是指向 SERVICE_REQUIRED_PRIVILEGES_INFO 結構的指標。Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONFIG_SERVICE_SID_INFO:LpInfo 引數是指向 SERVICE_SID_INFO 結構的指標。Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONFIG_TRIGGER_INFO:LpInfo 引數是指向 SERVICE_TRIGGER_INFO 結構的指標。Windows Server 2008、 Windows Vista、 Windows Server 2003 和 Windows XP: 不支援此值。

SERVICE_CONFIG_LAUNCH_PROTECTED:LpInfo 引數是一個 SERVICE_LAUNCH_PROTECTED_INFO 結構的指標。此值從 Windows 8.1 開始支援。

lpBuffer:指向接收服務配置資訊的緩衝區的指標。此資料的格式取決於 dwInfoLevel 引數的值。
此陣列的最大大小為 8k 位元組。若要確定所需的大小,請將此引數與 cbBufSize 引數設定為 0。該函式將失敗GetLastError返回 ERROR_INSUFFICIENT_BUFFER。PcbBytesNeeded 引數接收所需的大小。

SERVICE_DESCRIPTION 結構:

typedef struct _SERVICE_DESCRIPTION {
  LPTSTR lpDescription;
} SERVICE_DESCRIPTION, *LPSERVICE_DESCRIPTION;

lpDescription:服務描述。能超過型別為 REG_SZ 登錄檔值的大小。也可以指定為這樣:@[path\]dllname,-strID。請參見MSDN文件的RegLoadMUIString

SERVICE_FAILURE_ACTIONS 結構:

typedef struct _SERVICE_FAILURE_ACTIONS {
  DWORD     dwResetPeriod;
  LPTSTR    lpRebootMsg;
  LPTSTR    lpCommand;
  DWORD     cActions;
  SC_ACTION *lpsaActions;
} SERVICE_FAILURE_ACTIONS, *LPSERVICE_FAILURE_ACTIONS;
dwResetPeriod:以秒為單位,表示服務失敗計數在沒有錯誤下重置的時間,INFINITE表示永遠不會被重置 lpRebootMsg:要重新啟動 SC_ACTION_REBOOT 服務控制器動作響應之前廣播到伺服器的使用者的訊息。對於修改配置,如果此值為 NULL,重新啟動訊息是不變的。如果值為空字串 (""),重新啟動訊息將被刪除並沒有訊息被廣播。 lpCommand:響應 SC_ACTION_RUN_COMMAND 時執行程序的命令列。這一過程在相同的服務帳戶下執行。對於修改配置,如果此值為 NULL,該命令是不變的。如果值為空字串 (""),該命令刪除並且服務失敗時不執行任何程式。 cActions:LpsaActions 陣列中的元素數。對於修改配置,如果此值為 0,但 lpsaActions 不是 NULL,刪除重置期間和失敗操作的陣列。 lpsaActions:指向一個 SC_ACTION 結構陣列的指標。對於修改配置,如果此值為 NULL,則忽略,cActions 和 dwResetPeriod 的成員。 SC_ACTION 結構:
typedef struct _SC_ACTION {
  SC_ACTION_TYPE Type;
  DWORD          Delay;
} SC_ACTION, *LPSC_ACTION;
Type:要執行的操作。此成員可以是下列之一:
SC_ACTION_NONE:沒有行動。

SC_ACTION_REBOOT:重新啟動計算機。

SC_ACTION_RESTART:重新啟動該服務。

SC_ACTION_RUN_COMMAND:執行一個命令。
Delay:在執行指定的操作,以毫秒為單位之前等待的時間。
備註:服務啟動失敗時,系統啟動的次數進行計數。經過 dwResetPeriod 秒時,計數重置為 0。當服務失敗第 n 次時,服務控制器執行 lpsaActions 陣列中的元素 [N-1] 中指定的操作。如果 N 大於 cActions,服務控制器重複上次運算元組中。

cbBufSize:以位元組為單位的緩衝區的大小

pcbBytesNeeded:如果緩衝區太小,指向接收的需要返回剩餘的服務條目的位元組數的變數的指標。

返回值:如果此函式成功,返回值不為零。如果函式失敗,返回值為零。

12。ChangeServiceConfig 修改服務配置引數

BOOL WINAPI ChangeServiceConfig(
  _In_      SC_HANDLE hService,
  _In_      DWORD     dwServiceType,
  _In_      DWORD     dwStartType,
  _In_      DWORD     dwErrorControl,
  _In_opt_  LPCTSTR   lpBinaryPathName,
  _In_opt_  LPCTSTR   lpLoadOrderGroup,
  _Out_opt_ LPDWORD   lpdwTagId,
  _In_opt_  LPCTSTR   lpDependencies,
  _In_opt_  LPCTSTR   lpServiceStartName,
  _In_opt_  LPCTSTR   lpPassword,
  _In_opt_  LPCTSTR   lpDisplayName
);

hService:服務控制代碼。此控制代碼是OpenService 或 CreateService函式返回的,並且必須具有 SERVICE_CHANGE_CONFIG 訪問許可權。

從 dwServiceType 到 lpServiceStartName :參見上面的QUERY_SERVICE_CONFIG結構(快速跳轉

lpPassword:LpServiceStartName 引數所指定的帳戶名稱的密碼。如果您不更改現有的密碼,請指定 NULL。如果該帳戶沒有密碼,或在本地、 網路服務或本地系統帳戶執行該服務,請指定空字串。

lpDisplayName:服務描述。能超過型別為 REG_SZ 登錄檔值的大小。也可以指定為這樣:@[path\]dllname,-strID。請參見MSDN文件的RegLoadMUIString

返回值:如果此函式成功,返回值不為零。如果函式失敗,返回值為零。

13。ChangeServiceConfig2 修改服務配置可選引數

BOOL WINAPI ChangeServiceConfig2(
  _In_     SC_HANDLE hService,
  _In_     DWORD     dwInfoLevel,
  _In_opt_ LPVOID    lpInfo
);

hService:服務的控制代碼。此控制代碼是OpenService 或 CreateService函式返回的,並且必須具有 SERVICE_CHANGE_CONFIG 訪問許可權。

dwInfoLevel:見上面QueryServiceConfig2的相關內容(快速跳轉

lpInfo:見上面QueryServiceConfig2的相關內容(快速跳轉

返回值:如果此函式成功,返回值不為零。如果函式失敗,返回值為零。

示例原始碼: 引數說明和程式碼註釋就不寫了,如果看過上文理解下面的很輕鬆。 ①列舉服務
BOOL WINAPI ListWin32Service(){
	SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
	if (hSCManager != NULL){
		DWORD BytesNeeded;
		DWORD count;
		EnumServicesStatus(hSCManager, SERVICE_WIN32, SERVICE_STATE_ALL, NULL, 0, &BytesNeeded, &count, 0);
		char* buffer = new char[BytesNeeded];
		RtlZeroMemory(buffer, BytesNeeded);
		ENUM_SERVICE_STATUS* Services = (ENUM_SERVICE_STATUS*)buffer;
		if (EnumServicesStatus(hSCManager, SERVICE_WIN32, SERVICE_STATE_ALL, Services, BytesNeeded, &BytesNeeded, &count, 0)){
			for (int i = 0; i < count; i++) _putts(Services[i].lpServiceName);
			delete[] buffer;
			return TRUE;
		}
		delete[] buffer;
		CloseServiceHandle(hSCManager);
		return FALSE;
	}
	else return FALSE;
}

②修改服務描述
BOOL WINAPI SetServiceDescription(LPCTSTR ServiceName, LPTSTR Description){
	SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
	if (hSCManager != NULL){
		SC_HANDLE hService = OpenService(hSCManager, ServiceName, SERVICE_CHANGE_CONFIG);
		if (hService != NULL){
			SERVICE_DESCRIPTION desc;
			desc.lpDescription = Description;
			if (ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &desc))
			{
				CloseServiceHandle(hService);
				CloseServiceHandle(hSCManager);
				return TRUE;
			}
			CloseServiceHandle(hService);
			CloseServiceHandle(hSCManager);
			return FALSE;
		}
		CloseServiceHandle(hSCManager);
		return FALSE;
	}
	else return FALSE;
}

③讓服務啟動失敗後總是恢復
BOOL WINAPI LetServiceAlwaysReboot(LPCTSTR ServiceName){
	SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
	if (hSCManager != NULL){
		SC_HANDLE hService = OpenService(hSCManager, ServiceName, SC_MANAGER_ALL_ACCESS);//值得一提的是需要用SC_MANAGER_ALL_ACCESS
		if (hService != NULL){
			SERVICE_FAILURE_ACTIONS failact = { 0 };
			SC_ACTION act[3];
			act[0].Delay = act[1].Delay = act[2].Delay = 0;
			act[0].Type = act[1].Type = act[2].Type = SC_ACTION_RESTART;
			failact.cActions = 3;
			failact.lpsaActions = act;
			failact.dwResetPeriod = 0;
			if (ChangeServiceConfig2(hService, SERVICE_CONFIG_FAILURE_ACTIONS, &failact))
			{
				CloseServiceHandle(hService);
				CloseServiceHandle(hSCManager);
				return TRUE;
			}
			CloseServiceHandle(hService);
			CloseServiceHandle(hSCManager);
			return FALSE;
		}
		CloseServiceHandle(hSCManager);
		return FALSE;
	}
	else return FALSE;
}

 

相關推薦

[Win32] SCManager 服務控制管理API2

在上一篇博文“[Win32] SCManager 服務控制管理器API(1)”中(地址:http://blog.csdn.net/zuishikonghuan/article/details/478

DIM-00014: 無法開啟windows nt服務控制管理

在windows上安裝oracle 11g時,dbca圖形化介面出來後,前面步驟已配置好,最後安裝時出現了 DIM-00014: 無法開啟windows nt服務控制管理器      這個錯誤其實是和許可權有關   解決方法

不用寫Windows服務實現定時功能FluentScheduler

ace 簡單 要去 job macbook sharp 管理 dia 做到 MacBook Pro 只有四個 USB Type-C 接口是否錯了? 一項新技術的誕生總會對已存在的事物造成沖擊或影響,如果大家都害怕沖擊與影響,那這個世界永遠像現在不變就行了,大家都好好的,待

Qt入門 佈局管理layout

佈局layout 在Qt中,為了實現特定的功能,一般情況下我們會使用的是自己定義的視窗類。 官方提供了Qt Create來編輯的ui檔案,但是我不會使用操作編輯之後的ui,所以這裡介紹如何定義自己的佈局。 在QWidget中設定佈局 Qxxlayout類 若要佈局的視窗

npm模組管理入門轉載

npm模組管理器入門(轉) 作者原文地址:https://www.cnblogs.com/slly/p/7927760.html npm模組管理器入門 什麼是 NPM npm 是 Node 官方提供的包管理工具,他已經成了 Node 包的標準釋出平臺,用於 Node 包的釋出、傳

Spring Cloud:服務閘道zuul10

前面的文章我們介紹了,Eureka用於服務的註冊於發現,Feign支援服務的呼叫以及均衡負載,Hystrix處理服務的熔斷防止故障擴散,Spring Cloud Config服務叢集配置中心,似乎一個微服務框架已經完成了。 我們還是少考慮了一個問題,外部的應用如何來訪問內部各種各樣的微服務呢?在

Java虛擬機性能管理神器 - VisualVM2 入門

light 文章 bar tom 位置 title 列表 jdk8 div 一下載VisualVM 最新版本下載 歷史版本下載 二啟動VisualVM 三VisualVM用戶目錄 四VisualVM窗口 1應用程序窗口 2詳情窗口 五VisualVM插件 J

7javascript的程序控制結構及語句------2循環控制語句、跳轉語句、對話框

對話 ima bsp .cn while語句 prompt 彈出 asc div 一、循環控制語句 循環語句主要就是在滿足條件的情況下反復執行某一個操作,循環控制語句主要包括while語句、do...while語句 和for語句。 1、While

splash3.2學習筆記——HTTP API2

render.har     使用HAR格式返回Splash與網站互動的資訊。包含請求、響應、時間線、頭部資訊,等。     可以使用HAR Viewer顯示端點返回的視覺化資訊;與FIrefox和Chrome開發者工具中的"Netwo

zookeeper java api2

    這裡介紹其他的API對zookeeper的操作。 同步方式獲取子節點資料 public static void getChildrenSync() throws KeeperException, InterruptedException {

nova原始碼分析--API2

/etc/nova/api-paste.ini檔案中的定義了以下三個composite: [composite:osapi_compute] use = call:nova.api.openstack.urlmap:urlmap_factory /: oscomputeve

MSP430微控制器各種暫存總結2——UCS

作者:BerenCamlost 本文針對於南京理工大學的王巨集波老師的MSP430微控制器原理與應用課程,請在複習時使用。 參考資料: 王巨集波老師的PPT MSP430F6638使用者手冊 王巨集波老師實驗教程 本章最新更新日期:2018.12.2

Android Wear計時開發2

上一篇文章中我們解釋了為什麼要在Android Wear重寫這個計時器app(因為之前已經在“I’m Watch”裡面開發過了),下面我們就來看看程式碼。 我們以這個app的一個核心類開始,這個類負責控制計時器的狀態。這個類包含了4個long型別的變數:第一個代表計

簡易智慧家居管理--魔鏡2:介面

0、說些廢話 介面開發網上有兩個思路,一是傳統的前端介面開發,PHP、CSS之類的,然而我並不會前端的開發,暫時也沒這麼多時間去折騰了,所以先採用原生的介面。二是用QT來作為跨平臺的開發,先在window這邊用QT creator進行介面的佈局並且實現相應的功能,然後再用對

Redis原始碼分析三十五--- redis.c服務端的實現分析2

       在Redis服務端的程式碼量真的是比較大,如果一個一個API的學習怎麼實現,無疑是一種效率很低的做法,所以我今天對服務端的實現程式碼的學習,重在他的執行流程上,而對於他的模組設計在上一篇中我已經分析過了,不明白的同學可以接著看上篇。所以我學習分析redis服務

SDL 與 FFMPEG 音樂播放開發2——混播多個音訊

第一篇總體提了一下SDL,完全沒有提到FFMPEG。我的思路是,在說解碼之前,你起碼要知道怎麼使用解碼後的檔案。 相信大家如果看了網上的一些教程,應該已經能夠播放出PCM檔案。今天我來談談如何播放多個PCM檔案。 這回先上程式碼 #define MAX_MUSIC_DA

CODING 告訴你矽谷專案經理的專案管理之道2

優秀的專案管理者是怎麼工作的?如何幫助研發團隊高效工作?這一直是 CODING 關注的重要話題,我們不斷地打磨 CODING 研發管理系統來讓開發更簡單。 近期我們精心挑選了幾篇矽谷科技公司研發管理者的 README 進行翻譯。README 主要用來向團隊成員展示專案管理者的工作理念和工作方式,以便成員能夠

【JVM】垃圾回收總結2——七種垃圾回收型別

七種垃圾回收器型別 GC的約定引數 DefNew——Default New Generation Tenured——Serial Old ParNew——Parallel New Generation PSYoungGen&mdash

Spring Cloud ZuulAPI閘道服務2

路由詳情 傳統路由配置 傳統路由配置方式就是在不依賴與服務發現機制的情況下,通過在配置檔案中具體指定每個路由表示式與服務例項的對映關係來實現API閘道器對外部請求的路由。 單例項配置:通過zuul.routes.<route>.path與zuul.routes.<r

持久化APIJPA系列(四)管理EntityManager--執行資料庫更新

        EntityManager是應用訪問持久化上下文中的實體的介面,用來對實體Bean進行操作。我們可以使用它來建立、刪除、修改持久化的實體,以體現到資料庫中;也可以從資料庫中查詢得到實