ویرگول
ورودثبت نام
سید عمید قائم مقامی
سید عمید قائم مقامیبرنامه نویسی سیستم ویندوز و مهندسی معکوس و علاقه مند به آموزش.
سید عمید قائم مقامی
سید عمید قائم مقامی
خواندن ۶ دقیقه·۱۸ روز پیش

Services in windows


سرویس‌ها در ویندوز برنامه‌هایی هستند که در پس‌زمینه اجرا می‌شوند و به طور معمول بدون تعامل مستقیم کاربر عمل می‌کنند. این برنامه‌ها معمولاً برای انجام کارهای خاص و مداوم طراحی شده‌اند، مانند ارائه خدمات شبکه، نظارت بر سیستم، یا پردازش داده‌ها.

ویژگی‌های اصلی سرویس‌ها در ویندوز:

  1. اجرای پس‌زمینه: سرویس‌ها به گونه‌ای طراحی شده‌اند که بدون نیاز به کاربران اجرا شوند. این یعنی که آن‌ها می‌توانند در پشت صحنه و حتی در زمان راه‌اندازی سیستم (قبل از ورود کاربران) فعال شوند.

  2. مدیریت سیستم: بسیاری از سرویس‌ها به مدیریت منابع سیستم، مانند حافظه، پردازنده و شبکه کمک می‌کنند. به عنوان مثال، سرویس‌هایی مانند "Windows Update" به طور منظم به‌روزرسانی‌های امنیتی و نرم‌افزاری را برای سیستم نصب می‌کنند.

  3. شروع به کار خودکار: سرویس‌ها می‌توانند به صورت خودکار با شروع ویندوز فعال شوند. این می‌تواند شامل تنظیماتی باشد که سرویس به صورت دستی، خودکار یا غیرفعال تنظیم شود.

  4. عدم وابستگی به حساب کاربر: سرویس‌ها به حساب کاربری نیاز ندارند و می‌توانند تحت یک حساب مخصوص به نام "Local System" اجرا شوند که دسترسی‌های وسیعی به منابع سیستم را فراهم می‌کند.

  5. کنترل و مدیریت از طریق ابزارهای خاص: مدیریت سرویس‌ها از طریق ابزارهایی مانند "Services.msc" در ویندوز انجام می‌شود. در این محیط، کاربران می‌توانند سرویس‌ها را مشاهده، راه‌اندازی، متوقف یا تنظیم کنند.


    سرویس‌ها بخش مهمی از سیستم عامل ویندوز هستند و به مدیریت و عملکرد پایدار سیستم کمک می‌کنند. فهمیدن نحوه کار سرویس‌ها می‌تواند در عیب‌یابی مشکلات و بهینه‌سازی عملکرد سیستم مفید باشد.


سرویس‌ها بخش مهمی از سیستم عامل ویندوز هستند و به مدیریت و عملکرد پایدار سیستم کمک می‌کنند. فهمیدن نحوه کار سرویس‌ها می‌تواند در عیب‌یابی مشکلات و بهینه‌سازی عملکرد سیستم مفید باشد.


توضیح کد:

SERVICE_STATUS_HANDLE g_ServiceStatus = NULL;

این خط یک متغیر سراسری به نام g_ServiceStatus از نوع SERVICE_STATUS_HANDLE تعریف می‌کند و آن را با NULL مقداردهی اولیه می‌کند.

  • SERVICE_STATUS_HANDLE: یک دستگیره (handle) است که سیستم‌عامل به سرویس شما اختصاص می‌دهد. این دستگیره برای ارتباط با مدیر کنترل سرویس (Service Control Manager - SCM) استفاده می‌شود، مثلاً برای گزارش وضعیت سرویس.

SERVICE_STATUS g_ServiceStatusInfo = { 0 };

این خط یک متغیر سراسری به نام g_ServiceStatusInfo از نوع SERVICE_STATUS تعریف می‌کند و تمام اعضای آن را با صفر مقداردهی اولیه می‌کند.

  • SERVICE_STATUS: یک ساختار است که حاوی اطلاعات مربوط به وضعیت فعلی یک سرویس است (مانند نوع سرویس، وضعیت فعلی، کدهای خطا و غیره).

VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);

این خط یک نمونه اولیه (prototype) برای تابع ServiceMain اعلام می‌کند.

  • VOID: نشان می‌دهد که تابع هیچ مقداری را برنمی‌گرداند.

  • WINAPI: یک قرارداد فراخوانی (calling convention) است که توسط مایکروسافت برای توابع API ویندوز استفاده می‌شود.

  • ServiceMain: این تابع نقطه ورود اصلی (main entry point) برای سرویس شماست. وقتی مدیر کنترل سرویس، سرویس شما را شروع می‌کند، این تابع را فراخوانی می‌کند.

  • DWORD argc: تعداد آرگومان‌های خط فرمان که به سرویس شما ارسال شده‌اند.

  • LPTSTR* argv: آرایه‌ای از رشته‌ها (آرگومان‌های خط فرمان) که به سرویس شما ارسال شده‌اند. LPTSTR نیز یک نوع کاراکتر عمومی است.

