
Setelah Anda berpikir tentang cara mengubah skrip atau aplikasi menjadi layanan Windows. Kemungkinan besar, tugas itu tidak akan sepele - setidaknya aplikasi akan membutuhkan antarmuka khusus untuk menerima perintah dari sistem. Dan karena ada persyaratan dan batasan, yaitu skrip, dan kruk, yang menyenangkan hati, untuk diatasi.
Artikel ini akan bermanfaat bagi mereka yang, seperti saya, adalah "bukan programmer yang sebenarnya."
Mengapa saya memerlukan layanan jika ada tugas yang dijadwalkan
Berbeda dengan tugas yang ditugaskan, layanan berjalan terus-menerus, dimulai pada awal PC dan dapat dikontrol oleh alat Windows. Juga, skrip yang diluncurkan secara rutin mungkin memerlukan data dari peluncuran sebelumnya, dan mungkin bermanfaat untuk mendapatkan data dari sumber eksternal - misalnya, dalam kasus TCP atau server Web.
Secara pribadi, selama lima tahun terakhir saya harus membuat layanan tiga setengah kali:
- Itu diperlukan untuk membuat layanan pada fail2ban untuk Windows 2003. yang berfungsi dengan log FileZilla dan Apache, dan jika dicurigai brute force, ia memblokir IP menggunakan alat Windows biasa - ipsec.
- Analog server telnet untuk Windows versi rumah. Butuh untuk menjalankan perintah pada workstation jarak jauh yang menjalankan Windows 7 Home. Bahkan, upaya kedua untuk memainkan layanan.
- Pemutar musik untuk lantai perdagangan di bawah Windows. Tugas pada TK dapat diselesaikan dengan bantuan mpd dan sekumpulan skrip, tapi saya memutuskan - jika kita membuat skrip, lalu mengapa tidak "menumpuk" pemain itu sendiri. Berdasarkan perpustakaan BASS.dll .
- Ketika memilih server web dengan dukungan untuk mengunduh file di bawah Windows, satu opsi adalah HFS . Dia tidak bisa bekerja sendiri, jadi dia harus "mendorong" dia ke dalam layanan. Akibatnya, saya tidak suka solusinya, dan baru saja menginstal tema Apaxy di server web Apache.
Untuk membuat layanan, Anda dapat menggunakan bahasa pemrograman dewasa seperti C. Tetapi jika Anda tidak ingin menghubungi Visual Studio, maka ambil alat yang sudah jadi. Ada solusi berbayar seperti FireDaemon Pro atau AlwaysUp , tetapi kami secara tradisional akan fokus pada yang gratis.
Cara pertama. Dari Microsoft
Mekanisme yang sudah lama ini terdiri dari dua komponen: utilitas instsrv.exe untuk menginstal layanan dan srvany.exe , proses untuk meluncurkan file yang dapat dieksekusi. Misalkan kita membuat server Web pada PowerShell menggunakan modul Polaris . Scriptnya akan sangat sederhana:
New-PolarisGetRoute -Path '/helloworld' -Scriptblock { $Response.Send('Hello World!') } Start-Polaris -Port 8080 while($true) { Start-Sleep -Milliseconds 10 }

Karya yang disebut "server".
Sekarang mari kita coba mengubah skrip menjadi layanan. Untuk melakukan ini, unduh Windows Resource Kit Tools , di mana utilitas kami akan berada. Mari kita mulai dengan menginstal layanan kosong dengan perintah:
instsrv WebServ C:\temp\rktools\srvany.exe
Di mana WebServ adalah nama layanan baru kami. Jika perlu, melalui snap-in services.msc , Anda dapat menentukan pengguna di mana layanan akan diluncurkan dan memungkinkan interaksi dengan desktop.
Sekarang mari kita menulis path ke skrip kita menggunakan sihir registri. Parameter layanan ada di kunci registri HKLM \ SYSTEM \ CurrentControlSet \ Services \ WebServ . Di dalamnya, kita perlu menambahkan Parameter bagian baru dan membuat Aplikasi parameter string di sana, yang menunjukkan di dalamnya path ke file yang dapat dieksekusi. Dalam kasus skrip PowerShell, akan terlihat seperti ini:
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -File C:\temp\Polaris\server.ps1

