Когда мы пишем графическое приложение, бывает что требуется вызывать внешние программы и читать из STDOUT/STDERR.
С этим прекрасно справляется модуль IPC::Open3.
Однако, программу Вы написали, все работает, но Вы не хотите чтобы пользователь (или Вы) видели ненужное окно терминала.
Есть несколько вариантов его скрыть:
1. Запускать скрипт через wperl.exe, а не через perl.exe
2. ???
Рассмотрим программу
Вызывается команда dir, и выводится ее результат. (не обращайте внимания на кодировку).
Все работает, но если Вы запустите скрипт через wperl.exe, то при вызове open3 получите ошибку:
Проблема в том что, wperl не создает стандартные потоки (STDIN, STDOUT, STDERR).
Я долго ломал голову, как заставить работать программу. Пробовал вызывать WINAPI внутри тела программы, запускать через bat файл (работает, но не со всеми программами), однако решение оказалось наудивление простым.
Необходимо использовать функцию ShellExecute из shell32.dll c аттрибутом SW_HIDE.
Ниже код лоадера на Си.
Компилировать gcc из MinGW.
С этим прекрасно справляется модуль IPC::Open3.
Однако, программу Вы написали, все работает, но Вы не хотите чтобы пользователь (или Вы) видели ненужное окно терминала.
Есть несколько вариантов его скрыть:
1. Запускать скрипт через wperl.exe, а не через perl.exe
2. ???
Рассмотрим программу
use strict; use Tkx; use IPC::Open3; my $mw = Tkx::widget->new('.'); my $tw = $mw->new_text(); my $bt = $mw->new_ttk__button( -text => 'dir', -command => sub { my($rdr, $pid); $pid = open3( undef, $rdr, undef, 'dir' ); $tw->insert( 'end', do { local $/; <$rdr> } ); }, ); Tkx::pack( $tw ); Tkx::pack( $bt ); Tkx::MainLoop;
Вызывается команда dir, и выводится ее результат. (не обращайте внимания на кодировку).
Все работает, но если Вы запустите скрипт через wperl.exe, то при вызове open3 получите ошибку:
open3: Can't call method "close" on an undefined value at C:/perl5.8/lib/IPC/Open3.pm line 368. open3: Can't call method "close" on an undefined value at C:/perl5.8/lib/IPC/Open3.pm line 368.
Проблема в том что, wperl не создает стандартные потоки (STDIN, STDOUT, STDERR).
Я долго ломал голову, как заставить работать программу. Пробовал вызывать WINAPI внутри тела программы, запускать через bat файл (работает, но не со всеми программами), однако решение оказалось наудивление простым.
Необходимо использовать функцию ShellExecute из shell32.dll c аттрибутом SW_HIDE.
Ниже код лоадера на Си.
#include <stdio.h> #include <windows.h> static char *ldr_file = "app.pl"; static char *ldr_path = ""; int main(int argc, char *argv[]) { int code; LoadLibrary("shell32.dll"); code = (int) ShellExecute(NULL, "open", ldr_file, ldr_path, NULL, SW_HIDE); if (code <= 32) { char buf[200]; sprintf(buf, "Cannot run application. Code: %d", code); MessageBox( NULL, buf, "Dynld Error", MB_ICONERROR | MB_OK ); } return code; }
Компилировать gcc из MinGW.
gcc -mwindows loader.c -o loader.exe