Saat membuat layanan dengan sc.exe bagaimana cara mengirimkan parameter konteks?

143

Saat membuat layanan Windows menggunakan:

sc create ServiceName binPath= "the path"

bagaimana argumen dapat diteruskan ke koleksi Context.Parameters kelas Installer?

Bacaan sc.exedokumentasi saya adalah bahwa argumen seperti itu hanya dapat diajukan pada akhir binPath, tetapi saya belum menemukan contoh atau berhasil melakukan ini.

simpatrik greg
sumber
Pandangan sekilas pada kunci Layanan di Registry menunjukkan bahwa setiap parameter yang diperlukan disertakan dengan nilai ImagePath, sehingga Anda binPath= "c:\abc\def.exe /Param1=ghi"sepertinya ide yang tepat. Apakah garis miring terbalik perlu diloloskan (yaitu "c: \\ abc \\ ...")? Hal terburuk, Anda bisa langsung mengedit nilai Registry setelahnya jika SC.EXE tidak bisa melakukannya.
ewall
1
Saya menyerah pada sc.exe dan saya menggunakan installutil.exe seperti: Installutil.exe / ServiceName = "TheName" / targetdir = "C: \ TheInstallDirectory \" / PackageRoot = "PackageRootPath"
sympatric greg
Saya menggunakan Installutil.exe dan untuk teknologi yang lebih lama saya menggunakan Instsrv.exe dari Windows XP / 2003 Resource Ket.
Gary Kindel

Jawaban:

257
sc create <servicename> binpath= "<pathtobinaryexecutable>" [option1] [option2] [optionN]

Triknya adalah meninggalkan spasi setelah = dalam pernyataan buat Anda, dan juga menggunakan "" untuk apa pun yang mengandung karakter atau spasi khusus.

Dianjurkan untuk menentukan Nama Tampilan untuk layanan serta mengatur pengaturan mulai ke otomatis sehingga mulai secara otomatis. Anda dapat melakukan ini dengan menentukan DisplayName= yourdisplaynamedan start= automembuat pernyataan.

Berikut ini sebuah contoh:

C:\Documents and Settings\Administrator> sc create asperacentral 
binPath= "C:\Program Files\Aspera\Enterprise Server\bin\Debug\asperacentral.exe" 
DisplayName= "Aspera Central" 
start= auto

Jika ini berhasil, Anda akan melihat:

[SC] CreateService SUCCESS

PEMBARUAN 1

http://support.microsoft.com/kb/251192

Mhmd
sumber
39
Perlu diingat bahwa ruang setelah binpath = ( binPath= "C:\...") perlu untuk hadir, atau yang lain ini tidak akan bekerja.
Onion-Knight
1
start= autoadalah yang penting, jadi setelah reboot layanan akan dimulai secara otomatis. Sangat bagus jika pengguna akhir bukan ahli
LaBracca
21
Juga jika Anda perlu memberikan parameter tambahan pada binPathtanda kutip yang memerlukan tanda kutip, mereka harus melarikan diri ( \") contoh: jika jalurnya c:\some long path\some.exe "first argument"harus,binPath= "\"c:\some long path\some.exe\" \"first argument\""
Lankymart
1
Jika Anda tidak memiliki spasi setelah "=" di argumen Anda (seperti binPath= ...dan DisplayName= ...; dalam kasus saya, saya lupa "=" setelah DisplayName), maka konsol akan mencetak petunjuk penggunaan untuk createperintah; like: DESCRIPTION: Creates a service entry... USAGE: sc <server> create....etc
The Red Pea
3
Spasi
152

Parameter untuk layanan yang dibuat memiliki beberapa masalah pembentukan khusus, khususnya jika perintah termasuk spasi atau kutipan:

Jika Anda ingin memasukkan parameter baris perintah untuk layanan, Anda harus menyertakan seluruh baris perintah dalam tanda kutip. (Dan selalu meninggalkan tempat setelah binPath=dan sebelum kutipan pertama, seperti yang ditunjukkan mrswadge)

Jadi, untuk membuat layanan untuk perintah PATH\COMMAND.EXE --param1=xyz Anda akan menggunakan parameter binPath berikut:

binPath= "PATH\COMMAND.EXE --param1=xyz"
        ^^                             ^
        ||                             |
  space    quote                     quote

Jika path ke executable berisi spasi , Anda harus menyertakan path dalam tanda kutip.

Jadi untuk sebuah perintah yang memiliki kedua parameter dan jalan dengan spasi, Anda perlu tanda kutip bersarang . Anda harus melarikan diri dari kutipan batin dengan garis miring terbalik \". Hal yang sama berlaku jika parameter itu sendiri mengandung tanda kutip, Anda juga perlu menghindarinya.

Meskipun menggunakan garis miring terbalik sebagai karakter pelarian, Anda tidak perlu melarikan diri garis miring terbalik yang biasa terdapat di jalur. Ini bertentangan dengan bagaimana Anda biasanya menggunakan garis miring terbalik sebagai karakter pelarian.

Jadi untuk perintah seperti
"PATH WITH SPACES \COMMAND.EXE" --param-with-quotes="a b c" --param2:

binPath= "\"PATH WITH SPACES \COMMAND.EXE\" --param-with-quotes=\"a b c\" --param2"
         ^ ^                 ^           ^                      ^       ^         ^
         | |                 |           |                      |       |         | 
 opening     escaped      regular     escaped                    escaped       closing
   quote     quote       backslash    closing                    quotes          quote
     for     for            in         quote                      for              for
   whole     path          path       for path                  parameter        whole
 command                                                                       command

Ini adalah contoh nyata dari dokumentasi SVNserve, yang memperlihatkan semua kasus khusus:

sc create svnserve 
   binpath= "\"C:\Program Files\CollabNet Subversion Server\svnserve.exe\" --service -r \"C:\my repositories\"  "
   displayname= "Subversion Server" depend= Tcpip start= auto 

(linebreak ditambahkan untuk dibaca, jangan termasuk mereka)

Ini akan menambah layanan baru dengan baris perintah "C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories".

Demikian ringkasannya

  • spasi setelah setiap parameter sc: binpath=_, displayname=_dandepend=_
  • setiap parameter sc yang berisi spasi harus dilampirkan dalam tanda kutip
  • semua kutipan tambahan di dalam binpath lolos dengan garis miring terbalik: \"
  • semua backslash di dalam binpath tidak lolos
HugoRune
sumber
7
Saya menemukan itu penting untuk memastikan ada ruang antara binPath = dan nilai "myservice.exe". yaitu binPath= "myservice.exe. Penerjemah baris perintah harus mengharapkan ini dan membutuhkan perintah untuk menjadi tokenized dengan menggunakan spasi sebagai pembatas.
mrswadge
Saya mencoba cara ini dan berhasil. SC.EXE "\\ ServerName" Buat "ServiceName" BinPath = "SampleService.exe"
Sai
5

Saya mengalami masalah dalam menjalankan ini pada Windows 7. Tampaknya mengabaikan argumen pertama yang saya sampaikan sehingga saya menggunakan binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2"dan berhasil.

Craig Carpenter
sumber
4

Saya gunakan untuk membuatnya tanpa parameter, dan kemudian mengedit registri HKLM\System\CurrentControlSet\Services\[YourService].

Tony
sumber
2

Perintah ini berfungsi:

sc create startSvn binPath= "\"C:\Subversion\bin\svnserve.exe\" --service -r \"C:\SVN_Repository\"" displayname= "MyServer" depend= tcpip start= auto
pengguna2535091
sumber
2

Penting juga untuk mempertimbangkan bagaimana Anda mengakses Argumen dalam kode aplikasi.

Dalam aplikasi c # saya menggunakan kelas ServiceBase:

 class MyService : ServiceBase
{

    protected override void OnStart(string[] args)
    {
       }
 }

Saya mendaftarkan layanan saya menggunakan

sc buat myService binpath = "MeyService.exe arg1 arg2"

Tapi saya tidak bisa mengakses argumen melalui argsvariabel ketika saya menjalankannya sebagai layanan.

Dokumentasi MSDN menyarankan tidak menggunakan metode utama untuk mengambil binPathatau ImagePathargumen. Sebaliknya itu menyarankan menempatkan logika Anda dalam OnStartmetode dan kemudian menggunakan (C #) Environment.GetCommandLineArgs();.

Untuk mengakses argumen pertama yang arg1perlu saya lakukan seperti ini:

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

                log.Info("arg1 == "+Environment.GetCommandLineArgs()[1]);

       }
 }

