Khi tạo một dịch vụ với sc.exe làm thế nào để vượt qua trong các tham số ngữ cảnh?


143

Khi tạo dịch vụ Windows bằng:

sc create ServiceName binPath= "the path"

làm thế nào các đối số có thể được chuyển đến bộ sưu tập Context.Parameter của lớp Trình cài đặt?

Việc đọc sc.exetài liệu của tôi là các đối số như vậy chỉ có thể được thông qua vào cuối binPath, nhưng tôi chưa tìm thấy một ví dụ hoặc có thể thực hiện thành công điều này.


Nhìn lướt qua phím Dịch vụ trong Sổ đăng ký cho thấy rằng mọi tham số cần thiết đều được bao gồm với giá trị ImagePath, vì vậy bạn binPath= "c:\abc\def.exe /Param1=ghi"có vẻ như là ý tưởng đúng. Các dấu gạch chéo ngược có cần được thoát không (ví dụ: "c: \\ abc \\ ...")? Điều tồi tệ nhất, bạn có thể trực tiếp chỉnh sửa giá trị Registry sau đó nếu SC.EXE không thể làm điều đó.
ewall

1
Tôi đã từ bỏ trên sc.exe và đang sử dụng installutil.exe như vậy: Installutil.exe / ServiceName =”TheName” / TargetDir =”C: \ TheInstallDirectory \” / PackageRoot =”PackageRootPath”
sympatric greg

Tôi đã sử dụng Installutil.exe và đối với công nghệ cũ hơn, tôi sử dụng Instsrv.exe từ Windows XP / 2003 Resource Ket.
Gary Kindel

Câu trả lời:


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

Mẹo là để lại một khoảng trắng sau dấu = trong câu lệnh tạo của bạn và cũng sử dụng "" cho bất kỳ thứ gì có chứa các ký tự hoặc khoảng trắng đặc biệt.

Bạn nên chỉ định Tên hiển thị cho dịch vụ cũng như đặt cài đặt bắt đầu thành tự động để nó tự động bắt đầu. Bạn có thể làm điều này bằng cách chỉ định DisplayName= yourdisplaynamestart= autotrong tuyên bố tạo của bạn.

Đây là một ví dụ:

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

Nếu điều này làm việc bạn nên xem:

[SC] CreateService SUCCESS

CẬP NHẬT 1

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


39
Hãy nhớ rằng không gian sau binPath = ( binPath= "C:\...") cần phải có mặt, nếu không điều này sẽ không hoạt động.
Onion-Knight

1
start= autolà một điều quan trọng, vì vậy sau khi khởi động lại, dịch vụ sẽ tự động bắt đầu. Rất tốt trong trường hợp người dùng cuối không phải là chuyên gia
LaBracca

