<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; VBScript: запуск файлов ассоциированным приложением]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=982</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=982&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «VBScript: запуск файлов ассоциированным приложением».]]></description>
		<lastBuildDate>Sat, 22 Dec 2007 17:16:36 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[VBScript: запуск файлов ассоциированным приложением]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=7283#p7283</link>
			<description><![CDATA[<p>Автор данной статьи - <strong>alexii</strong>.</p><p>Некоторые особенности методов <strong>DoIt</strong>, <strong>InvokeVerb</strong>, <strong>InvokeVerbEx</strong>, <strong>ShellExecute</strong> объекта автоматизации <strong>Shell.Application</strong> и метода <strong>Run</strong> объекта автоматизации <strong>WScript.Shell</strong>.</p><p>При опосредованном запуске приложений посредством методов <strong>DoIt</strong>, <strong>InvokeVerb</strong>, <strong>InvokeVerbEx</strong>, <strong>ShellExecute</strong> объекта автоматизации <strong>Shell.Application</strong> и метода <strong>Run</strong> объекта автоматизации <strong>WScript.Shell</strong> может возникнуть ситуация, что методы не будут работать как ожидается. Это может быть связано с тем, что скрипт завершает свою работу, прежде чем методы успевают отработать. Обычно подобное наблюдается, когда эти методы используются для опосредованного запуска «тяжёлых» приложений.</p><p><strong>Демонстрация</strong>:</p><p>В папке <strong>C:\ShellExecute Demonstration</strong> находятся:<br />— текстовый файл <strong>Sample.txt</strong>;<br />— файлы <em>Microsoft Word</em> <strong>Sample.doc</strong>, <strong>Sample2.doc</strong> и <strong>Sample3.doc</strong>;<br />— файлы <em>Microsoft Excel</em> <strong>Sample.xls</strong> и <strong>Sample2.xls</strong>.<br /></p><div class="codebox"><pre><code>Option Explicit

Dim objShell

LogOut WScript.ScriptName &amp; &quot; started.&quot;

Set objShell = WScript.CreateObject(&quot;Shell.Application&quot;)

LogOut &quot;Try run WinWord.exe by ShellExecute method&quot;
objShell.ShellExecute &quot;Sample.doc&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1

LogOut &quot;Try run Notepad.exe by ShellExecute method&quot;
objShell.ShellExecute &quot;Sample.txt&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1

Set objShell = Nothing

LogOut WScript.ScriptName &amp; &quot; finished.&quot;

WScript.Quit 0

&#039;=============================================================================
Function LogOut(varValue)
    WScript.Echo CStr(Now()) &amp; &quot; : &quot; &amp; CStr(varValue)
End Function
&#039;=============================================================================</code></pre></div><p>В большинстве случаев строка скрипта<br /></p><div class="codebox"><pre><code>objShell.ShellExecute &quot;Sample.txt&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1</code></pre></div><p>отработает корректно и откроет приложение <em>Notepad.exe</em> c файлом <strong>C:\ShellExecute Demonstration\Sample.txt</strong>, а при исполнении строки<br /></p><div class="codebox"><pre><code>objShell.ShellExecute &quot;Sample.doc&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1</code></pre></div><p>может произойти:<br />— будет открыто приложение <em>WinWord.exe</em> с файлом <strong>C:\ShellExecute Demonstration\Sample.doc</strong>;<br />— будет открыто приложение <em>WinWord.exe</em>;<br />— будет запущен процесс <em>WinWord.exe</em> (окно приложения не появляется);<br />— ничего не произойдёт;</p><p>Если после вызова этих методов добавить в скрипт паузу некоторой длительности, то указанные методы отработают корректно (необходимое значение времени приостановки работы скрипта может зависеть от многих факторов, как-то: общего быстродействия компьютера, наличия антивируса и включённых эвристик проверки, размера открываемого файла, дефрагментации диска):<br /></p><div class="codebox"><pre><code>Option Explicit

Dim objShell

LogOut WScript.ScriptName &amp; &quot; started.&quot;

Set objShell = WScript.CreateObject(&quot;Shell.Application&quot;)

LogOut &quot;Try run WinWord.exe by ShellExecute method&quot;
objShell.ShellExecute &quot;Sample.doc&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1

LogOut &quot;Try run Notepad.exe by ShellExecute method&quot;
objShell.ShellExecute &quot;Sample.txt&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1

&#039; Приостановка работы скрипта на 10 секунд
WScript.Sleep 10000

Set objShell = Nothing

LogOut WScript.ScriptName &amp; &quot; finished.&quot;

WScript.Quit 0

&#039;=============================================================================
Function LogOut(varValue)
    WScript.Echo CStr(Now()) &amp; &quot; : &quot; &amp; CStr(varValue)
End Function
&#039;=============================================================================</code></pre></div><p><strong>Замечание</strong>: обратите внимание, что окно более «легкого» приложения <em>Notepad.exe</em> может появиться первым, несмотря на то, что опосредованно запускается вторым.</p><p>Подобным образом можно попробовать добиться корректной работы во всех перечисленных методах:<br /></p><div class="codebox"><pre><code>Option Explicit

Dim objShell
Dim objNameSpace
Dim objFolderItem
Dim objVerb

Dim objWshShell

LogOut WScript.ScriptName &amp; &quot; started.&quot;

Set objShell = WScript.CreateObject(&quot;Shell.Application&quot;)

LogOut &quot;Try run WinWord.exe by ShellExecute method&quot;
objShell.ShellExecute &quot;Sample.doc&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1

Set objNameSpace = objShell.NameSpace(&quot;C:\ShellExecute Demonstration&quot;)

LogOut &quot;Try run WinWord.exe by InvokeVerb method&quot;
Set objFolderItem = objNameSpace.ParseName(&quot;Sample2.doc&quot;)
objFolderItem.InvokeVerb

LogOut &quot;Try run WinWord.exe by InvokeVerbEx method&quot;
Set objFolderItem = objNameSpace.ParseName(&quot;Sample3.doc&quot;)
objFolderItem.InvokeVerbEx

LogOut &quot;Try run Excel.exe by DoIt method&quot;
Set objFolderItem = objNameSpace.ParseName(&quot;Sample.xls&quot;)

For Each objVerb In objFolderItem.Verbs()
    If objVerb.Name = &quot;&amp;Открыть&quot; Then
        objVerb.DoIt
        
        Exit For
    End If
Next

LogOut &quot;Try run Excel.exe by Run method&quot;
Set objWshShell = WScript.CreateObject(&quot;WScript.Shell&quot;)
objWshShell.Run &quot;&quot;&quot;&quot; &amp; &quot;C:\ShellExecute Demonstration\Sample2.xls&quot; &amp; &quot;&quot;&quot;&quot;

LogOut &quot;Try run Notepad.exe by ShellExecute&quot;
objShell.ShellExecute &quot;Sample.txt&quot;, &quot;&quot;, &quot;C:\ShellExecute Demonstration&quot;, &quot;&quot;, 1

&#039; Приостановка работы скрипта на 20 секунд
WScript.Sleep 20000

Set objWshShell = Nothing

Set objVerb = Nothing
Set objFolderItem = Nothing
Set objNameSpace = Nothing
Set objShell = Nothing

LogOut WScript.ScriptName &amp; &quot; finished.&quot;

WScript.Quit 0

&#039;=============================================================================
Function LogOut(varValue)
    WScript.Echo CStr(Now()) &amp; &quot; : &quot; &amp; CStr(varValue)
End Function
&#039;=============================================================================</code></pre></div><p>Ещё одна особенность библиотеки <strong>SHELL32.dll</strong> проявляется в следующем примере:<br /></p><div class="codebox"><pre><code>Option Explicit

Dim objShell
Dim objNameSpace
Dim objFolderItem

Set objShell = WScript.CreateObject(&quot;Shell.Application&quot;)
Set objNameSpace = objShell.NameSpace(&quot;C:\ShellExecute Demonstration&quot;)
Set objFolderItem = objNameSpace.ParseName(&quot;Sample.txt&quot;)

objFolderItem.InvokeVerb &quot;properties&quot;

WScript.Sleep 5000

Set objFolderItem = Nothing
Set objNameSpace = Nothing
Set objShell = Nothing

WScript.Quit 0</code></pre></div><p>Данный скрипт отображает окно свойств файла <strong>C:\ShellExecute Demonstration\Sample.txt</strong> (такое же, которое появится при выборе пункта <strong>Свойства</strong> контекстного меню файла в Проводнике). После того, как скрипт завершит свою работу, это окно будет автоматически закрыто. Если же убрать команду<br /></p><div class="codebox"><pre><code>WScript.Sleep 5000</code></pre></div><p>это окно не отобразится вовсе.</p><p>Примечание от <strong>The gray Cardinal</strong>: похоже, вышеописанные методы <strong>DoIt</strong>, <strong>InvokeVerb</strong>, <strong>InvokeVerbEx</strong>, <strong>ShellExecute</strong> запускаются асинхронно. Если взять код, отвечающий за организацию паузы, и переставить его <strong>после</strong> очистки объектов, то ничего не изменится — всё по-прежнему будет работать. Поэтому, похоже, проблема заключается даже не в безвременном &quot;R.I.P.&quot; объектов, а именно в завершении всего скрипта.</p>]]></description>
			<author><![CDATA[null@example.com (The gray Cardinal)]]></author>
			<pubDate>Sat, 22 Dec 2007 17:16:36 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=7283#p7283</guid>
		</item>
	</channel>
</rss>
