2015-06-04 6 views
5

पावरशेल के माध्यम से इंटरनेट एक्सप्लोरर के साथ कुछ करने के बारे में हाल ही में पूछे जाने वाले प्रश्नों का एक सेट था। उनमें से सभी को PowerShell से IE को लॉन्च करने के लिए कोड हैं, $ie=new-object -comobject InternetExplorer.Application के माध्यम से। समस्या यह है कि का उचित तरीका बंद करना है जिसमें $ie.quit() कॉलिंग शामिल है, पहले काम नहीं करता है - पहला, यदि वह आईई एक खुले टैब से अधिक होता, तो IE पूरी तरह से छोड़ नहीं जाता है और केवल टैब जो कि COM ऑब्जेक्ट से मेल खाता है, और दूसरा, इसमें केवल एक टैब होना चाहिए, खिड़की बंद हो जाती है लेकिन प्रक्रियाएं बनी रहती हैं।PowerShell से लॉन्च होने पर इंटरनेट एक्सप्लोरर को सही तरीके से कैसे बंद करें?

PS > get-process iexplore 

Handles NPM(K) PM(K)  WS(K) VM(M) CPU(s)  Id ProcessName 
------- ------ -----  ----- ----- ------  -- ----------- 
    352  31  7724  24968 142  0,58 3236 iexplore 
    228  24 22800  15384 156  0,19 3432 iexplore 

मैं कैसे बंद करने के लिए एक प्रक्रिया के माध्यम से New-Object -ComObject शुरू कर दिया पर तरीकों अनुसंधान करने के लिए कोशिश की है, और यह पाया है: How to get rid of a COMObject। उस COMObject का उदाहरण Excel.Application है, जो वास्तव में इरादे से व्यवहार करता है - quit() कॉलिंग विंडो को बंद करता है, और [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ex) निष्पादित करता है यदि $ex एक निर्मित COMObject एक्सेल प्रक्रिया को रोकता है। लेकिन इंटरनेट एक्सप्लोरर के साथ यह मामला नहीं है।

मैं भी इस सवाल का पाया है: How to get existing COM Object of a running IE जो खुले खिड़कियों की सूची के माध्यम से आईई से कनेक्ट करने के कोड प्रदान करता है, और दूसरी जगहों से प्रक्षेपित IE के एक हद तक काम करता है, लेकिन अगर COM वस्तु PowerShell के माध्यम से बनाई गई है, यह स्क्रिप्ट नहीं है पूरी तरह से आईई की प्रक्रियाओं को रोकने के लिए, अगर इस तरह के रूप में संशोधित सक्षम:

$shellapp = New-Object -ComObject "Shell.Application" 
$ShellWindows = $shellapp.Windows() 
for ($i = 0; $i -lt $ShellWindows.Count; $i++) 
{ 
if ($ShellWindows.Item($i).FullName -like "*iexplore.exe") 
    { 
    $ie = $ShellWindows.Item($i) 
    $ie.quit() 
    [System.Runtime.Interopservices.Marshal]::ReleaseComObject($ie) 
    } 
} 

IE के मामले में PowerShell के बाहर शुरू किया, प्रक्रियाओं बंद कर दिया जाता है, लेकिन IE के मामले में PowerShell के भीतर शुरू की, दो प्रक्रियाओं रहते हैं, और इस कोड को रिपोर्ट COM ऑब्जेक्ट तक पहुंचने के लिए कोई आईई विंडो नहीं मिली है, इसलिए आईई प्रक्रियाएं (अभी तक) रुकने में असमर्थ हैं।

तो, स्पष्ट रूप से अनाथ खिड़की रहित आईई प्रक्रियाओं तक पहुंचने के लिए कैसे और शानदार उन्हें रोकें? मुझे Get-Process iexplore | Stop-Process के बारे में पता है, लेकिन यह किसी भी और सभी आईई को रोक देगा, न केवल स्क्रिप्ट द्वारा लॉन्च किए गए, और अगर स्क्रिप्ट प्रशासक या SYSTEM पर चलाया जाता है, तो दूरस्थ डेस्कटॉप सर्वर कहें, हर किसी के आईई बंद हो जाएंगे।

पर्यावरण: ओएस विंडोज 7 एक्स 64, पावरशेल 4 (पीएस संस्करण 2 के ऊपर स्थापित), आईई 11 संस्करण 11.0.9600.176 9 1 (स्वचालित रूप से अपडेट किया गया)। आईई शुरू करने पर "होम पेज खोलें" पर सेट है, इसलिए कम से कम एक टैब हमेशा खुला रहता है।

उत्तर

4