21
Ngoài ra, nếu bạn cần vượt qua các tham số bổ sung trong binPathyêu cầu trích dẫn, chúng phải được thoát ( \") ví dụ: nếu đường dẫn là c:\some long path\some.exe "first argument"cần phải cóbinPath= "\"c:\some long path\some.exe\" \"first argument\""
Lankymart 16/07/2015

1
Nếu bạn không có khoảng trắng sau "=" trong đối số của bạn (như binPath= ...DisplayName= ...trong trường hợp của tôi, tôi đã quên "=" sau DisplayName), thì bảng điều khiển sẽ in hướng dẫn sử dụng cho createlệnh; như: DESCRIPTION: Creates a service entry... USAGE: sc <server> create....vân vân
Hạt đậu đỏ

3
Các khoảng trắng sau dấu "=" là rất quan trọng
ErisoHV

152

Các tham số cho các dịch vụ được tạo có một số vấn đề hình thành đặc biệt, đặc biệt nếu lệnh bao gồm khoảng trắng hoặc dấu ngoặc kép:

Nếu bạn muốn nhập tham số dòng lệnh cho dịch vụ, bạn phải đặt toàn bộ dòng lệnh trong dấu ngoặc kép. (Và luôn để lại một khoảng trống sau binPath=và trước trích dẫn đầu tiên, như mrswadge đã chỉ ra)

Vì vậy, để tạo một dịch vụ cho lệnh, PATH\COMMAND.EXE --param1=xyz bạn sẽ sử dụng tham số binPath sau:

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

Nếu đường dẫn đến tệp thực thi chứa khoảng trắng , bạn phải đặt đường dẫn trong dấu ngoặc kép.

Vì vậy, đối với một lệnh có cả tham số đường dẫn có khoảng trắng, bạn cần dấu ngoặc kép . Bạn phải thoát các trích dẫn bên trong với dấu gạch chéo ngược\" . Điều tương tự giữ nếu các tham số tự chứa dấu ngoặc kép, bạn cũng sẽ cần phải thoát chúng.

Mặc dù sử dụng dấu gạch chéo ngược làm ký tự thoát, bạn không phải thoát dấu gạch chéo ngược thông thường có trong đường dẫn. Điều này trái với cách bạn thường sử dụng dấu gạch chéo ngược làm ký tự thoát.

Vì vậy, đối với một lệnh như
"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

Dưới đây là một ví dụ cụ thể từ tài liệu SVNserve, cho thấy tất cả các trường hợp đặc biệt:

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

(ngắt dòng được thêm vào để dễ đọc, không bao gồm chúng)

Điều này sẽ thêm một dịch vụ mới với dòng lệnh "C:\Program Files\CollabNet Subversion Server\svnserve.exe" --service -r "C:\my repositories".

Tóm lại

  • không gian sau mỗi tham số sc: binpath=_, displayname=_depend=_
  • mỗi tham số sc có chứa khoảng trắng phải được đặt trong dấu ngoặc kép
  • tất cả các trích dẫn bổ sung bên trong binpath được thoát với dấu gạch chéo ngược: \"
  • tất cả các dấu gạch chéo ngược bên trong binpath không được thoát

7
Tôi thấy điều quan trọng là phải đảm bảo có khoảng cách giữa binPath = và giá trị "myservice.exe". tức binPath= "myservice.exe. Trình thông dịch dòng lệnh phải mong đợi điều này và yêu cầu lệnh phải được mã hóa bằng cách sử dụng khoảng trắng làm dấu phân cách.
mrswadge 20/03/13

Tôi đã thử cách này và nó đã làm việc. SC.EXE "\\ Tên máy chủ" Tạo "Tên dịch vụ" BinPath = "SampleService.exe"
Sai


5

Tôi gặp vấn đề khi điều này hoạt động trên Windows 7. Nó dường như bỏ qua đối số đầu tiên tôi đã sử dụng để tôi sử dụng binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2"và nó đã hoạt động.


4

Tôi sử dụng để chỉ tạo nó mà không có tham số, và sau đó chỉnh sửa sổ đăng ký HKLM\System\CurrentControlSet\Services\[YourService].


2

Lệnh này hoạt động:

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

2

Nó cũng quan trọng trong việc tính đến cách bạn truy cập các Đối số trong mã của ứng dụng.

Trong ứng dụng c # của tôi, tôi đã sử dụng lớp ServiceBase:

 class MyService : ServiceBase
{

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

Tôi đã đăng ký dịch vụ của mình bằng

sc tạo myService binpath = "MeyService.exe arg1 arg2"

Nhưng tôi không thể truy cập các đối số thông qua argsbiến khi tôi chạy nó như một dịch vụ.

Tài liệu MSDN đề nghị không sử dụng phương thức Main để truy xuất binPathhoặc ImagePathđối số. Thay vào đó, nó gợi ý đặt logic của bạn vào OnStartphương thức và sau đó sử dụng (C #) Environment.GetCommandLineArgs();.

Để truy cập các đối số đầu tiên arg1tôi cần phải làm như thế này:

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

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

       }
 }

cái này sẽ in

       arg1 == arg1

Bạn cũng có thể lấy arg1 và arg2 từ tham số args trên phương thức Main.
Wojciech Mikołajewicz

1

Tôi tìm thấy một cách để sử dụng sc.

sc config binPath = "\" c: \ path có khoảng trắng trong đó \ service_executable.exe \ ""

Nói cách khác, sử dụng \ để thoát bất kỳ "bạn muốn tồn tại quá cảnh vào sổ đăng ký.


1

Một ví dụ tạo dịch vụ sử dụng dấu gạch chéo ngược có nhiều dấu ngoặc kép.

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

Hãy chắc chắn có dấu ngoặc kép ở đầu và cuối giá trị binPath của bạn.


1
Đưa ra một đường dẫn "c: \ abc \ def.exe", tôi đã cố gắng vượt qua trong Param1 = "ghi" như thế này: binPath = "c: \ abc \ def.exe / Param1 = ghi". Nhưng không có việc gì ...
chứng cộng đồng

0

Tôi không thể xử lý vấn đề với các đề xuất của bạn, cuối cùng với thư mục x86, nó chỉ hoạt động trong shell điện (máy chủ windows 2012) bằng các biến môi trường:

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

0

Nếu bạn đã thử tất cả các cách trên mà vẫn không thể chuyển args sang dịch vụ của mình, nếu dịch vụ của bạn được viết bằng C / C ++, thì đây có thể là vấn đề: khi bạn bắt đầu dịch vụ của mình thông qua "sc start arg1 arg2 ..." , SC gọi hàm ServiceMain của dịch vụ của bạn trực tiếp với các đối số đó. Nhưng khi Windows khởi động dịch vụ của bạn (chẳng hạn như lúc khởi động), thì đó là chức năng chính của dịch vụ của bạn (_tmain) được gọi, với thông số từ "binPath" của cơ quan đăng ký.


0

nó không hoạt động trong Powershell và nên sử dụng CMD trong trường hợp của tôi


đã sửa trong PowerShell 5.1
oetzi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.