2012-01-12 14 views
19

नोब सहायता कृपया शुरू करें। मैं एक स्क्रिप्ट लिखने की कोशिश कर रहा हूं जो जांच करेगा कि कोई प्रक्रिया चल रही है या नहीं, और यदि नहीं, तो इसे शुरू करें। अगर प्रक्रिया चल रही है, तो इसे कुछ भी नहीं करना चाहिए। मैं अब तक निम्न के साथ आया हूं लेकिन यह प्रक्रिया का एक नया उदाहरण शुरू कर रहा है चाहे वह पहले से चल रहा था या नहीं। किसी भी मदद की सराहना की है।पावरहेल - यदि कोई प्रक्रिया नहीं चल रही है, तो इसे

$Prog = "C:\utilities\prog.exe" 
$Running = Get-Process prog -ErrorAction SilentlyContinue 
$Start = ([wmiclass]"win32_process").Create($Prog) 
if($Running -eq $null) 
{$Start} 
else 
{} 

उत्तर

24

सबसे पहले, यहां आपके कोड में क्या गलत है। अपने कोड में, प्रक्रिया से पहले आप का मूल्यांकन कि क्या आपके कार्यक्रम पहले से ही चल रहा है बनाई गई है

$Prog = "C:\utilities\prog.exe" 
$Running = Get-Process prog -ErrorAction SilentlyContinue 
$Start = ([wmiclass]"win32_process").Create($Prog) # the process is created on this line 
if($Running -eq $null) # evaluating if the program is running 
{$Start} 

यह में {} यह लपेटकर द्वारा कोड है कि अपने कोड में आगे मूल्यांकन किया जाना चाहिए का एक ब्लॉक बनाने के लिए संभव है (एक scriptblock):

$Prog = "C:\utilities\prog.exe" 
$Running = Get-Process prog -ErrorAction SilentlyContinue 
$Start = {([wmiclass]"win32_process").Create($Prog)} 
if($Running -eq $null) # evaluating if the program is running 
{& $Start} # the process is created on this line 

हालांकि, अगर आप को हल करने के लिए एक छोटी एक लाइनर के लिए देख रहे हैं आपकी समस्या:में

if (! (ps | ? {$_.path -eq $prog})) {& $prog} 
+0

स्पष्ट व्याख्या के लिए ठीक है धन्यवाद। – Charlotte

+0

मुझे नहीं पता कि आपका समाधान समस्या का समाधान कैसे करेगा। लाइन '$ प्रारंभ = ... 'हर बार प्रक्रिया शुरू कर देगी। मैं परीक्षण चला गया कोड और उसी प्रक्रिया के गुणक शुरू किया गया था। (एक प्रोग्राम के साथ परीक्षण करना सुनिश्चित करें जो स्वयं के कई उदाहरणों को अनुमति देता है) – LosManos

+0

हाय @ लॉसमेनोस, क्या यह संभव है कि आप {} (scriptblock) भूल गए? –

3
$path = "C:\utilities\prog.exe"   
$list = get-process | where-object {$_.Path -eq $path }  
if ($list -eq $null) { start-process -filepath $path } 

या

$path = "C:\utilities\prog.exe" 
get-process | where-object {$_.Path -eq $path } | measure-object | where-object { $_.Count -eq 0} | foreach-object {start-process -filepath $path } 

यह आपको अगर बयान और एक चर घोषणा बचत होगी।

  1. प्राप्त प्रक्रियाओं
  2. पथ आप
  3. उपाय का प्रयोग वस्तु में रुचि रखते सूची के बारे में आँकड़े प्राप्त करने के लिए कर रहे हैं के साथ लोगों को उठाओ आप
  4. जारी रखें: यह रूप में अच्छी तरह एक एक पंक्ति आदेश हो सकता है पाइपिंग केवल तभी आँकड़े की गिनती मान 0
  5. प्रारंभ प्रक्रिया
  6. है

मत अंत में foreach आप बंद कर दिया। माप वस्तु केवल एक आइटम लौटाएगी जहां एक या शून्य लौटाएगा। परिणाम केवल शून्य होने पर निष्पादित करने के लिए किया जाता है। यह एक और प्रक्रिया शुरू नहीं करेगा। :)

+1

माप/गणना का उपयोग करने की कोई आवश्यकता नहीं है। 0 का मान $ false के रूप में माना जाता है, शून्य शून्य $ true है। व्यावहारिक कार्यान्वयन के लिए जोन-जेड के उत्तर के अंत को देखें। – x0n

+0

