Apakah ada cara yang lebih mudah untuk melangkah melalui kode daripada memulai layanan melalui Windows Service Control Manager dan kemudian melampirkan debugger ke utas? Agak rumit dan saya bertanya-tanya apakah ada pendekatan yang lebih langsung.
c#
debugging
windows-services
Matthias
sumber
sumber
Jawaban:
Jika saya ingin dengan cepat men-debug layanan, saya hanya masuk
Debugger.Break()
di sana. Ketika garis itu tercapai, itu akan menurunkan saya kembali ke VS. Jangan lupa untuk menghapus garis itu ketika Anda selesai.UPDATE: Sebagai alternatif untuk
#if DEBUG
pragma, Anda juga dapat menggunakanConditional("DEBUG_SERVICE")
atribut.Pada Anda
OnStart
, panggil saja metode ini:Di sana, kode hanya akan diaktifkan selama pembuatan Debug. Sementara Anda melakukannya, mungkin berguna untuk membuat Konfigurasi Bangun terpisah untuk debugging layanan.
sumber
Saya juga berpikir memiliki "versi" terpisah untuk eksekusi normal dan sebagai layanan adalah cara untuk pergi, tetapi apakah itu benar-benar diperlukan untuk mendedikasikan saklar baris perintah terpisah untuk tujuan itu?
Tidak bisakah Anda melakukannya:
Itu akan memiliki "manfaat", bahwa Anda hanya dapat memulai aplikasi Anda melalui klik dua kali (OK, jika Anda benar-benar membutuhkannya) dan Anda dapat menekan F5di Visual Studio (tanpa perlu mengubah pengaturan proyek untuk memasukkan
/console
Opsi itu).Secara teknis,
Environment.UserInteractive
pemeriksaan jikaWSF_VISIBLE
Bendera diatur untuk stasiun jendela saat ini, tetapi apakah ada alasan lain di mana ia akan kembalifalse
, selain dijalankan sebagai layanan (non-interaktif)?sumber
System.Diagnostics.Debugger.IsAttached
bukanEnvironment.UserInteractive
.Ketika saya membuat proyek layanan baru beberapa minggu yang lalu saya menemukan posting ini. Meskipun ada banyak saran bagus, saya masih tidak menemukan solusi yang saya inginkan: Kemungkinan untuk memanggil kelas layanan
OnStart
danOnStop
metode tanpa modifikasi ke kelas layanan.Solusi yang saya buat menggunakan
Environment.Interactive
mode pilih berjalan, seperti yang disarankan oleh jawaban lain untuk posting ini.The
RunInteractive
helper menggunakan refleksi untuk memanggil dilindungiOnStart
danOnStop
metode:Ini semua kode yang diperlukan, tetapi saya juga menulis panduan dengan penjelasan.
sumber
walk through
) adalah untuk memastikan Anda masuk ke properti proyek dan mengubah tipe outputConsole Application
sebelum Anda mencoba untuk mengkompilasi dan menjalankan. Menemukannya diProject Properties -> Application -> Output type -> Console Application
. Juga, agar ini berfungsi dengan baik untuk saya, saya akhirnya harus menjalankan aplikasi menggunakanstart
perintah. Mis:C:\"my app name.exe" -service
tidak akan bekerja untuk saya. Sebagai gantinya saya menggunakanC:\start /wait "" "my app name.exe" -service
Terkadang penting untuk menganalisis apa yang terjadi selama dimulainya layanan. Melampirkan ke proses tidak membantu di sini, karena Anda tidak cukup cepat untuk melampirkan debugger saat layanan dimulai.
Jawaban singkatnya adalah, saya menggunakan 4 baris kode berikut untuk melakukan ini:
Ini dimasukkan ke dalam
OnStart
metode layanan sebagai berikut:Bagi mereka yang belum pernah melakukannya, saya telah memasukkan petunjuk rinci di bawah ini , karena Anda dapat dengan mudah terjebak. Petunjuk berikut merujuk ke Windows 7x64 dan Visual Studio 2010 Team Edition , tetapi juga berlaku untuk lingkungan lain.
Penting: Menyebarkan layanan dalam mode "manual" (menggunakan
InstallUtil
utilitas dari command prompt VS atau menjalankan proyek installer layanan yang telah Anda siapkan). Buka Visual Studio sebelum Anda memulai layanan dan memuat solusi yang berisi kode sumber layanan - mengatur breakpoint tambahan seperti yang Anda butuhkan di Visual Studio - kemudian mulai layanan melalui Panel Kontrol Layanan.Karena
Debugger.Launch
kode, ini akan menyebabkan dialog "Pengecualian Microsoft .NET Framework tidak tertangani terjadi di Servicename.exe ." muncul. Klik seperti yang ditunjukkan pada tangkapan layar: Yes, debug Servicename.exeSetelah itu, khususnya di Windows 7 UAC mungkin meminta Anda untuk memasukkan kredensial admin. Masukkan mereka dan melanjutkan dengan Yes:
Setelah itu, jendela Debugger Visual Studio Just-In-Time yang terkenal muncul. Ia bertanya apakah Anda ingin men-debug menggunakan debugger yang dihapus. Sebelum Anda mengklik Yes, pilih bahwa Anda tidak ingin membuka instance baru (opsi ke-2) - instance baru tidak akan membantu di sini, karena kode sumber tidak akan ditampilkan. Jadi Anda memilih contoh Visual Studio yang telah Anda buka sebelumnya sebagai gantinya:
Setelah Anda mengklik Yes, setelah beberapa saat Visual Studio akan menunjukkan panah kuning tepat di baris di mana
Debugger.Launch
pernyataan itu dan Anda dapat men-debug kode Anda (metodeMyInitOnStart
, yang berisi inisialisasi Anda).Menekan F5melanjutkan eksekusi segera, hingga breakpoint berikutnya yang Anda siapkan tercapai.
Petunjuk: Agar layanan tetap berjalan, pilih Debug -> Lepaskan semua . Ini memungkinkan Anda menjalankan klien yang berkomunikasi dengan layanan setelah layanan dimulai dengan benar dan Anda selesai men-debug kode startup. Jika Anda menekan Shift+F5 (menghentikan debugging), ini akan menghentikan layanan. Alih-alih melakukan ini, Anda harus menggunakan Panel Kontrol Layanan untuk menghentikannya.
Catat itu
Jika Anda membuat Rilis, maka kode debug dihapus secara otomatis dan layanan berjalan secara normal.
Saya menggunakan
Debugger.Launch()
, yang memulai dan melampirkan debugger . Saya telah mengujiDebugger.Break()
juga, yang tidak berhasil , karena belum ada debugger yang terpasang saat memulai layanan (menyebabkan "Kesalahan 1067: Proses dihentikan tiba-tiba." ).RequestAdditionalTime
menetapkan batas waktu lebih lama untuk memulai layanan (itu bukan menunda kode itu sendiri, tetapi akan segera melanjutkan denganDebugger.Launch
pernyataan). Kalau tidak, batas waktu default untuk memulai layanan terlalu pendek dan memulai layanan gagal jika Anda tidakbase.Onstart(args)
cukup cepat menelepon dari debugger. Praktis, batas waktu 10 menit menghindari Anda melihat pesan " layanan tidak merespons ..." segera setelah debugger dimulai.Setelah Anda terbiasa, metode ini sangat mudah karena hanya mengharuskan Anda untuk menambahkan 4 baris ke kode layanan yang ada, yang memungkinkan Anda dengan cepat mendapatkan kontrol dan debug.
sumber
base.RequestAdditionalTime(600000)
akan mencegah kontrol layanan menghentikan layanan selama 10 menit jika tidak memanggilbase.OnStart(args)
dalam rentang waktu tersebut). Terlepas dari itu, saya ingat bahwa UAC juga akan dibatalkan jika Anda tidak memasukkan kredensial admin setelah beberapa saat (saya tidak tahu berapa detik tepatnya, tetapi saya pikir Anda harus memasukkannya dalam satu menit, kalau tidak, UAC dibatalkan) , yang akan mengakhiri sesi debug.Apa yang biasanya saya lakukan adalah merangkum logika layanan dalam kelas yang terpisah dan memulainya dari kelas 'pelari'. Kelas pelari ini dapat berupa layanan aktual atau hanya aplikasi konsol. Jadi solusi Anda memiliki (minimal) 3 proyek:
sumber
Video YouTube ini oleh Fabio Scopel menjelaskan cara men-debug layanan Windows dengan cukup baik ... metode sebenarnya untuk melakukannya dimulai pada 4:45 dalam video ...
Berikut adalah kode yang dijelaskan dalam video ... di file Program.cs Anda, tambahkan hal-hal untuk bagian Debug ...
Di file Service1.cs Anda, tambahkan metode OnDebug () ...
Pada dasarnya Anda harus membuat
public void OnDebug()
panggilanOnStart(string[] args)
yang dilindungi dan tidak dapat diakses di luar. Thevoid Main()
Program ditambahkan dengan#if
preprocessor dengan#DEBUG
.Visual Studio mendefinisikan
DEBUG
jika proyek dikompilasi dalam mode Debug. Ini akan memungkinkan bagian debug (di bawah) untuk mengeksekusi ketika kondisinya benarDan itu akan berjalan seperti aplikasi konsol, setelah semuanya berjalan baik Anda dapat mengubah mode
Release
dan bagian regulerelse
akan memicu logikasumber
MEMPERBARUI
Sejauh ini pendekatan ini paling mudah:
http://www.codeproject.com/KB/dotnet/DebugWinServices.aspx
Saya meninggalkan jawaban asli saya di bawah untuk keturunan.
Layanan saya cenderung memiliki kelas yang merangkum Timer karena saya ingin layanan memeriksa secara berkala apakah ada pekerjaan yang harus dilakukan.
Kami baru kelas dan panggilan StartEventLoop () selama layanan start-up. (Kelas ini dapat dengan mudah digunakan dari aplikasi konsol juga.)
Efek samping yang bagus dari desain ini adalah bahwa argumen yang Anda gunakan untuk mengatur Timer dapat digunakan untuk menunda sebelum layanan benar-benar mulai bekerja, sehingga Anda punya waktu untuk melampirkan debugger secara manual.
Saya juga biasa melakukan hal berikut (sudah disebutkan dalam jawaban sebelumnya tetapi dengan flag [#if] kompilator bersyarat untuk membantu menghindarinya dari rilis Release build).
Saya berhenti melakukannya dengan cara ini karena kadang-kadang kita akan lupa untuk membangun di Release dan memiliki istirahat debugger dalam aplikasi yang berjalan pada demo klien (memalukan!).
sumber
// do something
dibutuhkan lebih dari 30 menit untuk menyelesaikan?sumber
OnStart
adalahprotected
dan Anda tidak dapat mengubah tingkat akses :(Anda juga dapat memulai layanan melalui command prompt (sc.exe).
Secara pribadi, saya menjalankan kode sebagai program yang berdiri sendiri dalam fase debugging, dan ketika sebagian besar bug disetrika, ubah untuk menjalankan sebagai layanan.
sumber
Apa yang saya lakukan adalah memiliki saklar baris perintah yang akan memulai program baik sebagai layanan atau sebagai aplikasi biasa. Kemudian, dalam IDE saya, saya akan mengatur sakelar sehingga saya bisa melangkah melalui kode saya.
Dengan beberapa bahasa Anda benar-benar dapat mendeteksi jika itu berjalan dalam IDE, dan melakukan pergantian ini secara otomatis.
Bahasa apa yang Anda gunakan?
sumber
Gunakan perpustakaan TopShelf .
Buat aplikasi konsol lalu konfigurasikan pengaturan di Main Anda
Untuk men-debug layanan Anda, cukup tekan F5 di studio visual.
Untuk menginstal layanan, ketik cmd "install console.exe"
Anda kemudian dapat memulai dan menghentikan layanan di manajer layanan windows.
sumber
Saya pikir itu tergantung pada OS apa yang Anda gunakan, Vista jauh lebih sulit untuk dilampirkan ke Layanan, karena pemisahan antara sesi.
Dua opsi yang saya gunakan di masa lalu adalah:
Semoga ini membantu.
sumber
Saya ingin dapat men-debug setiap aspek layanan saya, termasuk inisialisasi apa pun di OnStart (), sementara masih menjalankannya dengan perilaku layanan penuh dalam kerangka SCM ... tidak ada mode "konsol" atau "aplikasi".
Saya melakukan ini dengan membuat layanan kedua, dalam proyek yang sama, untuk digunakan untuk debugging. Layanan debug, ketika dimulai seperti biasa (yaitu dalam plugin layanan MMC), menciptakan proses host layanan. Ini memberi Anda proses untuk melampirkan debugger ke meskipun Anda belum memulai layanan nyata Anda. Setelah melampirkan debugger ke proses, mulai layanan nyata Anda dan Anda dapat membobolnya di mana saja dalam siklus hidup layanan, termasuk OnStart ().
Karena memerlukan intrusi kode yang sangat minimal, layanan debug dapat dengan mudah dimasukkan dalam proyek pengaturan layanan Anda, dan mudah dihapus dari rilis produksi Anda dengan mengomentari satu baris kode dan menghapus satu proyek installer.
Detail:
1) Dengan asumsi Anda menerapkan
MyService
, juga buatMyServiceDebug
. Tambahkan keduanya ke dalamServiceBase
arrayProgram.cs
seperti ini:2) Tambahkan layanan nyata DAN layanan debug ke penginstal proyek untuk proyek layanan:
Kedua layanan (nyata dan debug) dimasukkan ketika Anda menambahkan output proyek layanan ke proyek pengaturan untuk layanan. Setelah instalasi, kedua layanan akan muncul di plugin MMC service.msc.
3) Mulai layanan debug di MMC.
4) Di Visual Studio, lampirkan debugger ke proses yang dimulai oleh layanan debug.
5) Mulai layanan nyata dan nikmati debugging.
sumber
Ketika saya menulis layanan, saya meletakkan semua logika layanan di proyek dll dan membuat dua "host" yang memanggil ke dll ini, satu adalah layanan Windows dan yang lainnya adalah aplikasi baris perintah.
Saya menggunakan aplikasi baris perintah untuk debugging dan melampirkan debugger ke layanan nyata hanya untuk bug saya tidak dapat mereproduksi dalam aplikasi baris perintah.
Saya menggunakan pendekatan ini hanya ingat bahwa Anda harus menguji semua kode saat menjalankan dalam layanan nyata, sedangkan alat baris perintah adalah bantuan debugging bagus itu lingkungan yang berbeda dan tidak berperilaku persis seperti layanan nyata.
sumber
Ketika mengembangkan dan men-debug layanan Windows, saya biasanya menjalankannya sebagai aplikasi konsol dengan menambahkan parameter startup / konsol dan memeriksa ini. Membuat hidup lebih mudah.
sumber
Bagaimana dengan Debugger.Break () di baris pertama?
sumber
Untuk men-debug Layanan Windows saya menggabungkan GFlags dan file .reg yang dibuat oleh regedit.
Atau simpan cuplikan berikut dan ganti servicename.exe dengan nama yang dapat dieksekusi yang diinginkan.
debugon.reg:
debugoff.reg:
sumber
Untuk pemrograman hal-hal kecil yang rutin, saya telah melakukan trik yang sangat sederhana untuk dengan mudah men-debug layanan saya:
Pada awal layanan, saya memeriksa parameter baris perintah "/ debug". Jika layanan dipanggil dengan parameter ini, saya tidak melakukan startup layanan biasa, tetapi memulai semua pendengar dan hanya menampilkan kotak pesan "Debug dalam proses, tekan ok untuk mengakhiri".
Jadi jika layanan saya dimulai dengan cara biasa, itu akan mulai sebagai layanan, jika dimulai dengan parameter baris perintah / debug itu akan bertindak seperti program normal.
Dalam VS saya hanya akan menambahkan / debug sebagai parameter debugging dan memulai program layanan secara langsung.
Dengan cara ini saya dapat dengan mudah melakukan debug untuk sebagian besar masalah kecil. Tentu saja, beberapa hal masih perlu didebug sebagai layanan, tetapi untuk 99% ini cukup baik.
sumber
sumber
Saya menggunakan variasi pada jawaban JOP. Menggunakan parameter baris perintah Anda dapat mengatur mode debugging di IDE dengan properti proyek atau melalui manajer layanan Windows.
sumber
Untuk pemecahan masalah pada program Layanan Windows yang ada, gunakan 'Debugger.Break ()' seperti yang disarankan orang lain.
Untuk program Layanan Windows baru, saya akan menyarankan menggunakan metode James Michael Hare http://geekswithblogs.net/BlackRabbitCoder/archive/2011/03/01/c-toolbox-debug-able-self-installable-windows-service-template- redux.aspx
sumber
Cukup letakkan makan siang debugger Anda di mana saja dan lampirkan Visualstudio pada startup
Anda juga perlu memulai VS sebagai Administrator dan Anda harus mengizinkan, bahwa suatu proses dapat secara otomatis di-debug oleh pengguna lain (seperti dijelaskan di sini ):
sumber
Gunakan proyek C # Template Layanan Windows untuk membuat aplikasi layanan baru https://github.com/HarpyWar/windows-service-template
Ada mode konsol / layanan yang terdeteksi secara otomatis, installer / deinstaller otomatis dari layanan Anda dan beberapa fitur yang paling sering digunakan.
sumber
Berikut adalah metode sederhana yang saya gunakan untuk menguji layanan, tanpa metode "Debug" tambahan dan dengan Tes Unit VS terintegrasi.
sumber
sumber
Anda memiliki dua opsi untuk melakukan debugging.
Silahkan lihat INI posting blog yang saya buat untuk topik.
sumber
Cukup tempel
dimanapun dalam kode Anda.
Sebagai contoh ,
Ini akan memukul
Debugger.Break();
ketika Anda menjalankan program Anda.sumber
Pilihan terbaik adalah menggunakan namespace ' System.Diagnostics '.
Lampirkan kode Anda jika ada yang memblokir mode debug dan mode rilis seperti yang ditunjukkan di bawah ini untuk beralih antara mode debug dan rilis di studio visual,
sumber