Layanan yang disesuaikan.
Anda dapat berlari dan menikmati.

Layanan kerja.
Namun, metode ini memiliki kelemahan:
- Utilitas sudah tua, dikembangkan sebelum penemuan PowerShell, UAC dan hal-hal lainnya.
- Srvany tidak mengontrol operasi aplikasi. Bahkan jika itu jatuh ke dalam kesalahan, layanan akan melanjutkan pekerjaannya seolah-olah tidak ada yang terjadi.
- Harus menyesuaikan dan menggali ke dalam registri. Apakah Anda ingat bahwa menggali ke dalam registri tidak aman?
Oleh karena itu, kami beralih ke metode yang sebagian tanpa masalah ini.
Cara kedua, hampir dewasa
Ada utilitas bernama NSSM - Non-Sucking Service Manager , yang dapat diterjemahkan sebagai manajer layanan yang tidak buruk . Berbeda dengan yang sebelumnya, ini didukung oleh pengembang, dan kode sumber diterbitkan di situs. Selain metode yang biasa, instalasi juga tersedia melalui manajer paket Chocolately .
Anda dapat membuat layanan dari baris perintah yang biasa, dilengkapi dengan dokumentasi di situs pengembang. Tapi kami akan menggunakan PowerShell. Karena kita bisa, tentu saja.
$nssm = (Get-Command ./nssm).Source $serviceName = 'WebServ' $powershell = (Get-Command powershell).Source $scriptPath = 'C:\temp\Polaris\server.ps1' $arguments = '-ExecutionPolicy Bypass -NoProfile -File "{0}"' -f $scriptPath & $nssm install $serviceName $powershell $arguments & $nssm status $serviceName Start-Service $serviceName Get-Service $serviceName

Instalasi melalui PowerShell.
Untuk perubahan, kami akan memeriksa kerja layanan tidak dengan browser, tetapi juga melalui PowerShell menggunakan perintah Invoke-RestMethod.

Dan itu benar-benar berfungsi.
Tidak seperti srvany , metode ini memungkinkan Anda untuk me-restart aplikasi saat startup, mengarahkan ulang stdin dan stdout dan banyak lagi. Secara khusus, jika Anda tidak ingin menulis perintah pada baris perintah, maka jalankan saja GUI dan masukkan parameter yang diperlukan melalui antarmuka yang nyaman.
GUI dimulai dengan perintah:
nssm.exe install ServiceName