VOID WINAPI ServiceHandler(DWORD control);

این خط یک نمونه اولیه برای تابع ServiceHandler اعلام می‌کند.

  • ServiceHandler: این تابع یک کنترل‌کننده (handler) برای رویدادهای کنترلی است که توسط مدیر کنترل سرویس به سرویس شما ارسال می‌شود (مثلاً دستور توقف، مکث، ادامه و غیره).

  • DWORD control: کدی که نوع رویداد کنترلی را مشخص می‌کند.

int main()

این تابع، نقطه ورود اصلی برنامه اجرایی (EXE) شماست. این تابع مسئول ثبت سرویس با مدیر کنترل سرویس است.

SERVICE_TABLE_ENTRY ServiceTable[] = { ... };

این خط یک آرایه از ساختارهای SERVICE_TABLE_ENTRY تعریف می‌کند.

  • SERVICE_TABLE_ENTRY: ساختاری است که نام سرویس و اشاره‌گر به تابع ServiceMain مربوط به آن سرویس را نگهداری می‌کند.

  • { (LPWSTR)L"MyService", (LPSERVICE_MAIN_FUNCTION)ServiceMain }: اولین ورودی در جدول سرویس.

    • (LPWSTR)L"MyService": نام سرویس شماست. L نشان‌دهنده یک رشته پهن (wide string) است و LPWSTR یک اشاره‌گر به یک رشته پهن است.

    • (LPSERVICE_MAIN_FUNCTION)ServiceMain: اشاره‌گری به تابع ServiceMain که نقطه ورود سرویس "MyService" است.

  • { NULL, NULL }: این ورودی به عنوان نشانگر پایان جدول سرویس عمل می‌کند.

if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)

این خط تابع StartServiceCtrlDispatcher را فراخوانی می‌کند.

  • StartServiceCtrlDispatcher: این تابع برنامه را به عنوان یک فرآیند سرویس در مدیر کنترل سرویس ثبت می‌کند. این تابع منتظر می‌ماند تا مدیر کنترل سرویس یک سرویس را در این فرآیند شروع کند و سپس تابع ServiceMain مربوط به آن سرویس را فراخوانی می‌کند.

  • اگر این تابع FALSE برگرداند، به این معنی است که عملیات ناموفق بوده است (معمولاً به این معنی است که برنامه به عنوان یک سرویس شروع نشده است، بلکه به صورت یک برنامه معمولی اجرا شده است).

{ return GetLastError(); }

اگر StartServiceCtrlDispatcher ناموفق باشد، این بلوک اجرا می‌شود و کد خطای مربوطه را با استفاده از GetLastError() برمی‌گرداند.

return 0;

اگر StartServiceCtrlDispatcher با موفقیت برگردد، این خط 0 را برمی‌گرداند که نشان‌دهنده اجرای موفقیت‌آمیز برنامه است.

VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)

این تابع نقطه ورود اصلی سرویس شماست که توسط StartServiceCtrlDispatcher فراخوانی می‌شود، زمانی که مدیر کنترل سرویس تصمیم به شروع "MyService" می‌گیرد.

g_ServiceStatusInfo.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

این خط نوع سرویس را مشخص می‌کند.

  • SERVICE_WIN32_OWN_PROCESS: نشان می‌دهد که سرویس در فرآیند خود اجرا می‌شود (یعنی یک فرآیند جداگانه برای این سرویس ایجاد می‌شود).

g_ServiceStatusInfo.dwCurrentState = SERVICE_START_PENDING;

این خط وضعیت فعلی سرویس را به SERVICE_START_PENDING (در حال شروع) تنظیم می‌کند. این به مدیر کنترل سرویس اطلاع می‌دهد که سرویس در حال آماده‌سازی برای شروع است.

g_ServiceStatusInfo.dwControlsAccepted = SERVICE_ACCEPT_STOP;

این خط مشخص می‌کند که سرویس چه کنترل‌هایی را می‌پذیرد.

  • SERVICE_ACCEPT_STOP: به مدیر کنترل سرویس اطلاع می‌دهد که این سرویس دستور توقف را می‌پذیرد.

g_ServiceStatus = RegisterServiceCtrlHandler(_T("MyService"), ServiceHandler);

این خط تابع کنترل‌کننده سرویس (ServiceHandler) را با مدیر کنترل سرویس ثبت می‌کند.

  • RegisterServiceCtrlHandler: این تابع به مدیر کنترل سرویس اطلاع می‌دهد که تابع ServiceHandler مسئول رسیدگی به دستورات کنترلی برای "MyService" است.

  • _T("MyService"): نام سرویس (با استفاده از _T برای پشتیبانی از کاراکترهای عمومی).

  • ServiceHandler: اشاره‌گری به تابع کنترل‌کننده.

  • این تابع یک SERVICE_STATUS_HANDLE را برمی‌گرداند که در g_ServiceStatus ذخیره می‌شود.

