عند إنشاء خدمة مع Sc.exe كيفية المرور في معلمات السياق؟
-
01-10-2019 - |
سؤال
عند إنشاء خدمة Windows باستخدام:
sc create ServiceName binPath= "the path"
كيف يمكن تمرير الحجج إلى سياق فئة المثبت. مجموعة الساميات؟
قراءتي sc.exe
الوثائق هي أنه لا يمكن تمرير مثل هذه الحجج إلا في نهاية binPath
, ، لكنني لم أجد مثالاً أو تمكنت من القيام بذلك بنجاح.
المحلول
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
نصائح أخرى
تحتوي المعلمات الخاصة بالخدمات التي تم إنشاؤها على بعض مشكلات التكوين الغريبة ، ولا سيما إذا كان الأمر يتضمن مسافات أو اقتباسات:
إذا كنت تريد الدخول معلمات سطر الأوامر للخدمة ، عليك أن ترفق سطر الأوامر بأكمله في اقتباسات. (وتترك دائمًا مساحة بعد binPath=
وقبل الاقتباس الأول ، كما أشار Mrswadge)
لذلك ، لإنشاء خدمة للأمر PATH\COMMAND.EXE --param1=xyz
يمكنك استخدام معلمة binpath التالية:
binPath= "PATH\COMMAND.EXE --param1=xyz"
^^ ^
|| |
space quote quote
إذا طريق إلى التنفيذ يحتوي على مسافات, ، عليك أن ترفق طريق في اقتباسات.
لذلك بالنسبة لأمر له على حد سواء المعلمات و طريق مع المسافات ، تحتاج اقتباسات متداخلة. عليك الهروب \". وينطبق الشيء نفسه إذا كانت المعلمات نفسها تحتوي على اقتباسات ، ستحتاج إلى الهروب من تلك أيضًا.
على الرغم من استخدام Blackslashes كشخصيات Escape ، لا يتعين عليك الهروب من عمليات التراجع العادية الموجودة في المسار. هذا يتعارض مع الطريقة التي تستخدم بها عادةً كحرفات Escape.
لذلك لأمر مثل
"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 create "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# الخاص بي ، استخدمت فئة قاعدة الخدمة:
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
لقد وجدت طريقة لاستخدام SC.
SC config binpath = "" c: path مع مسافات في service_executable.exe ""
بمعنى آخر ، استخدم للهروب من أي "تريد البقاء على قيد الحياة في السجل.
تأكد من وجود اقتباسات في بداية ونهاية قيمة binpath الخاصة بك.
لم أتمكن من التعامل مع المشكلة مع مقترحاتك ، في النهاية مع مجلد 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}
إذا جربت كل ما سبق وما زلت لا تستطيع نقل Args إلى خدمتك ، إذا تمت كتابة خدمتك في C/C ++ ، فإليك ما يمكن أن يكون المشكلة: عندما تبدأ خدمتك من خلال "SC Start Arg1 Arg2 ..." ، يدعو SC وظيفة ServiceMain الخاصة بخدمتك مباشرة مع تلك ARGS. ولكن عندما تبدأ Windows خدمتك (في وقت التمهيد ، على سبيل المثال) ، فإن الوظيفة الرئيسية لخدمتك (_tmain) التي تسمى ، مع Params من "BinPath" للسجل.
مثال على إنشاء الخدمة لاستخدام الخلف مع العديد من الاقتباسات المزدوجة.
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