Saya perlu menulis kode yang kuat di .NET untuk mengaktifkan layanan windows (server 2003) untuk memulai ulang sendiri. Apa cara terbaik untuk melakukannya? Apakah ada beberapa .NET API untuk melakukannya?
Saya perlu menulis kode yang kuat di .NET untuk mengaktifkan layanan windows (server 2003) untuk memulai ulang sendiri. Apa cara terbaik untuk melakukannya? Apakah ada beberapa .NET API untuk melakukannya?
Jawaban:
Atur layanan untuk memulai kembali setelah kegagalan (klik dua kali layanan di panel kontrol dan lihat-lihat tab tersebut - saya lupa namanya). Kemudian, kapan pun Anda ingin layanan dimulai ulang, cukup panggil Environment.Exit(1)
(atau pengembalian bukan nol) dan OS akan memulai ulang untuk Anda.
Service.ExitCode = 1
dan kemudian mengeksekusi Service.Stop()
bersama dengan mengaktifkan kotak centang 'Aktifkan tindakan untuk berhenti dengan kesalahan` pada layar pengaturan pemulihan layanan. Melakukannya dengan cara ini memungkinkan pematian yang benar dan masih memicu mulai ulang.
Dim proc As New Process()
Dim psi As New ProcessStartInfo()
psi.CreateNoWindow = True
psi.FileName = "cmd.exe"
psi.Arguments = "/C net stop YOURSERVICENAMEHERE && net start YOURSERVICENAMEHERE"
psi.LoadUserProfile = False
psi.UseShellExecute = False
psi.WindowStyle = ProcessWindowStyle.Hidden
proc.StartInfo = psi
proc.Start()
Anda tidak dapat memastikan bahwa akun pengguna yang menjalankan layanan Anda bahkan memiliki izin untuk menghentikan dan memulai ulang layanan.
Anda dapat membuat proses yang merupakan prompt perintah DOS yang dimulai ulang sendiri:
Process process = new Process();
process.StartInfo.FileName = "cmd";
process.StartInfo.Arguments = "/c net stop \"servicename\" & net start \"servicename\"";
process.Start();
const string strCmdText = "/C net stop \"SERVICENAME\"&net start \"SERVICENAME\"";
Process.Start("CMD.exe", strCmdText);
di mana SERVICENAME
nama layanan Anda (tanda kutip ganda disertakan untuk memperhitungkan spasi dalam nama layanan, jika tidak dapat dihilangkan).
Bersih, tidak perlu konfigurasi restart otomatis.
Itu akan tergantung pada mengapa Anda ingin me-restart sendiri.
Jika Anda hanya mencari cara agar layanan membersihkan dirinya sendiri secara berkala, maka Anda dapat memiliki pengatur waktu yang berjalan di layanan yang secara berkala menyebabkan rutinitas pembersihan.
Jika Anda mencari cara untuk memulai ulang saat gagal - host layanan itu sendiri dapat menyediakan kemampuan itu saat disiapkan.
Jadi mengapa Anda perlu me-restart server? Apa yang ingin Anda capai?
Saya rasa Anda tidak dapat melakukannya dalam layanan mandiri (saat Anda memanggil Restart, itu akan menghentikan layanan, yang akan mengganggu perintah Restart, dan tidak akan pernah memulai lagi). Jika Anda dapat menambahkan .exe kedua (aplikasi Konsol yang menggunakan kelas ServiceManager), Anda dapat memulai .exe mandiri dan memintanya memulai ulang layanan, lalu keluar.
Setelah dipikir-pikir, Anda mungkin bisa meminta layanan mendaftarkan Tugas Terjadwal (menggunakan perintah baris perintah 'at', misalnya) untuk memulai layanan dan kemudian menghentikannya sendiri; itu mungkin akan berhasil.
Masalah dengan mengupas ke file batch atau EXE adalah bahwa layanan mungkin memiliki atau tidak memiliki izin yang diperlukan untuk menjalankan aplikasi eksternal.
Cara terbersih untuk melakukan ini yang saya temukan adalah dengan menggunakan metode OnStop (), yang merupakan titik masuk untuk Service Control Manager. Kemudian semua kode pembersihan Anda akan berjalan, dan Anda tidak akan memiliki soket gantung atau proses lain, dengan asumsi kode penghentian Anda melakukan tugasnya.
Untuk melakukan ini, Anda perlu menyetel bendera sebelum Anda mengakhiri yang memberi tahu metode OnStop untuk keluar dengan kode kesalahan; maka SCM mengetahui bahwa layanan perlu direstart. Tanpa tanda ini, Anda tidak akan dapat menghentikan layanan secara manual dari SCM. Ini juga mengasumsikan Anda telah menyiapkan layanan untuk memulai ulang saat terjadi kesalahan.
Ini kode stop saya:
...
bool ABORT;
protected override void OnStop()
{
Logger.log("Stopping service");
WorkThreadRun = false;
WorkThread.Join();
Logger.stop();
// if there was a problem, set an exit error code
// so the service manager will restart this
if(ABORT)Environment.Exit(1);
}
Jika layanan mengalami masalah dan perlu dimulai ulang, saya meluncurkan utas yang menghentikan layanan dari SCM. Ini memungkinkan layanan untuk membersihkan dirinya sendiri:
...
if(NeedToRestart)
{
ABORT = true;
new Thread(RestartThread).Start();
}
void RestartThread()
{
ServiceController sc = new ServiceController(ServiceName);
try
{
sc.Stop();
}
catch (Exception) { }
}
Saya akan menggunakan Penjadwal Windows untuk menjadwalkan restart layanan Anda. Masalahnya adalah Anda tidak dapat memulai ulang diri sendiri, tetapi Anda dapat menghentikan diri sendiri. (Anda pada dasarnya telah memotong cabang yang Anda duduki ... jika Anda mendapatkan analogi saya) Anda memerlukan proses terpisah untuk melakukannya untuk Anda. Penjadwal Windows adalah salah satu yang sesuai. Jadwalkan tugas satu kali untuk memulai ulang layanan Anda (bahkan dari dalam layanan itu sendiri) agar segera dijalankan.
Jika tidak, Anda harus membuat proses "penggembalaan" yang melakukannya untuk Anda.
Tanggapan pertama untuk pertanyaan tersebut adalah solusi paling sederhana: "Environment.Exit (1)" Saya menggunakan ini di Windows Server 2008 R2 dan bekerja dengan sempurna. Layanan berhenti sendiri, O / S menunggu 1 menit, lalu memulai ulang.
Pendekatan yang lebih baik mungkin dengan memanfaatkan Layanan NT sebagai pembungkus untuk aplikasi Anda. Ketika Layanan NT dimulai, aplikasi Anda bisa mulai dalam mode "diam" menunggu perintah untuk memulai (atau dikonfigurasi untuk memulai secara otomatis).
Bayangkan sebuah mobil, ketika dihidupkan dimulai dalam keadaan diam, menunggu perintah Anda untuk maju atau mundur. Hal ini juga memungkinkan keuntungan lainnya, seperti administrasi jarak jauh yang lebih baik karena Anda dapat memilih cara mengekspos aplikasi Anda.
Hanya lewat: dan berpikir saya akan menambahkan beberapa info tambahan ...
Anda juga dapat memberikan pengecualian, ini akan menutup layanan windows secara otomatis, dan opsi re-start otomatis baru saja muncul. Satu-satunya masalah dengan ini adalah bahwa jika Anda memiliki lingkungan pengembang pada pc Anda maka JIT mencoba untuk masuk, dan Anda akan mendapatkan prompt yang mengatakan debug Y / N. katakan tidak, lalu tutup, lalu mulai ulang dengan benar. (pada PC tanpa JIT, semuanya berfungsi). alasan im trolling, apakah JIT ini baru untuk Win 7 (dulu berfungsi dengan baik dengan XP dll) dan saya mencoba menemukan cara untuk menonaktifkan JIT .... saya dapat mencoba metode Environment.Exit yang disebutkan di sini lihat caranya itu juga berhasil.
Kristian: Bristol, Inggris
Buat file restart.bat seperti ini
@echo on
set once="C:\Program Files\MyService\once.bat"
set taskname=Restart_MyService
set service=MyService
echo rem %time% >%once%
echo net stop %service% >>%once%
echo net start %service% >>%once%
echo del %once% >>%once%
schtasks /create /ru "System" /tn %taskname% /tr '%once%' /sc onstart /F /V1 /Z
schtasks /run /tn %taskname%
Kemudian hapus tugas% taskname% saat% service% Anda dimulai
Buat appdomain terpisah untuk menghosting kode aplikasi. Ketika membutuhkan restart, kita dapat membongkar dan memuat ulang appdomain sebagai gantinya (layanan windows). Ini adalah cara kerja pool aplikasi IIS, mereka tidak menjalankan aplikasi asp.net secara langsung, mereka menggunakan appdmain terpisah.
Cara termudah adalah memiliki file batch dengan:
bersih berhenti bersih mulai
dan tambahkan file ke penjadwal dengan interval waktu yang Anda inginkan
private static void RestartService(string serviceName)
{
using (var controller = new ServiceController(serviceName))
{
controller.Stop();
int counter = 0;
while (controller.Status != ServiceControllerStatus.Stopped)
{
Thread.Sleep(100);
controller.Refresh();
counter++;
if (counter > 1000)
{
throw new System.TimeoutException(string.Format("Could not stop service: {0}", Constants.Series6Service.WindowsServiceName));
}
}
controller.Start();
}
}