ব্যাচ বা সিএমডি ফাইলের মাধ্যমে কোনও পরিষেবা বন্ধ করুন এবং শুরু করবেন?


288

ত্রুটি যাচাইয়ের মাধ্যমে নির্ভরযোগ্যভাবে কোনও পরিষেবা থামাতে এবং পরিষেবা শুরু করতে আমি কীভাবে কোনও ব্যাট বা সেমিএসডি স্ক্রিপ্ট করতে পারি (বা আমাকে জানতে দিন যে এটি কোনও কারণেই সফল হয়নি)?


হতে পারে কিছুটা অফটোপিক (যেহেতু আপনি ব্যাট ও সেন্টিমিটারের নির্দেশ চান) তবে: পাওয়ারশেল আপনাকে এই জাতীয় ক্রিয়া করার জন্য প্রচুর নিয়ন্ত্রণ এবং প্রতিক্রিয়া দেয়।
জিভিএস

উত্তর:


347

SC(পরিষেবা নিয়ন্ত্রণ) কমান্ডটি ব্যবহার করুন , এটি আপনাকে ঠিক start& এর চেয়ে অনেক বেশি বিকল্প দেয় stop

  বর্ণনাঃ
          এসসি একটি কমান্ড লাইন প্রোগ্রাম যা এর সাথে যোগাযোগের জন্য ব্যবহৃত হয়
          এনটি পরিষেবা নিয়ন্ত্রক এবং পরিষেবাগুলি।
  ব্যবহার:
      sc <server> [কমান্ড] [পরিষেবার নাম] ...

      <server> বিকল্পটিতে "\\ সার্ভারনাম" ফর্মটি রয়েছে
      কমান্ডগুলিতে আরও সহায়তা টাইপ করার মাধ্যমে প্রাপ্ত হতে পারে: "sc [আদেশ]"
      আদেশগুলি:
        ক্যোয়ারী ----------- কোনও পরিষেবার স্থিতি সম্পর্কে জিজ্ঞাসা করে, বা
                        বিভিন্ন ধরণের পরিষেবার জন্য স্থিতি গণ্য করে।
        queryex --------- কোনও পরিষেবার জন্য বর্ধিত স্থিতি অনুসন্ধান করে, বা or
                        বিভিন্ন ধরণের পরিষেবার জন্য স্থিতি গণ্য করে।
        শুরু ----------- একটি পরিষেবা শুরু করে।
        বিরতি দিন ----------- একটি পরিষেবাতে একটি PAUSE নিয়ন্ত্রণ অনুরোধ প্রেরণ করে।
        জিজ্ঞাসাবাদ ----- একটি পরিষেবাতে একটি আন্তঃসংযোগ নিয়ন্ত্রণ অনুরোধ প্রেরণ করে।
        চালিয়ে যান -------- একটি পরিষেবাতে একটি চালিত নিয়ন্ত্রণ অনুরোধ প্রেরণ করে।
        থামান ------------ একটি পরিষেবাতে একটি স্টপ অনুরোধ প্রেরণ করে।
        কনফিগারেশন ---------- একটি পরিষেবার কনফিগারেশন পরিবর্তন (নিয়মিত)।
        বিবরণ ----- একটি পরিষেবার বর্ণনাকে পরিবর্তন করে।
        ব্যর্থতা --------- ব্যর্থতার পরে কোনও পরিষেবার দ্বারা নেওয়া পদক্ষেপগুলি পরিবর্তন করে।
        qc -------------- একটি পরিষেবার জন্য কনফিগারেশন তথ্য জিজ্ঞাসা করে।
        qdescript ---- একটি পরিষেবার বিবরণ জিজ্ঞাসা করে।
        qfailure -------- ব্যর্থতার পরে কোনও পরিষেবার দ্বারা নেওয়া পদক্ষেপগুলি জিজ্ঞাসা করে।
        মুছুন ---------- একটি পরিষেবা মুছুন (রেজিস্ট্রি থেকে)।
        তৈরি ---------- একটি পরিষেবা তৈরি করে। (এটি রেজিস্ট্রিতে যুক্ত করে)।
        নিয়ন্ত্রণ --------- একটি পরিষেবাতে একটি নিয়ন্ত্রণ প্রেরণ করে।
        sdshow ---------- একটি পরিষেবার সুরক্ষা বর্ণনাকারী প্রদর্শন করে।
        sdset ----------- একটি পরিষেবার সুরক্ষা বর্ণনাকারী সেট করে।
        GetDisplayName - একটি পরিষেবার জন্য প্রদর্শন নামটি পান।
        GetKeyName ------ একটি পরিষেবার জন্য সার্ভিসকি নামটি পান।
        EnumD depend ------ পরিষেবা নির্ভরতা গণনা করে।

      নিম্নলিখিত কমান্ডগুলির একটি পরিষেবার নামের প্রয়োজন নেই:
      sc <server> <কম্যান্ড> <ফাংশন>
        বুট ------------ (ঠিক আছে | খারাপ) শেষ বুট করা উচিত কিনা তা নির্দেশ করে
                        সর্বশেষ জ্ঞাত-বুট কনফিগারেশন হিসাবে সংরক্ষণ করুন
        লক ------------ পরিষেবা ডেটাবেস লক করে
        ক্যুরিলক ------- এসসি ম্যানেজার ডেটাবেসের জন্য লকস্ট্যাটাসের অনুসন্ধান করে
  উদাহরণ:
          মাই সার্ভিস শুরু করুন