आप सही हैं। टिप के लिए धन्यवाद; मैंने कुछ नया सीखा। जोन-जेड का अंतिम उदाहरण सबसे अच्छा लगता है। –

9

10, प्रक्रिया नाम तर्क फ़ाइल एक्सटेंशन के बिना निष्पादन योग्य का नाम होना चाहिए। $Prog = "prog" के साथ $Prog = "C:\utilities\prog.exe" को प्रतिस्थापित करने का प्रयास करें।

मेरी राय में, यदि आपने using the Where-Object cmdlet को प्रक्रिया को फ़िल्टर किया है तो आपकी स्क्रिप्ट अधिक पठनीय होगी।

$programName = "prog" 
$isRunning = (Get-Process | Where-Object { $_.Name -eq $programName }).Count -gt 0 

if ($isRunning) 
# ... 
else 
# ... 

इस तरह आप -ErrorAction SilentlyContinue तर्क से छुटकारा पा सकते हैं, जो किसी को भ्रमित कर सकते हैं, जो तथ्य यह है कि Get-Processएक त्रुटि अगर यह एक प्रक्रिया नहीं मिल सकता है फेंकता है के बारे में पता नहीं है: यहाँ एक उदाहरण है निर्दिष्ट नाम के साथ।

+0

ठीक है मैंने ऐसा करने के बारे में सोचा नहीं था, धन्यवाद! – Charlotte

+0

+1 क्योंकि मेरी गलती ने मुझे यहां ले जाया था कि मैं विस्तार भी शामिल था। – rbwhitaker

5

ध्यान रखें कि PowerShell ऑब्जेक्ट्स को संभालता है और न केवल टेक्स्ट। सामान्य बैच फ़ाइलों में आप एक स्ट्रिंग के लिए एक चर सेट करें और फिर सकता है सिर्फ एक आदेश के रूप में उपयोग:

set Foo=dir /b 
%Foo% 

... इस PowerShell में काम नहीं करता।इस प्रकार $Start का आपका कार्य पहले से ही नई प्रक्रिया बनाता है क्योंकि = के बाद कमांड चलाया जाता है और इसका परिणाम $Start पर दिया जाता है।

इसके अलावा आप चीजों को जटिलता से जटिल बना रहे हैं। मैं बजाय निम्नलिखित सुझाव चाहते हैं: एक वस्तु (जो $true का मूल्यांकन)

$Running = Get-Process prog -ErrorAction SilentlyContinue 
if (!$Running) { Start-Process C:\utilities\prog.exe } 

Get-Process के बाद रिटर्न या $null (जो $false का मूल्यांकन) आप ऊपर दिखाए गए तरह की जांच को आसान बनाने में कर सकते हैं। इसे टाइप कर्केशन कहा जाता है, क्योंकि if कथन से बूलियन मान और $true और $false के रूप में माना जाएगा कि नियमों के ऊपर के मामलों में बहुत ही संगत हैं। और यह अच्छी तरह से पढ़ता है।

मैंने नई प्रक्रिया बनाने के लिए डब्लूएमआई के बजाय Start-Process सेमीडलेट का भी उपयोग किया।

if (!$Running) { C:\utilities\prog.exe } 

यदि आवेदन एक सांत्वना आवेदन नहीं है (और जब तक यह बाहर निकालता है PowerShell स्क्रिप्ट को ब्लॉक कर देगा इस प्रकार): तुम भी निम्न का उपयोग कर सकता है। पावरशेल अभी भी एक खोल है, इसलिए प्रोग्राम शुरू करना कुछ अच्छी तरह से काम करता है :-)

आप $running वैरिएबल को भी इनलाइन कर सकते हैं, लेकिन मुझे लगता है कि आप जो भी करते हैं उसे स्पष्ट करने के लिए एक टिप्पणी होगी।

+0

आपने सच्चे/झूठे नियमों का जिक्र किया है ... जेफरी द्वारा उन्हें समझने में मदद करने के लिए एक अच्छी छोटी पोस्ट मिल सकती है [यहां] (http://blogs.msdn.com/b/powershell/archive/2006/12/24/ बूलियन मान और operators.aspx)। –

+0

मुझे लगता है कि इसके बारे में सबसे भ्रमित हिस्सा एक-तत्व सरणी के साथ नियम है, लेकिन यदि आप '@ (...) 'जैसी चीजों पर विचार करते हैं तो वे समझ में आते हैं और इस प्रकार वे अपेक्षाकृत अपेक्षाकृत व्यवहार करते हैं :-) – Joey

संबंधित मुद्दे