ini akan mencetak

       arg1 == arg1
Panciz
sumber
Anda juga bisa mendapatkan arg1 dan arg2 dari parameter args pada metode Utama.
Wojciech Mikołajewicz
1

Saya menemukan cara untuk menggunakan sc.

sc config binPath = "\" c: \ path dengan spasi di dalamnya \ service_executable.exe \ ""

Dengan kata lain, gunakan \ untuk melarikan diri dari setiap "" Anda ingin selamat dari transit ke dalam registri.

Rem Onyshczak
sumber
1

Contoh pembuatan layanan menggunakan backslash dengan banyak tanda kutip ganda.

C:\Windows\system32>sc.exe create teagent binpath= "\"C:\Program Files\Tripwire\TE\Agent\bin\wrapper.exe\" -s \"C:\Program Files\Tripwire\TE\Agent\bin\agent.conf\"" DisplayName= "Tripwire Enterprise Agent"

[SC] CreateService SUCCESS
Nash A
sumber
0

Pastikan Anda memiliki tanda kutip di awal dan akhir dari nilai binPath Anda.

cripox
sumber
1
Diberi path "c: \ abc \ def.exe", saya mencoba untuk mengirimkan Param1 = "ghi" seperti ini: binPath = "c: \ abc \ def.exe / Param1 = ghi". Tapi tidak berhasil ...
sympatric greg
0

Saya tidak bisa menangani masalah dengan proposal Anda, pada akhirnya dengan folder x86 itu hanya berfungsi di power shell (windows server 2012) menggunakan variabel lingkungan:

{sc.exe create svnserve binpath= "${env:programfiles(x86)}/subversion/bin/svnserve.exe --service -r C:/svnrepositories/"   displayname= "Subversion Server" depend= Tcpip start= auto}
g0r1lla
sumber
0

Jika Anda mencoba semua hal di atas dan masih tidak dapat mengirimkan argumen ke layanan Anda, jika layanan Anda ditulis dalam C / C ++, inilah yang bisa menjadi masalah: ketika Anda memulai layanan Anda melalui "sc start arg1 arg2 ..." , SC memanggil fungsi ServiceMain layanan Anda secara langsung dengan argumen tersebut. Tetapi ketika Windows memulai layanan Anda (saat boot, misalnya), itu fungsi utama layanan Anda (_tmain) yang dipanggil, dengan params dari "binPath" registri.

BlueRiver
sumber
0

itu tidak berfungsi di Powershell dan harus menggunakan CMD dalam kasus saya

William
sumber
diperbaiki di PowerShell 5.1
oetzi