[windows-services] sc.exe로 서비스를 만들 때 컨텍스트 매개 변수를 전달하는 방법은 무엇입니까?

다음을 사용하여 Windows 서비스를 작성할 때 :

sc create ServiceName binPath= "the path"

어떻게 인수를 Installer 클래스의 Context.Parameters 컬렉션에 전달할 수 있습니까?

sc.exe문서를 읽었을 때 그러한 인수는의 끝에 만 전달 될 수 binPath있지만 예제를 찾지 못했거나 성공적으로 수행 할 수 없었습니다.



답변

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

비결은 create 문에서 = 뒤에 공백을 남기고 특수 문자 나 공백을 포함하는 모든 항목에 “”를 사용하는 것입니다.

서비스의 표시 이름을 지정하고 자동으로 시작되도록 시작 설정을 자동으로 설정하는 것이 좋습니다. 당신은 지정하여이 작업을 수행 할 수 있습니다 DisplayName= yourdisplaynamestart= 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


답변

작성된 서비스의 매개 변수에는 특히 형식에 따옴표 나 공백이 포함 된 경우 특별한 형식화 문제가 있습니다.

서비스에 대한 명령 행 매개 변수 를 입력 하려면 전체 명령 행 을 따옴표로 묶어야합니다. (그리고 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 내부의 모든 백 슬래시는 이스케이프되지 않습니다

답변

sc "YOURSERVICENAME"작성 binpath = "\"C : \ Program Files (x86) \ Microsoft SQL Server \ MSSQL11 \ MSSQL \ Binn \ sqlservr.exe \ "-sOPTIONALSWITCH"start = auto

여기를 참조하십시오 : Windows 서비스의 “실행 파일 경로”수정


답변

나는 이것을 Windows 7에서 작동시키는 데 문제가있었습니다 binPath= "C:\path\to\service.exe -bogusarg -realarg1 -realarg2".


답변

매개 변수없이 생성 한 다음 레지스트리를 편집하는 데 사용합니다 HKLM\System\CurrentControlSet\Services\[YourService].


답변

이 명령은 작동합니다 :

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


답변

또한 응용 프로그램 코드에서 인수에 액세스하는 방법을 고려하는 것이 중요합니다.

내 C # 응용 프로그램에서 ServiceBase 클래스를 사용했습니다.

 class MyService : ServiceBase
{

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

서비스를 사용하여 서비스를 등록했습니다

sc create myService binpath = “MeyService.exe arg1 arg2”

그러나 args서비스로 실행할 때 변수를 통해 인수에 액세스 할 수 없었 습니다.

MSDN 설명서에서는 Main 메서드를 사용하여 binPath또는 ImagePath인수 를 검색하지 않는 것이 좋습니다 . 대신 OnStart메소드에 논리를 배치 하고 (C #)을 사용 하는 것이 좋습니다 Environment.GetCommandLineArgs();.

첫 번째 인수에 액세스하려면 arg1다음과 같이해야합니다.

class MyService : ServiceBase
 {

    protected override void OnStart(string[] args)
    {

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

       }
 }

이것은 인쇄 할 것이다

       arg1 == arg1