1
আমি সম্মত হই যে এটি নেট শুরু / থামার চেয়ে ভাল। মনে রাখবেন যে দূরবর্তী যন্ত্রগুলিতেও পরিষেবাগুলিকে স্পর্শ করার বিকল্প রয়েছে।
আউটলা প্রোগ্রামার 15

1
দুর্দান্ত উত্তর। তবে 'এসসি স্টার্ট পরিষেবা' চালানোর জন্য আপনার প্রশাসক হওয়া দরকার। আমি এখানে এর জন্য একটি সমাধান পেয়েছি ((স্বীকৃত উত্তরের সমাধানটিতে রয়েছে)
মাইকেল কে।

56
এসসি সমস্যা হ'ল কমান্ডটি তত্ক্ষণাত ফিরে আসে এবং ক্রিয়াটি সম্পূর্ণ হওয়ার পরে না। আপনি যদি ব্যাচ ফাইলের মাধ্যমে কোনও পরিষেবা পুনরায় চালু করতে চান (থামুন তবে শুরু করুন), স্টপটি তাত্ক্ষণিকভাবে ফিরে আসে, প্রারম্ভটি ব্যর্থ হয় কারণ পরিষেবাটি বন্ধ হয়নি। অ্যাকশন শেষ হওয়ার পরে নেট স্টপ / স্টার্ট রিটার্ন, সুতরাং এই সমস্যা নেই।
ডম

আমি প্রশাসনিক মোড হিসাবে সেন্টিমিডিটি খুললাম, ত্রুটি পেয়ে এই কমান্ডটির বাক্য গঠনটি হ'ল নেট স্টপ পরিষেবা
সতীশ সিং

পরিষেবাটি ঠিকভাবে বন্ধ করা হচ্ছে কিনা তা পরীক্ষা করার কোনও উপায় আছে ?? 2020 সালে?
আনন্দ বার্কি ফিলিপস

212
net start [serviceName]

এবং

net stop [serviceName]

তারা সফলভাবে সাফল্য পেয়েছে বা সফলভাবে ব্যর্থ হয়েছে কিনা তা আপনাকে বলুন। উদাহরণ স্বরূপ

U:\>net stop alerter
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

যদি কোনও ব্যাচ ফাইল থেকে চালানো হয় তবে আপনার কাছে রিটার্ন কোডটির ERRORLEVEL এ অ্যাক্সেস রয়েছে। 0 সাফল্যের ইঙ্গিত দেয়। উচ্চতর কিছু ব্যর্থতা নির্দেশ করে।

ব্যাট ফাইল হিসাবে error.bat:

@echo off
net stop alerter
if ERRORLEVEL 1 goto error
exit
:error
echo There was a problem
pause

আউটপুটটি দেখতে এমন দেখাচ্ছে:

U:\>error.bat
The Alerter service is not started.

More help is available by typing NET HELPMSG 3521.

There was a problem
Press any key to continue . . .

রিটার্ন কোডস

 - 0 = Success
 - 1 = Not Supported
 - 2 = Access Denied
 - 3 = Dependent Services Running
 - 4 = Invalid Service Control
 - 5 = Service Cannot Accept Control
 - 6 = Service Not Active
 - 7 = Service Request Timeout
 - 8 = Unknown Failure
 - 9 = Path Not Found
 - 10 = Service Already Running
 - 11 = Service Database Locked
 - 12 = Service Dependency Deleted
 - 13 = Service Dependency Failure
 - 14 = Service Disabled
 - 15 = Service Logon Failure
 - 16 = Service Marked For Deletion
 - 17 = Service No Thread
 - 18 = Status Circular Dependency
 - 19 = Status Duplicate Name
 - 20 = Status Invalid Name
 - 21 = Status Invalid Parameter 
 - 22 = Status Invalid Service Account
 - 23 = Status Service Exists
 - 24 = Service Already Paused

20.04.2015 সম্পাদনা করুন

রিটার্ন কোডগুলি:

নেট কমান্ড নথিভুক্ত উইন32_সেসওয়ার ক্লাসের রিটার্ন কোডগুলি (সার্ভিস অ্যাক্টিভ নয়, সার্ভিস রিকোয়েস্ট টাইমআউট ইত্যাদি) ফেরত দেয় না এবং অনেক ত্রুটির জন্য কেবল ত্রুটিযুক্ত 2 ফিরে আসবে।

এখানে দেখুন: http://ss64.com/nt/net_service.html


1
NET নয় থাকাকালীন মাত্র সেবা সম্পর্কিত কাজকর্মের জন্য SC হয় মাত্র সেবা সম্পর্কিত কাজকর্মের জন্য।
ওয়ার্নাইট

3
এই উত্তরটি আরও ভাল কারণ "নেট" কমান্ডটি ব্যাচ স্ক্রিপ্টটি চালিয়ে যাওয়ার আগে পরিষেবাটি শুরু বা থামার জন্য অপেক্ষা করে।
স্টিভেন

যেহেতু (সম্পাদনা হিসাবে বলা হয়েছে) বেশিরভাগ সময় errorlevelফিরে আসে 2, ত্রুটির ফলাফলকে কীভাবে ব্যাখ্যা করা যায় তা এখানে দেখুন
ওহে জুড

28

আপনি নেট START কমান্ডটি ব্যবহার করতে পারেন এবং তারপরে ERRORLEVEL এনভায়রনমেন্ট ভেরিয়েবল পরীক্ষা করতে পারেন, যেমন

net start [your service]
if %errorlevel% == 2 echo Could not start service.
if %errorlevel% == 0 echo Service started successfully.
echo Errorlevel: %errorlevel%

দাবি অস্বীকার: আমি এটিকে আমার মাথার উপরে থেকে লিখেছি, তবে আমি মনে করি এটি কার্যকর হবে।


8

কোডগুলি যাচাইয়ের পরিবর্তে এটিও কার্যকর হয়

net start "Apache tomcat" || goto ExitError

:End  
exit 0  

:ExitError  
echo An error has occurred while starting the tomcat services  
exit 1  

7

আমি এটির জন্য আমার ব্যক্তিগত ব্যাচ ফাইলটি তৈরি করেছি, আমার কিছুটা আলাদা তবে আপনি যথাযথ দেখতে দেখতে পরিবর্তন করতে নির্দ্বিধায়। আমি এটি কিছুক্ষণ আগে তৈরি করেছি কারণ আমি বিরক্ত হয়ে গিয়েছিলাম এবং লোকেরা ইনপুট শেষ করতে, শুরু করতে, থামাতে বা অটোতে সেট করতে সক্ষম হওয়ার একটি সহজ উপায় তৈরি করতে চেয়েছিল। এই বিএটি ফাইলটি কেবল আপনাকে পরিষেবার নামটি ইনপুট করার জন্য অনুরোধ করে এবং এটি আপনার জন্য বাকীটি করবে। আমি বুঝতে পারি নি যে তিনি এমন কোনও কিছু সন্ধান করছেন যা কোনও ত্রুটি বলেছিল, আমার অবশ্যই এই অংশটি ভুল করে পড়ে থাকতে হবে। যদিও সাধারণত লাইনটির শেষে >> output.txt ইনপুট করে এটি করা যায়।

% Var% হ'ল এটির নিজস্ব উপায় যাতে ব্যবহারকারীরা নিজের নিজের পরিষেবাটি ইনপুট করতে সক্ষম হবেন, প্রতিবার ব্যাট ফাইলটি পরিবর্তন করার পরিবর্তে আপনি যখন অন্য কোনও পরিষেবা শুরু / বন্ধ করতে চান তখনই।

আমি যদি ভুল হয় তবে যে কেউ এই বিষয়ে আমাকে সংশোধন করতে দ্বিধা বোধ করতে পারে।

@echo off
set /p c= Would you like to start a service [Y/N]?
  if /I "%c%" EQU "Y" goto :1
  if /I "%c%" EQU "N" goto :2
    :1  
    set /p var= Service name: 
:2 
set /p c= Would you like to stop a service [Y/N]?
  if /I "%c%" EQU "Y" goto :3
  if /I "%c%" EQU "N" goto :4
    :3  
    set /p var1= Service name:
:4
set /p c= Would you like to disable a service [Y/N]?
  if /I "%c%" EQU "Y" goto :5
  if /I "%c%" EQU "N" goto :6
    :5  
    set /p var2= Service name:
:6 
set /p c= Would you like to set a service to auto [Y/N]?
  if /I "%c%" EQU "Y" goto :7
  if /I "%c%" EQU "N" goto :10
    :7  
    set /p var3= Service name:
:10
sc start %var%
sc stop %var1%
sc config %var2% start=disabled
sc config %var3% start=auto

1
সাধারণত, কোডের উত্তরগুলির প্রশংসা করা হয় না। আপনি কি নিজের সমাধানটি বিস্তারিতভাবে বর্ণনা করতে পারেন বা কিছু ব্যাখ্যামূলক মন্তব্য যুক্ত করতে পারেন?
একটি ইয়ারইগ

2
আমি এটি কিছুক্ষণ আগে তৈরি করেছি কারণ আমি বিরক্ত হয়ে গিয়েছিলাম এবং লোকেরা ইনপুট শেষ করতে, শুরু করতে, থামাতে বা অটোতে সেট করতে সক্ষম হওয়ার একটি সহজ উপায় তৈরি করতে চেয়েছিল। এই বিএটি ফাইলটি কেবল আপনাকে পরিষেবার নামটি ইনপুট করার জন্য অনুরোধ করে এবং এটি আপনার জন্য বাকীটি করবে।
নাথানিয়াল উইলসন

6

থেকে রিটার্ন কোডগুলি ব্যবহার করা net startএবং net stopআমার কাছে সেরা পদ্ধতির মতো বলে মনে হচ্ছে। এটি একবার দেখুন: নেট স্টার্ট রিটার্ন কোডগুলি


2
লিঙ্কযুক্ত পৃষ্ঠাটি আর বিদ্যমান নেই। যেমনটি, এটি এখন আরও একটি মন্তব্য।
নিওলিস্ক

5

সিনট্যাক্স সবসময় আমাকে পায় .... তাই ...

আপনি উভয় মেশিনের অ্যাডমিন হয়ে থাকলে, প্রশাসক হিসাবে .bat চালনাবেন এবং মেশিনগুলি একই ডোমেনে থাকলে কীভাবে ব্যাচ ফাইলে একটি লাইন যুক্ত করা যায় যা দূরবর্তী পরিষেবাটি (অন্য মেশিনে) মেরে ফেলবে Here মেশিনের নামটি ইউএনসি ফর্ম্যাট \ মাইজারের অনুসরণ করে

sc \\ip.ip.ip.ip stop p4_1

এই ক্ষেত্রে ... p4_1 ছিল পরিষেবা নাম এবং প্রদর্শনের নাম উভয়ই, আপনি যখন পরিষেবা পরিচালকের পরিষেবার জন্য সম্পত্তিগুলি দেখেন। আপনাকে অবশ্যই পরিষেবার নামটি ব্যবহার করতে হবে।

আপনার সার্ভিস অপস নেশাগুলির জন্য ... আপনার যুক্তি কোড এবং মন্তব্য যুক্ত করতে ভুলবেন না! অর্থাত্ '4' যা 'পরিকল্পিত' সমান এবং মন্তব্য করে 'রক্ষণাবেক্ষণের জন্য সার্ভার থামানো'

sc \\ip.ip.ip.ip stop p4_1 4 Stopping server for maintenance

1
লগ ইন করার জন্য যদি আমাকে অন্য ব্যবহারকারীর আইডি এবং পাসওয়ার্ড ব্যবহার করতে হয় তবে আমি এটি কীভাবে করব?
ফ্র্যান্টথল

1
আপনি CMDঅন্য ব্যবহারকারীর / আইডি হিসাবে চালান runas /user:Domain\UserName cmdতারপর আপনার পাসওয়ার্ড লিখুন। সিএমডি নির্দিষ্ট ব্যবহারকারী অ্যাকাউন্ট হিসাবে চলমান শুরু করবে।
ব্যবহারকারী 4317867

4

আমরা ভাবতে চাই যে "নেট স্টপ" পরিষেবাটি বন্ধ করে দেবে। দুঃখের বিষয়, বাস্তবতা কালো এবং সাদা নয়। যদি পরিষেবাটি থামতে দীর্ঘ সময় নেয়, পরিষেবা বন্ধ হওয়ার আগে কমান্ডটি ফিরে আসবে। আপনি যদি ত্রুটিযুক্তি পরীক্ষা না করেন তবে আপনি জানেন না।

সমাধানটি লুপটি প্রদাহ হওয়া অবধি পরিষেবাটির অবস্থা সন্ধান না করা অবধি প্রতিটি বার লুপের বিরতি দিয়ে থামবে।

তবে আবার ...

আমি দেখতে পাচ্ছি প্রথম পরিষেবাটি থামতে অনেক দিন সময় নেয়, তারপরে পরবর্তী পরিষেবাগুলির জন্য "নেট স্টপ" ঠিক তেমন কিছুই করেনি। পরিষেবাদি পরিচালকগুলিতে পরিষেবাটি দেখুন এবং এর রাজ্যটি এখনও "শুরু" - "থামানো" তে কোনও পরিবর্তন নেই। তবুও আমি এসসিএম ব্যবহার করে ম্যানুয়ালি এই দ্বিতীয় পরিষেবাটি বন্ধ করতে পারি এবং এটি 3 বা 4 সেকেন্ডের মধ্যে বন্ধ হয়ে যায়।


3

অথবা আপনি এই সেন্টিমিডির সাহায্যে দূরবর্তী পরিষেবা শুরু করতে পারেন: sc \\<computer> start <service>


3

আমি উপরে উপরে জোনাসের উদাহরণ ব্যবহার করেছি এবং 0 থেকে 24 ত্রুটিযুক্তগুলির সম্পূর্ণ তালিকা তৈরি করেছি। অন্যান্য পোস্টটি সঠিক net startএবং এটি net stopকেবল errorlevelসাফল্যের জন্য 0 এবং ব্যর্থতার জন্য 2 ব্যবহার করে।

তবে এটি আমার পক্ষে কাজ করেছে:

net stop postgresql-9.1
if %errorlevel% == 2 echo Access Denied - Could not stop service
if %errorlevel% == 0 echo Service stopped successfully
echo Errorlevel: %errorlevel%

পরিবর্তন stopকরুন startএবং বিপরীতে কাজ করে।


3

ম্যানুয়াল সার্ভিস পুনঃসূচনা ঠিক আছে - পরিষেবাদি.এমএসসিতে "পুনঃসূচনা" বাটন রয়েছে তবে কমান্ড লাইনে এসসি এবং নেট উভয় কমান্ডেরই "পুনঃসূচনা" স্যুইচ অভাব আছে এবং সেমিটি / ব্যাট ফাইলে পুনরায় চালু হওয়ার পরে পরিষেবাটি বন্ধ হয়ে যায় এবং তত্ক্ষণাত শুরু হয়, কখনও কখনও এটি ত্রুটি পায় কারণ পরিষেবাটি এখনও বন্ধ হয়নি, জিনিসগুলি বন্ধ করতে কিছুটা সময় প্রয়োজন।

এটি ত্রুটি উত্পন্ন করতে পারে: স্কিপ স্টপ স্কার্ট

টাইমআউট সন্নিবেশ করা ভাল ধারণা, আমি পিং ব্যবহার করি (এটি প্রতি 1 সেকেন্ডে পিং করে): স্কিপ পিং লোকালহোস্ট -n 60 স্কার্ট স্টার্ট


2

ব্যাচ ব্যবহার করে সিস্টেম পুনরুদ্ধার শুরু করার জন্য এখানে উইন্ডোজ 10 কমান্ডটি রয়েছে:

sc config swprv start= Auto

আপনি এই আদেশগুলি পছন্দ করতে পারেন:

  • সিস্টেম পুনরুদ্ধারে স্বয়ংক্রিয় সূচনায় রেজিস্ট্রি মান পরিবর্তন করুন

    আরইগি "এইচকেএলএম \ সফ্টওয়্যার \ মাইক্রোসফ্ট, উইন্ডোজ এনটি \ কারেন্ট ভার্সন \ সিস্টেমরেস্টোর" / ভি অক্ষম এসআর / টি আরজিএইডডওয়ার্ড / ডি 0 / এফ যোগ করুন

  • একটি সিস্টেম পুনরুদ্ধার পয়েন্ট তৈরি করুন

    ডাব্লু.এম.এক্সি / নেমস্পেস: \ মূল \ ডিফল্ট পাথ সিস্টেমরেস্টোর কল ক্রিয়েটরিপয়েন্ট "

  • সিস্টেম পুনরুদ্ধার ডিস্কের ব্যবহার পরিবর্তন করুন

    vssadmin শেডস্টোরেজ আকারের জন্য / for = C: / অন = সি: / ম্যাক্সেসাইজ = 10%

উপভোগ করুন


1

SC পরিষেবাগুলি দিয়ে সবকিছু করতে পারে ... শুরু, থামানো, চেক, কনফিগার করা এবং আরও অনেক কিছু ...


1

কখনও কখনও আপনি স্টপ কাজ করে না জানতে পারেন ..

আমার এসকিউএল সার্ভার কখনও কখনও এটি করে। নিম্নলিখিত কমান্ডলাইনটি ব্যবহার করে এটি হত্যা করে। আপনার যদি সত্যই সত্যই আপনার স্ট্রিপটি এমন জিনিসগুলিকে মেরে ফেলার দরকার হয় যা থামে না। আমি এটি একটি শেষ রিসোর্ট হিসাবে এটি করতে চাই

taskkill /pid [pid number] /f

0

আমি সি # তে একটি উইন্ডোজ পরিষেবা লিখছি, স্টপ / আনইনস্টল / বিল্ড / ইনস্টল / স্টার্ট লুপটি খুব ক্লান্তিকর হয়ে উঠল। একটি মিনি স্ক্রিপ্ট লিখেছিল, এটিকে বলা reploy.batহয়েছিল এবং লুপটি স্বয়ংক্রিয় করতে আমার ভিজ্যুয়াল স্টুডিও আউটপুট ডিরেক্টরিতে (বিল্ট সার্ভিস এক্সিকিউটেবল রয়েছে এমন একটি) ফেলে দেওয়া হয়েছে।

শুধু এই 3 টি ভার্সন সেট করুন

servicename : এটি উইন্ডোজ পরিষেবা নিয়ন্ত্রণ প্যানেলে প্রদর্শিত হবে (Services.msc)

slndir : আপনার সমাধান (.sln) ফাইলযুক্ত ফোল্ডার (পুরো পাথ নয়)

binpath : বিল্ড থেকে নির্বাহযোগ্য পরিষেবাটির পুরো পথ (ফোল্ডার পাথ নয়)

দ্রষ্টব্য: msbuildকমান্ডটি কাজ করার জন্য এটি ভিজ্যুয়াল স্টুডিও বিকাশকারী কমান্ড লাইন থেকে চালানো দরকার ।

SET servicename="My Amazing Service"
SET slndir="C:dir\that\contains\sln\file"
SET binpath="C:path\to\service.exe"
SET currdir=%cd%

call net stop %servicename%
call sc delete %servicename%
cd %slndir%
call msbuild 
cd %bindir%
call sc create %servicename% binpath=%binpath%
call net start %servicename%
cd %currdir%

হতে পারে এটি কাউকে সহায়তা করে :)

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.