सीधे शब्दों में Quit() विधि बुला सामान्य रूप से शान से Internet Explorer प्रक्रियाओं को समाप्त, चाहे वे iexplore.exe चला कर या PowerShell में एक COM वस्तु instantiating द्वारा बनाया गया था परवाह किए बिना के लिए पर्याप्त होना चाहिए।

प्रदर्शन:

 
PS C:\>$env:PROCESSOR_ARCHITECTURE 
AMD64 
PS C:\>(Get-WmiObject -Class Win32_OperatingSystem).Caption 
Microsoft Windows 8.1 Enterprise 
PS C:\>Get-Process | ? { $_.ProcessName -eq 'iexplore' } 
PS C:\>$ie = New-Object -COM 'InternetExplorer.Application' 
PS C:\>Get-Process | ? { $_.ProcessName -eq 'iexplore' } 

Handles NPM(K) PM(K)  WS(K) VM(M) CPU(s)  Id ProcessName 
------- ------ -----  ----- ----- ------  -- ----------- 
    352  20  4244  14164 176  0.05 3460 iexplore 
    407  32  6428  23316 182  0.23 5356 iexplore 

PS C:\>$ie.Quit() 
PS C:\>Get-Process | ? { $_.ProcessName -eq 'iexplore' } 
PS C:\> _ 

आप जो करने के लिए आप इस तरह उन के माध्यम से एक हैंडल आप चक्र कर सकते हैं की जरूरत नहीं है Internet Explorer प्रक्रियाओं अनाथ है:

(New-Object -COM 'Shell.Application').Windows() | Where-Object { 
    $_.Name -like '*Internet Explorer*' 
} | ForEach-Object { 
    $_.Quit() 
} 

पूरी तरह से पर होना करने के लिए सुरक्षित पक्ष आप Quit() पर कॉल करने के बाद COM ऑब्जेक्ट को छोड़ सकते हैं और फिर कचरा कलेक्टर को साफ करने के लिए प्रतीक्षा करें:

(New-Object -COM 'Shell.Application').Windows() | Where-Object { 
    $_.Name -like '*Internet Explorer*' 
} | ForEach-Object { 
    $_.Quit() 
    [Runtime.Interopservices.Marshal]::ReleaseComObject($_) 
} 

[GC]::Collect() 
[GC]::WaitForPendingFinalizers() 
+0

वैसे, मैंने अभी कोशिश की है, और मैंने एक दिलचस्प बात देखी है। जब मैं बनाया गया आईई COMObject के खिलाफ '[Runtime.Interopservices.Marshal] :: रिलीजकॉम ऑब्जेक्ट() 'को कॉल करता है तो यह एक गैर-शून्य मान देता है - यह स्पष्ट रूप से इंगित करता है कि सिस्टम में उस COM ऑब्जेक्ट के अधिक लिंक हैं। इसके अलावा मेरे मामले में तीन प्रक्रियाएं शुरू की गई हैं, दो नहीं। यह आईई संस्करण और ओएस संस्करण से भिन्न हो सकता है, इसलिए मैं अन्य पीसी पर फिर से जांच करूंगा। अब तक यह आईई 11 में पेश की गई बग या .NET 4.5 में एक बग जैसा दिखता है, यदि यह समस्या Win8.1 और IE11 (जो अभी उपलब्ध नहीं है) के साथ एक पीसी पर प्रकट होगी। – Vesper

+0

हम्म, ऐसा इसलिए हो सकता है क्योंकि ओएस x64 है, दो शेष प्रक्रियाएं एक x64 और एक x32 हैं, और केवल एक x32 एक परिणाम को x64 एक के शानदार स्टॉप में मारना। तो, यह वास्तव में आईई में स्पष्ट रूप से एक (अभी तक एक और) बग हो सकता है :) – Vesper

+0

@ वेस्पर मुझे शक होगा। मेरे उत्तर में प्रदर्शन 64-बिट विंडोज 8.1 से भी है (इंटरनेट एक्सप्लोरर 11 के साथ)। –

1
IE के लिए ComObject में चारों ओर एक संक्षिप्त दृष्टि डालकर

, ऐसा लगता है कि जब यह बनाई गई है, यह आप तरीकों कि IE के साथ बातचीत कर आसान उदाहरण Navigate() या ReadyState के लिए, के लिए एक सीधा इंटरफ़ेस देता है।

मैं एक संपत्ति है कि हो सकता है आप के लिए क्या देख रहे हैं और उस Parent

कॉलिंग $IE.Parent.Quit() लग रहा था PowerShell से छुटकारा पाने के उदाहरणों बनाया होगा लगता है की खोज की थी।

$IE = New-Object -ComObject InternetExplorer.Application 
Get-Process | Where-Object {$_.Name -Match "iex"} 

