Win32 API из PowerShell 1.0

Иногда сталкиваешься с такими задачами, которые кажутся нерешаемыми с помощью скриптов. Для их выполнения нет ни стандартных утилит, ни COM-объектов. И даже в .NET отсутствуют необходимые методы.

Например недавно один мой знакомый захотел скрыть окно PowerShell при запуске скрипта. Это полезно в тех случаях когда используется графический интерфейс, и черное окно командной строки просто не нужно. Задача элементарно решается в PowerShell 2.0, где при вызове powershell.exe можно указать ему параметр командной строки –WindowStyle hidden, например:

powershell.exe -WindowStyle Hidden -file c:\scripts\myscript.ps1

Но PowerShell 2.0 пока не готов, и применять его в рабочем окружении просто опрометчиво. Что же можно сделать? Использовать для скрытия окна функцию Win32 API – SetWindowPos! Это конечно тоже гораздо проще сделать в PowerShell 2.0, с его новым командлетом Add-Type, но и в 1.0 мы не беспомощны😉

Напрямую PowerShell не может вызывать функции Win32 API, но зато может выполнять код c#, а уже тому под силу и API😉

#Создаём объект CodeProvider, для выполнения кода c# в нашем сценарии
$cp = new-object Microsoft.CSharp.CSharpCodeProvider
#В этой переменной можно задать параметры для выполнения кода
$cpar = New-Object System.CodeDom.Compiler.CompilerParameters
#Константы задающие действие функции SetWindowPos
$HideWindow = 0x0080
$ShowWindow = 0x0040

#С помощью конструкции "HereString" помещаем в переменную $Code код c#
#объявляющий функцию SetWindowPos
$Code = @"
using System;
using System.Runtime.InteropServices;
namespace Win32API
{
    public class Window
    {
        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, uint uFlags);
    }
}
"@

#Выполняем код c#
$cp.CompileAssemblyFromSource($cpar, $code)

#Получаем указатель (Handle) текущего окна PowerShell, используя специальную переменную $pid
$PSHandle = (Get-Process id $pid).MainWindowHandle

#Используем объявленную функцию из PowerShell
[Win32API.Window]::SetWindowPos($PSHandle, 0, 0, 0, 0, 0, $HideWindow)

Этот код можно поместить прямо в начало сценария использующего графический интерфейс, или в отдельный файл, например HideMe.ps1 и вызывать уже его.

Опубликовано в Learn, PowerShell, Practice, Scripting. Метки: , , . 3 комментария »

комментария 3 to “Win32 API из PowerShell 1.0”

  1. borismor Says:

    Консоль все-таки на секунду мелькает…
    Но пример интересный)

  2. Vadims Podans's blog - Подписывание скриптов PowerShell – практическая реализация (часть 2) Says:

    […] скрытия консоли честно взята из блога Васи Гусева: Win32 API из PowerShell 1.0. Данный метод работает как в PowerShell V2 CTP3, так и в PowerShell […]

  3. Как создать свой объект в PowerShell « Powershell for Windows Says:

    […] Аналогично можно сделать и в 1.0, но там вызывать C# код уже несколько сложнее. […]


Обсуждение закрыто.

%d такие блоггеры, как: