Kendisini yeniden başlatmak için bir Windows hizmeti (sunucu 2003) etkinleştirmek için .NET sağlam bir kod yazmak gerekiyor. Bunu yapmanın en iyi yolu nedir? Bunu yapmak için bazı .NET API var mı?
Kendisini yeniden başlatmak için bir Windows hizmeti (sunucu 2003) etkinleştirmek için .NET sağlam bir kod yazmak gerekiyor. Bunu yapmanın en iyi yolu nedir? Bunu yapmak için bazı .NET API var mı?
Yanıtlar:
Başarısızlıktan sonra hizmeti yeniden başlatacak şekilde ayarlayın (kontrol panelinde hizmeti çift tıklatın ve bu sekmelere bir göz atın - adını unuttum). Ardından, hizmetin yeniden başlatılmasını istediğinizde, sadece arayın Environment.Exit(1)
(veya sıfır olmayan herhangi bir dönüş) ve işletim sistemi sizin için yeniden başlatacaktır.
Service.ExitCode = 1
ve sonra çalıştırabilirsiniz Service.Stop()
. Bu şekilde yapılması uygun bir kapanmaya izin verir ve yine de yeniden başlatmayı tetikler.
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()
Hizmetinizin altında çalıştığı kullanıcı hesabının, hizmeti durdurma ve yeniden başlatma izinlerine sahip olduğundan bile emin olamazsınız.
Kendinizi yeniden başlatan bir DOS komut istemi olan bir işlem oluşturabilirsiniz:
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);
nerede SERVICENAME
hizmetinizin adıdır (hizmet adındaki boşlukları hesaba katmak için çift tırnak işareti kullanılır, aksi takdirde atlanabilir).
Temiz, otomatik yeniden başlatma yapılandırması gerekmez.
Neden kendini yeniden başlatmasını istediğinize bağlı olacaktır.
Hizmetin periyodik olarak kendini temizlemesinin bir yolunu arıyorsanız, periyodik olarak bir temizleme rutinine neden olan hizmette çalışan bir zamanlayıcı olabilir.
Hata durumunda yeniden başlatmanın bir yolunu arıyorsanız - servis ana bilgisayarı kurulum sırasında bu yeteneği sağlayabilir.
Peki neden sunucuyu yeniden başlatmanız gerekiyor? Ne elde etmeye çalışıyorsunuz?
Kendi kendine yeten bir hizmette yapabileceğinizi sanmıyorum (Yeniden Başlat'ı çağırdığınızda, Yeniden Başlat komutunu kesecek hizmeti durduracak ve bir daha başlatılmayacaktır). İkinci bir .exe (ServiceManager sınıfını kullanan bir Konsol uygulaması) ekleyebiliyorsanız, bağımsız .exe dosyasını başlatarak hizmeti yeniden başlatmasını ve sonra çıkmasını sağlayabilirsiniz.
İkinci düşüncede, muhtemelen hizmeti başlatmak için bir Zamanlanmış Görev kaydettirebilirsiniz (örneğin, 'at' komutunu kullanarak) ve sonra kendi kendine durmasını sağlayabilirsiniz; muhtemelen işe yarar.
Bir toplu iş dosyasına veya EXE'e bombardıman sorunu, bir hizmetin harici uygulamayı çalıştırmak için gerekli izinlere sahip olabileceği veya olmayabilir.
Bulduğum bunu yapmanın en temiz yolu, Hizmet Denetim Yöneticisi'nin giriş noktası olan OnStop () yöntemini kullanmaktır. Ardından, tüm temizleme kodunuz çalışır ve durma kodunuzun işini yaptığını varsayarak, herhangi bir asılı sokete veya başka işleme sahip olmazsınız.
Bunu yapmak için, OnStop yöntemine bir hata kodu ile çıkmasını söyleyen sonlandırmadan önce bir bayrak ayarlamanız gerekir; SCM, hizmetin yeniden başlatılması gerektiğini bilir. Bu bayrak olmadan hizmeti SCM'den manuel olarak durduramazsınız. Bu, hizmeti bir hatayla yeniden başlayacak şekilde ayarladığınızı varsayar.
İşte benim durdurma kodu:
...
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);
}
Hizmet bir sorunla karşılaşırsa ve yeniden başlatılması gerekirse, hizmeti SCM'den durduran bir iş parçacığı başlatırım. Bu, hizmetin kendisinden sonra temizlenmesini sağlar:
...
if(NeedToRestart)
{
ABORT = true;
new Thread(RestartThread).Start();
}
void RestartThread()
{
ServiceController sc = new ServiceController(ServiceName);
try
{
sc.Stop();
}
catch (Exception) { }
}
Hizmetinizin yeniden başlatılmasını zamanlamak için Windows Zamanlayıcı'yı kullanırdım. Sorun şu ki, kendinizi yeniden başlatamazsınız, ancak kendinizi durdurabilirsiniz. (Esasen, oturduğunuz şubeyi gördünüz ... benzetimimi alırsanız) Bunu sizin için yapmak için ayrı bir işleme ihtiyacınız var. Windows Zamanlayıcı uygun bir programdır. Hemen yürütmek için hizmetinizi (hizmetin içinden bile olsa) yeniden başlatmak üzere bir kerelik bir görev zamanlayın.
Aksi takdirde, bunu sizin için yapan bir "çobanlık" işlemi oluşturmanız gerekir.
Soruna ilk yanıt en basit çözümdür: "Environment.Exit (1)" Bunu Windows Server 2008 R2 üzerinde kullanıyorum ve mükemmel çalışıyor. Hizmet kendini durdurur, O / S 1 dakika bekler, sonra yeniden başlatır.
Daha iyi bir yaklaşım, NT Service'i uygulamanız için bir sarıcı olarak kullanmak olabilir. NT Hizmeti başlatıldığında, uygulamanız komutun başlamasını bekleyen (veya otomatik olarak başlayacak şekilde yapılandırılmış) bir "boşta" modunda başlayabilir.
Bir araba düşünün, çalıştırıldığında boşta başlar, komutunuzun ileri veya geri gitmesini bekler. Bu, uygulamanızı nasıl açığa çıkaracağınızı seçebileceğinizden daha iyi uzaktan yönetim gibi diğer avantajlara da izin verir.
Sadece geçen: ve bazı ekstra bilgi eklemek düşündüm ...
Ayrıca bir istisna atabilirsiniz, bu otomatik olarak Windows hizmetini kapatacak ve otomatik yeniden başlatma seçenekleri sadece tekme. Bu konuda tek sorun, PC'nizde bir dev çevreniz varsa, o zaman JIT tekmelemeye çalışır, ve hata ayıklama Y / N diyerek bir uyarı alırsınız. hayır deyin ve sonra kapanacak ve düzgün bir şekilde yeniden başlayacaktır. (JIT olmayan bir bilgisayarda sadece hepsi çalışır). neden im trolling, bu JIT Win 7 (XP ile iyi çalışmak için kullanılan) yeni ve ben JIT devre dışı bırakmanın bir yolunu bulmaya çalışırken yeni .... ben burada belirtilen Environment.Exit yöntemi deneyebilirsiniz bu da işe yarıyor.
Kristian: Bristol, İngiltere
Bunun gibi bir restart.bat dosyası oluşturun
@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%
Ardından% service% hizmetiniz başladığında% taskname% görevini silin
Uygulama kodunu barındırmak için ayrı bir uygulama alanı oluşturun. Yeniden başlatma gerektiğinde, işlem yerine uygulama alanını kaldırabilir ve yeniden yükleyebiliriz (Windows hizmeti). IIS uygulama havuzu bu şekilde çalışır, asp.net uygulamasını doğrudan çalıştırmazlar, ayrı uygulama alanı kullanırlar.
En kolay yol, bir toplu iş dosyasına sahip olmaktır:
net stop net başlatma
ve dosyayı istediğiniz zaman aralığıyla zamanlayıcıya ekleyin
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();
}
}