Handles NPM(K) PM(K)  WS(K) VM(M) CPU(s)  Id ProcessName 
------- ------ -----  ----- ----- ------  -- ----------- 
    291  20  5464  14156 200  0.16 1320 iexplore 
    390  30  5804  20628 163  0.14 5704 iexplore 

$IE.Parent.Quit() 
(Get-Process | Where-Object {$_.Name -Match "iex"}).GetType() 
You cannot call a method on a null-valued expression... 
+0

मैंने अभी कोशिश की है, कोई पासा नहीं, दो प्रक्रियाएं बनी रहती हैं। साथ ही, '$ ie.parent -eq $ यानी' सत्य लौटाता है, इसलिए यह 'पैरेंट' नहीं होना चाहिए। आपका ओएस, पीएस और आईई संस्करण क्या है? – Vesper

+0

मैंने देखा कि आपको प्रक्रियाओं की जांच करने से पहले इसे कुछ सेकंड या इससे पहले देना था – SomeShinyObject

+0

हमारे सेटअप के बीच अलग-अलग चीज ओएस संस्करण है। मैं 8.1 पर हूँ। शायद 7 में टूटा? – SomeShinyObject

2

मुझे COM ऑब्जेक्ट्स के साथ समान समस्याएं हैं जो छोड़ने() विधि का उपयोग समाप्त नहीं कर पाएंगी। Interopservices.marshall भी कई बार काम नहीं करता है। मेरा कामकाज: मैं कॉम ऑब्जेक्ट को कॉल करने से पहले सभी प्रोसेस की एक सूची प्राप्त करने के लिए एक प्रक्रिया प्राप्त करता हूं और ठीक बाद: इस तरह मेरे पास मेरे उदाहरण का पीआईडी ​​है। मेरी लिपि चलाने के बाद यह स्टॉप-प्रोसेस का उपयोग कर प्रक्रिया को मार देती है।

नहीं सबसे अच्छा तरीका यह करने के लिए, लेकिन कम से कम यह

+0

मुझे आश्चर्य है कि किस तरह के सिस्टम इस तरह व्यवहार करते हैं। शायद विंडोज़ या उनके COM मॉड्यूल के कुछ संस्करणों में एक अंतर्निहित बग है जिसे पीसी चश्मा से लिया जा सकता है। – Vesper

0

काम करता है वहाँ HKCU\Software\Microsoft\Internet Explorer\Main\FrameMerging रजिस्ट्री कुंजी कि IE विलय "फ्रेम" प्रक्रियाओं, explained here से बचाता है। मैंने इसे स्वयं नहीं किया है, लेकिन मुझे लगता है कि अगर आप इसे से पहले सेट करते हैं तो यह आपकी समस्या का समाधान कर सकता है, तो आप InternetExplorer.Application COM ऑब्जेक्ट को तुरंत चालू करते हैं।

अगर वह मदद नहीं करता है, तो निम्न कमांड लाइन के साथ एक नया आईई उदाहरण शुरू करने, पहले COM वस्तु बनाने के लिए (मुझे लगता है कि प्रयास नहीं किया है, या तो) का प्रयास करें:

  • iexplore.exe -noframemerging -private -embedding

इस आईई इंस्टेंस को COM सर्वर के रूप में उपलब्ध होने से पहले संभावित दौड़ स्थिति है, इसलिए आप ऑब्जेक्ट बनाने से पहले कुछ देरी डाल सकते हैं।

0

मैं Powershell कॉम के माध्यम से एक्सेल की शुरूआत के साथ एक प्रयोग करने की कोशिश की:

$x = New-Object -com Excel.Application 
$x.Visible = $True 
Start-Sleep 5 # make it stay visible for a little while 
$x.Quit() 
$x = 0 # Remove .NET's reference to com object 
[GC]::collect() # run garbage collection 

जैसे ही [जीसी] :: इकट्ठा() समाप्त प्रक्रिया taskmgr से गायब हो गया। यह मुझे समझ में आता है, क्योंकि (मेरी समझ में) एक COM क्लाइंट COM सर्वर के संदर्भ जारी करने के लिए ज़िम्मेदार है। इस मामले में .NET (एक रनटाइम कॉलबल रैपर के माध्यम से) COM क्लाइंट है।

स्थिति आईई के साथ अधिक जटिल हो सकती है, क्योंकि किसी दिए गए आईई प्रक्रिया से जुड़े अन्य टैब हो सकते हैं (और उस फ्रेम में विलय हो रहा है जो @ नोसेरेटियो उल्लेख है), लेकिन कम से कम यह इस संदर्भ से छुटकारा पायेगा पीएस लिपि

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