เมื่อสร้างบริการด้วย sc.exe จะส่งผ่านพารามิเตอร์บริบทได้อย่างไร


143

เมื่อสร้างบริการ Windows โดยใช้:

sc create ServiceName binPath= "the path"

อาร์กิวเมนต์สามารถส่งผ่านไปยังคอลเลกชัน Context.Parameters ของคลาส Installer ได้อย่างไร

การอ่านsc.exeเอกสารของฉันคือข้อโต้แย้งดังกล่าวจะถูกส่งต่อเมื่อสิ้นสุดbinPathแต่ฉันไม่พบตัวอย่างหรือสามารถทำสิ่งนี้ได้สำเร็จ


ภาพรวมของคีย์ Services ใน Registry แสดงให้เห็นว่ามีพารามิเตอร์ที่จำเป็นใด ๆ รวมอยู่ในค่า ImagePath ดังนั้นคุณจึงbinPath= "c:\abc\def.exe /Param1=ghi"ดูเหมือนเป็นแนวคิดที่ถูกต้อง แบ็กสแลชจำเป็นต้องหลบหนี (เช่น "c: \\ abc \\ ... ") หรือไม่ สิ่งที่แย่ที่สุดคือคุณสามารถแก้ไขค่า Registry โดยตรงหลังจากนั้นถ้า SC.EXE ไม่สามารถทำได้
eWall

1
ฉันยอมแพ้กับ sc.exe และฉันใช้ installutil.exe เช่นนั้น: Installutil.exe / ServiceName =” TheName” / targetdir =” C: \ TheInstallDirectory \” / PackageRoot =” PackageRootPath”
sympatric greg

ฉันใช้ Installutil.exe และเทคโนโลยีเก่าฉันใช้ Instsrv.exe จาก Windows XP / 2003 Resource Ket
Gary Kindel

คำตอบ:


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

เคล็ดลับคือการเว้นช่องว่างหลังจาก = ในคำสั่งสร้างของคุณและเพื่อใช้ "" สำหรับทุกสิ่งที่มีอักขระพิเศษหรือช่องว่าง

ขอแนะนำให้ระบุชื่อที่แสดงสำหรับบริการรวมถึงการตั้งค่าการตั้งค่าเริ่มต้นเป็นอัตโนมัติเพื่อให้เริ่มโดยอัตโนมัติ คุณสามารถทำได้โดยการระบุDisplayName= yourdisplaynameและstart= autoในคำสั่งสร้างของคุณ

นี่คือตัวอย่าง:

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

หากทำงานได้คุณควรเห็น:

[SC] CreateService SUCCESS

อัพเดท 1

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


39
โปรดจำไว้ว่าช่องว่างหลังจาก binPath = ( binPath= "C:\...") จำเป็นต้องมีอยู่มิฉะนั้นจะไม่สามารถใช้งานได้
Onion-Knight

1
start= autoเป็นสิ่งสำคัญดังนั้นหลังจากรีบูตบริการจะเริ่มโดยอัตโนมัติ ดีมากในกรณีที่ผู้ใช้ไม่ใช่ผู้เชี่ยวชาญ
LaBracca