Anda bahkan dapat mengkonfigurasi prioritas dan penggunaan inti prosesor.
Memang, ada lebih banyak peluang daripada svvany dan sejumlah analog lainnya. Dari minus, kontrol yang tidak memadai atas seluruh proses mencolok.
Ada kekurangan timah. Oleh karena itu, saya akan beralih ke metode paling hardcore dari semua yang diuji.
Cara ketiga. AutoIT
Karena saya sudah lama menyukai bahasa scripting ini, saya tidak bisa melewati perpustakaan yang disebut _Services_UDF v4 . Ini dilengkapi dengan dokumentasi dan contoh yang kaya, jadi di bawah spoiler saya akan segera memberikan teks lengkap dari skrip yang dihasilkan.
Daftar skripJadi, mari kita coba "membungkus" layanan web kami ke dalamnya:
#NoTrayIcon #RequireAdmin #Region #AutoIt3Wrapper_Version=Beta #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_UseX64=y #EndRegion Dim $MainLog = @ScriptDir & "\test_service.log" #include <services.au3> #include <WindowsConstants.au3> $sServiceName="WebServ" If $cmdline[0] > 0 Then Switch $cmdline[1] Case "install", "-i", "/i" InstallService() Case "remove", "-u", "/u", "uninstall" RemoveService() Case Else ConsoleWrite(" - - - Help - - - " & @CRLF) ConsoleWrite("params : " & @CRLF) ConsoleWrite(" -i : install service" & @CRLF) ConsoleWrite(" -u : remove service" & @CRLF) ConsoleWrite(" - - - - - - - - " & @CRLF) Exit EndSwitch Else _Service_init($sServiceName) Exit EndIf Func _main($iArg, $sArgs) If Not _Service_ReportStatus($SERVICE_RUNNING, $NO_ERROR, 0) Then _Service_ReportStatus($SERVICE_STOPPED, _WinAPI_GetLastError(), 0) Exit EndIf $bServiceRunning = True $PID=Run("C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -ExecutionPolicy Bypass -NoProfile -File C:\temp\Polaris\server.ps1") While $bServiceRunning _sleep(1000) WEnd ProcessClose($PID) _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 1000) DllCallbackFree($tServiceMain) DllCallbackFree($tServiceCtrl) _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0) DllClose($hAdvapi32_DLL) DllClose($hKernel32_DLL) EndFunc Func _Sleep($delay) Local $result = DllCall($hKernel32_DLL, "none", "Sleep", "dword", $delay) EndFunc Func InstallService() #RequireAdmin Local $bDebug = True If $cmdline[0] > 1 Then $sServiceName = $cmdline[2] EndIf If $bDebug Then ConsoleWrite("InstallService("&$sServiceName &"): Installing service, please wait") _Service_Create($sServiceName, $sServiceName, $SERVICE_WIN32_OWN_PROCESS, $SERVICE_AUTO_START, $SERVICE_ERROR_SEVERE, '"' & @ScriptFullPath & '"');,"",False,"","NT AUTHORITY\NetworkService") If @error Then Msgbox("","","InstallService(): Problem installing service, Error number is " & @error & @CRLF & " message : " & _WinAPI_GetLastErrorMessage()) Else If $bDebug Then ConsoleWrite("InstallService(): Installation of service successful") EndIf Exit EndFunc Func RemoveService() _Service_Stop($sServiceName) _Service_Delete($sServiceName) If Not @error Then EndIf Exit EndFunc Func _exit() _Service_ReportStatus($SERVICE_STOPPED, $NO_ERROR, 0); EndFunc Func StopTimer() _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, $iServiceCounter) $iServiceCounter += -100 EndFunc Func _Stopping() _Service_ReportStatus($SERVICE_STOP_PENDING, $NO_ERROR, 3000) EndFunc
Saya akan menganalisis lebih detail saat aplikasi diluncurkan. Itu dimulai setelah operasi $ bServiceRunning = True dan berubah menjadi loop yang tampaknya tak terbatas. Bahkan, proses ini akan terganggu segera setelah layanan menerima sinyal penyelesaian - apakah itu keluar atau berhenti secara manual.
Karena program untuk skrip adalah eksternal (powershell.exe), maka setelah keluar dari loop kita harus menyelesaikan pekerjaannya menggunakan ProcessClose .
Untuk melakukan ini, skrip harus dikompilasi ke .exe , dan kemudian instal layanan dengan menjalankan exe dengan -i switch .

Itu berhasil!
Tentu saja, metode ini bukan yang paling nyaman, dan semua fitur tambahan harus diimplementasikan secara independen, apakah itu me-restart aplikasi jika terjadi kegagalan atau rotasi log. Tetapi dia memberikan kontrol penuh atas apa yang terjadi. Dan pada akhirnya, Anda dapat melakukan lebih banyak lagi - mulai dari memberi tahu Telegram tentang kegagalan layanan hingga interaksi IPC dengan program lain. Dan selain itu - dalam bahasa scripting, tanpa menginstal dan belajar Visual Studio.
Beri tahu kami, apakah Anda harus mengubah skrip dan aplikasi menjadi layanan?