if (g_ServiceStatus == NULL)

اگر ثبت کنترل‌کننده سرویس ناموفق باشد، g_ServiceStatus برابر با NULL خواهد بود.

{ return; }

اگر ثبت ناموفق باشد، تابع ServiceMain به سادگی برمی‌گردد.

g_ServiceStatusInfo.dwCurrentState = SERVICE_RUNNING;

این خط وضعیت سرویس را به SERVICE_RUNNING (در حال اجرا) تغییر می‌دهد. این به مدیر کنترل سرویس اطلاع می‌دهد که سرویس با موفقیت شروع شده است.

SetServiceStatus(g_ServiceStatus, &g_ServiceStatusInfo);

این تابع وضعیت فعلی سرویس را به مدیر کنترل سرویس گزارش می‌دهد.

  • g_ServiceStatus: دستگیره سرویس که قبلاً با RegisterServiceCtrlHandler به دست آمده است.

  • &g_ServiceStatusInfo: اشاره‌گری به ساختار SERVICE_STATUS که حاوی اطلاعات وضعیت جدید است.

while (g_ServiceStatusInfo.dwCurrentState == SERVICE_RUNNING)

این یک حلقه اصلی است که تا زمانی که وضعیت سرویس SERVICE_RUNNING باشد، اجرا می‌شود. این حلقه جایی است که کار اصلی سرویس شما انجام می‌شود.


این کد نمونه به زبان c++ هست:

#include <windows.h> #include <tchar.h> SERVICE_STATUS_HANDLE g_ServiceStatus = NULL; SERVICE_STATUS g_ServiceStatusInfo = { 0 }; VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv); VOID WINAPI ServiceHandler(DWORD control); int main() { SERVICE_TABLE_ENTRY ServiceTable[] = { { (LPWSTR)L"MyService", (LPSERVICE_MAIN_FUNCTION)ServiceMain }, { NULL, NULL } }; if (StartServiceCtrlDispatcher(ServiceTable) == FALSE) { return GetLastError(); } return 0; } VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv) { g_ServiceStatusInfo.dwServiceType = SERVICE_WIN32_OWN_PROCESS; g_ServiceStatusInfo.dwCurrentState = SERVICE_START_PENDING; g_ServiceStatusInfo.dwControlsAccepted = SERVICE_ACCEPT_STOP; g_ServiceStatus = RegisterServiceCtrlHandler(_T("MyService"), ServiceHandler); if (g_ServiceStatus == NULL) { return; } g_ServiceStatusInfo.dwCurrentState = SERVICE_RUNNING; SetServiceStatus(g_ServiceStatus, &g_ServiceStatusInfo); // سرویس شما در اینجا شروع می‌شود while (g_ServiceStatusInfo.dwCurrentState == SERVICE_RUNNING) { // کد سرویس Sleep(1000); // مثلاً یک توقف برای جلوگیری از استفاده زیاد از CPU } g_ServiceStatusInfo.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(g_ServiceStatus, &g_ServiceStatusInfo); } VOID WINAPI ServiceHandler(DWORD control) { switch (control) { case SERVICE_CONTROL_STOP: g_ServiceStatusInfo.dwCurrentState = SERVICE_STOP_PENDING; SetServiceStatus(g_ServiceStatus, &g_ServiceStatusInfo); g_ServiceStatusInfo.dwCurrentState = SERVICE_STOPPED; SetServiceStatus(g_ServiceStatus, &g_ServiceStatusInfo); break; default: break; } }

این کد را درون ویژوال استدیو کامپایل کنید.

برای نصب سرویس ویندوز، شما نیاز به استفاده از خط فرمان (Command Prompt) با دسترسی ادمین دارید. مراحل زیر را دنبال کنید:

  1. باز کردن Command Prompt با دسترسی ادمین:

    • کلید Windows را فشار دهید و "cmd" را جستجو کنید.

    • روی "Command Prompt" راست کلیک کرده و گزینه "Run as administrator" را انتخاب کنید.

  2. استفاده از دستور sc create:
    دستور زیر را وارد کنید (پوشه را با مسیر واقعی فایل exe خود که ساخته‌اید جایگزین کنید):

sc create MyService binPath= "C:\Users\MyWindows\source\repos\YourService\Release\YourService.exe"

توجه: دقت داشته باشید که پس از binPath= حتماً یک فاصله وجود داشته باشد.

برای شروع سرویس، از دستور زیر استفاده کنید:

sc start MyService

اگر بخواهید سرویس را متوقف کنید، می‌توانید دستور زیر را وارد کنید:

sc stop MyService

اگر بخواهید سرویس را از سیستم حذف کنید، از دستور زیر استفاده کنید:

sc delete MyService

Telegram: @CaKeegan
Gmail : amidgm2020@gmail.com

سیستم عامل
۳
۰
سید عمید قائم مقامی
سید عمید قائم مقامی
برنامه نویسی سیستم ویندوز و مهندسی معکوس و علاقه مند به آموزش.
شاید از این پست‌ها خوشتان بیاید