Копирование экрана консоли в системный буфер

В предыдущем примере мы рассмотрели, как создать цветную копию консоли в формате HTML и RTF. Однако вывод этого сценария нельзя немедленно использовать для вставки в приложения для веб или обработки текстов. Чтобы вставить его в статью в формате MS Word, следует сделать несколько шагов: создать строку RTF, сохранить ее в файл RTF, затем открыть файл в MS Word, скопировать его содержимое, и наконец вставить его в документ. Нельзя ли сократить пару шагов: запустить сценарий, который копирует экран консоли в системный буфер, а потом вставить результат в MS Word? Действительно мы можем это сделать. Но чтобы реализовать такую возможность, нам надо изучить, как работать с буфером обмена в Windows PowerShell.

Ниже приведены основы для тех, кто не слишком хорошо знает механизм работы с буфером обмена. Когда вы копируете что либо из оконного приложения, приложение создает объект данных, который содержит ссылку или сериализованную копию выбранных данных. Данные могут сохраняться в различных форматах, чтобы повысить шанс того, что целевое приложение, требований которого к формату вы можете не знать, сможет получить их. Например, приложение Windows Mail в Vista может получать данные, представленные в формате текста или HTML, но не понимает RTF. Microsoft Word, с другой стороны, при вставке будет рад получить текст или RTF, но не сможет работать с HTML. Блокнот возьмет только текст, игнорируя и HTML, и RTF. Поэтому при копировании форматированного текста обычно полезно помещать данные в буфер как минимум в трех популярных форматах – Текст, HTML и RTF. Самый простой способ это сделать – использовать класс System.Windows.Forms.Clipboard, который является частью .NET Framework.

Короче говоря, вот вам пример:

# Load System.Windows.Forms assembly.
$null = [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

# Create a data object.
$dataObject = New-Object windows.forms.dataobject

# Add generated strings to the data object.
$dataObject.SetData([Windows.Forms.DataFormats]::UnicodeText, $true, $text)
$dataObject.SetData([Windows.Forms.DataFormats]::RTF, $true, $rtf)
$dataObject.SetData([Windows.Forms.DataFormats]::HTML, $true, $html)

# Place the data object in the system clipboard.
[Windows.Forms.Clipboard]::SetDataObject($dataObject, $true)

Учтите, что работа с буфером обмена системы имеет одно важное ограничение. Класс Clipboard можно использовать только из потоков, которые переключены в однопоточный режим (single thread apartment, STA). ISE Windows Powershell запускается в режиме STA по умолчанию, но стандартный режим работы консоли Windows PowerShell – MTA. Чтобы обойти это ограничение в консоли Windows PowerShell, вам следует запустить консоль Windows PowerShell с переключателем -sta, который доступен в версии CTP3 Windows PowerShell V2.

В прикрепленном сценарии мы повторно используем код из сообщений Захват экрана консоли и Захват экрана консоли с синтаксической подсветкой в HTML и RTF для захвата буфера экрана консоли и преобразования его в три базовых текстовых формата (Текст Unicode, HTML и RTF). Затем мы помещаем результат в системный буфер, как показано в фрагменте кода выше.

Для использования этого сценария необходимо установить на вашу машину PowerShell V2 CTP3. Для выполнения сценария запустите консоль Windows PowerShell в режиме STA или запустите сценарий, используя командную строку powershell – sta – command < scriptpath> .

 Windows PowerShell V2 (Community Technology Preview - Features Subject to Change)                                       
Copyright (C) 2008 Microsoft Corporation. All rights reserved.                                                          
                                                                                                                        
PS C:\Users\Vladimir> cd E:\MyScripts                                                                                   
PS E:\MyScripts>                                                                                                        
PS E:\MyScripts> .\Copy-Console.ps1                                                                                     
The script cannot be run in MTA mode.                                                                                   
Start Windows Powershell with -STA switch, or rerun the script using powershell -sta -command <scriptpath>.             
Example:                                                                                                                
    powershell -noprofile -sta -command d:\myscripts\Copy-Console.ps1                                                   
PS E:\MyScripts> powershell -noprofile -sta -command e:\myscripts\Copy-Console.ps1                                      
The console screen has been copied to system clipboard.                                                                 
You can now paste it to any application that supports text, HTML or RTF pasting.                                        
PS E:\MyScripts>                                                                                                        

Результаты выполнения сценария приведены выше. Я просто запустил сценарий и перенес результаты в редактор сообщений в блогах.

Учтите, что команду powershell sta commandCopy - Console . ps1 можно запустить не только из консоли Windows PowerShell, но и из обычной консоли CMD. Это означает, что вы можете использовать этот сценарий для захвата цветного вывода из любого консольного приложения Windows.

 Microsoft Windows [Version 6.0.6001]                                                                                    
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.                                                         
                                                                                                                        
C:\Windows\System32>cd WindowsPowerShell                                                                                
                                                                                                                        
C:\Windows\System32\WindowsPowerShell>dir                                                                               
 Volume in drive C has no label.                                                                                        
 Volume Serial Number is D67B-C7C5                                                                                      
                                                                                                                        
 Directory of C:\Windows\System32\WindowsPowerShell                                                                     
                                                                                                                        
09/08/2008  07:08 PM    <DIR>          .                                                                                
09/08/2008  07:08 PM    <DIR>          ..                                                                               
01/10/2009  05:24 PM    <DIR>          v1.0                                                                             
               0 File(s)              0 bytes                                                                           
               3 Dir(s)  55,533,215,744 bytes free                                                                      
                                                                                                                        
C:\Windows\System32\WindowsPowerShell>powershell -noprofile -sta -command e:\myscripts\Copy-Console.ps1                 

Не скучайте!

Владимир Аверкин (Vladimir Averkin)

Windows PowerShell team

Перевод: Виктор Горбунков