21
นอกจากนี้หากคุณจำเป็นต้องผ่านพารามิเตอร์พิเศษในการbinPathที่ต้องมีการพูดพวกเขาจะต้องหลบหนี ( \") ตัวอย่าง: ถ้าเส้นทางc:\some long path\some.exe "first argument"ก็จะต้องเป็นbinPath= "\"c:\some long path\some.exe\" \"first argument\""
Lankymart

1
หากคุณไม่มีช่องว่างหลังจาก "=" ใน args ของคุณ (เช่นbinPath= ...และDisplayName= ...; ในกรณีของฉันฉันลืม "=" หลังจาก DisplayName) จากนั้นคอนโซลจะพิมพ์คำแนะนำการใช้งานสำหรับcreateคำสั่ง; ไลค์: DESCRIPTION: Creates a service entry... USAGE: sc <server> create....ฯลฯ
The Red Pea

3
ช่องว่างหลังจาก "=" มีความสำคัญมาก
ErisoHV

152

พารามิเตอร์สำหรับบริการที่สร้างขึ้นมีปัญหาในการจัดรูปแบบเฉพาะโดยเฉพาะถ้าคำสั่งมีช่องว่างหรือเครื่องหมายคำพูด:

หากคุณต้องการป้อนพารามิเตอร์บรรทัดคำสั่งสำหรับบริการคุณจะต้องใส่บรรทัดคำสั่งทั้งหมดในเครื่องหมายคำพูด (และมักจะเว้นช่องว่างหลังbinPath=และก่อนที่จะพูดครั้งแรกตามที่ mrswadge ชี้ให้เห็น)

ดังนั้นเพื่อสร้างบริการสำหรับคำสั่งPATH\COMMAND.EXE --param1=xyz คุณจะใช้พารามิเตอร์ binPath ต่อไปนี้:

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

หากเส้นทางไปยังแฟ้มที่ปฏิบัติการได้มีช่องว่างคุณจะต้องใส่เส้นทางในเครื่องหมายคำพูด

ดังนั้นสำหรับคำสั่งที่มีทั้งพารามิเตอร์และเส้นทางที่มีช่องว่างที่คุณจะต้องคำพูดที่ซ้อนกัน \"คุณจะต้องหลบหนีคำพูดด้านที่มีเครื่องหมาย การเก็บเดียวกันถ้าพารามิเตอร์ตัวเองมีคำพูดคุณจะต้องหลบหนีเหล่านั้นด้วย

แม้จะใช้เครื่องหมายแบ็กสแลชเป็นอักขระเลี่ยงคุณไม่จำเป็นต้องหลบหนีแบ็กสแลชปกติที่อยู่ในพา ธ นี่ตรงกันข้ามกับวิธีที่คุณใช้แบ็กสแลชเป็นอักขระเลี่ยง

ดังนั้นสำหรับคำสั่งเช่น
"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

นี่คือตัวอย่างที่เป็นรูปธรรมจากเอกสาร SVNserve ซึ่งแสดงกรณีพิเศษทั้งหมด:

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

(มีการเพิ่มการแบ่งบรรทัดสำหรับการอ่านได้ แต่ไม่รวม)

"C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories"นี้จะเพิ่มบริการใหม่ที่มีบรรทัดคำสั่ง

ดังนั้นโดยสรุป

  • ช่องว่างหลังพารามิเตอร์ sc แต่ละตัว: binpath=_, displayname=_และdepend=_
  • พารามิเตอร์ sc แต่ละตัวที่มีช่องว่างต้องอยู่ในเครื่องหมายคำพูด
  • เครื่องหมายอัญประกาศเพิ่มเติมทั้งหมดภายใน binpath มีการหลบหนีด้วยแบ็กสแลช: \"
  • แบ็กสแลชทั้งหมดที่อยู่ใน binpath จะไม่ถูก Escape

7
ฉันพบว่ามันสำคัญที่ต้องแน่ใจว่ามีช่องว่างระหว่าง binPath = และค่า "myservice.exe" binPath= "myservice.exeกล่าวคือ ตัวแปลบรรทัดคำสั่งต้องคาดหวังสิ่งนี้และต้องการให้คำสั่งกลายเป็นโทเค็นโดยใช้ช่องว่างเป็นตัวคั่น
mrswadge

ฉันลองวิธีนี้และใช้งานได้ SC.EXE "\\ ServerName" สร้าง "ServiceName" BinPath = "SampleService.exe"
สาย


5

ฉันมีปัญหาในการทำให้สิ่งนี้ทำงานบน Windows 7 ดูเหมือนจะไม่สนใจอาร์กิวเมนต์แรกที่ฉันส่งผ่านดังนั้นฉันจึงใช้binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2"และทำงานได้


4

HKLM\System\CurrentControlSet\Services\[YourService]ฉันจะใช้เพียงแค่สร้างมันขึ้นมาโดยไม่มีพารามิเตอร์แล้วแก้ไขรีจิสทรี


2

คำสั่งนี้ใช้งานได้:

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

2

สิ่งสำคัญคือคุณต้องคำนึงถึงวิธีการเข้าถึงอาร์กิวเมนต์ในรหัสของแอปพลิเคชัน

ในแอปพลิเคชัน c # ของฉันฉันใช้คลาส ServiceBase:

 class MyService : ServiceBase
{

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

ฉันลงทะเบียนบริการโดยใช้

sc สร้าง myService binpath = "MeyService.exe arg1 arg2"

แต่ฉันไม่สามารถเข้าถึงข้อโต้แย้งผ่านargsตัวแปรเมื่อฉันเรียกใช้เป็นบริการ

เอกสาร MSDN ไม่แนะนำให้ใช้วิธีการหลักในการเรียกคืนbinPathหรือImagePathอาร์กิวเมนต์ แต่มันแสดงให้เห็นการวางตรรกะของคุณในOnStartวิธีการและแล้วใช้ (C Environment.GetCommandLineArgs();#)

ในการเข้าถึงอาร์กิวเมนต์แรกarg1ฉันต้องทำดังนี้

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

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

       }
 }

สิ่งนี้จะพิมพ์

       arg1 == arg1

คุณสามารถรับ arg1 และ arg2 ของคุณจากพารามิเตอร์ args ในวิธีการหลักได้
วอยMikołajewicz

1

ฉันพบวิธีใช้ sc

sc config binPath = "\" c: \ path ที่มีช่องว่างอยู่ \ service_executable.exe \ ""

กล่าวอีกนัยหนึ่งให้ใช้ \ เพื่อหลีกเลี่ยง "ที่คุณต้องการเอาตัวรอดจากการขนส่งเข้าไปในรีจิสตรี


1

ตัวอย่างการสร้างบริการของการใช้แบ็กสแลชที่มีเครื่องหมายคำพูดคู่หลายตัว

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

0

ตรวจสอบให้แน่ใจว่ามีเครื่องหมายคำพูดที่จุดเริ่มต้นและจุดสิ้นสุดของค่า binPath ของคุณ


1
ให้เส้นทาง "c: \ abc \ def.exe" ฉันพยายามผ่าน Param1 = "ghi" เช่นนี้: binPath = "c: \ abc \ def.exe / Param1 = ghi" แต่ไม่มีงาน ...
sympatric greg

0

ฉันไม่สามารถจัดการปัญหากับข้อเสนอของคุณได้ในตอนท้ายด้วยโฟลเดอร์ x86 มันใช้งานได้เฉพาะใน power shell (windows server 2012) โดยใช้ตัวแปรสภาพแวดล้อม:

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

0

หากคุณลองทุกอย่างที่กล่าวมาแล้วและยังไม่สามารถผ่าน args ไปยังบริการของคุณได้ถ้าบริการของคุณเขียนเป็น C / C ++ นี่คือสิ่งที่อาจเป็นปัญหา: เมื่อคุณเริ่มบริการผ่าน "sc start arg1 arg2 ... " เซาท์แคโรไลนาเรียกใช้ฟังก์ชัน ServiceMain ของบริการโดยตรงกับเนื้อหาเหล่านั้น แต่เมื่อ Windows เริ่มบริการของคุณ (เช่นเวลาบูต) มันเป็นหน้าที่หลักของบริการของคุณ (_tmain) ที่ถูกเรียกใช้โดยมี params จาก "binPath" ของรีจิสทรี


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.