View previous topic :: View next topic |
Author |
Message |
Ciber SLasH
Joined: 20 Aug 2005 Posts: 209 Location: С.-Петербург
|
(Separately) Posted: Wed Jul 24, 2013 23:08 Post subject: Возможен ли запуск плагинов отдельно от TC? |
|
|
Приветствую всех!
Подскажите пожалуйста, возможен ли запуска плагинов из командной строки или из другой программы?
В частности хотел запустить SGViewer через rundll32:
rundll32 SGViewer.vlx,ListLoad 0 "D:\tmp\1.jpg"
Но так не работает.
Пробовал писать программу на Delphi с запуском:
Code: | program test;
uses Windows, Messages;
function ListLoad(wnd: HWND; path: PChar): HWND; stdcall; external 'SGViewer.wlx';
var
hTC, w: THandle;
path: PChar;
begin
hTC := FindWindow('ToolbarWindow32', 'Quick Launch');
//hTC := FindWindowEx(FindWindow('TTOTAL_CMD', nil), 0, 'TMyListBox', nil);
try
path := 'D:\tmp\1.jpg';
w := ListLoad(hTC, path);
Sleep(3000);
finally
//
end;
end.
|
так появляется окно SGViewer-а, но без картинки и после 3-х секунд исчезает.
Ещё пробовал запускать через winapiexec.exe:
Code: | winapiexec.exe" "%~dp0SGViewer.wlx"@ListLoad 0 "D:\tmp\1.bmp" |
Получаю сначала "Инструкция по адресу "0x04004096" обратилась к памяти по адресу "0x00d1fe00". Память не может быть "read"". Затем "Runtime error 216 at 040D61E4".
Что я делаю не так? |
|
Back to top |
|
|
Avada
Joined: 01 Aug 2008 Posts: 10261 Location: Россия, Саратов
|
(Separately) Posted: Thu Jul 25, 2013 00:03 Post subject: |
|
|
Ciber SLasH wrote: | Что я делаю не так? |
Не знаю, как насчёт представленных попыток запуска плагинов вне TC (специалистом в этой области не являюсь), но для обсуждения работы плагинов есть специальный подфорум, и называется он вовсе не "Общие вопросы".
Что касается способов вызова WLX-плагинов из командной строки и вне TC, то см., например, здесь (и далее по ссылкам).
Тема перенесена. _________________ Даже самая богатая фантазия
Не представит себе наши безобразия.
Last edited by Avada on Thu Jul 25, 2013 13:32; edited 1 time in total |
|
Back to top |
|
|
Ciber SLasH
Joined: 20 Aug 2005 Posts: 209 Location: С.-Петербург
|
(Separately) Posted: Thu Jul 25, 2013 11:55 Post subject: |
|
|
В ходе поиска решения проблемы, нашёл интересную программу WLX_Host, которая может отдельно от TC запустить WLX-плагин.
Изначально всё это задумывалось, чтобы можно было через SGViewer сконвертировать JPG в BMP. Нужно было это потому, что SGViewer на некоторых битых JPG-файлах показывает целую картинку, а другие вьюверы (протестировал XnView, IrfanView, ACDSee, FastStone Viewer, Picasa) - показывают битое изображение и совсем другое.
Примеры:
в настройках SGViewer-а стоят галочки "Использовать Intel JPEG library" и "Открывать любую графику с помощью LibGFL".
1.jpg
SGViewer:
Imagine (и остальные)
2.jpg
SGViewer:
Imagine (и остальные)
Решено было написать скрипт для Easy Macro Recorder:
Code: | KeyDown Tab
KeyUp Tab
Wait 10
KeyDown Ctrl
KeyDown s
Wait 10
KeyUp s
KeyUp Ctrl
Wait 500
KeyDown Enter
KeyUp Enter
Wait 2000
KeyDown Tab
KeyUp Tab
Wait 10
KeyDown DownArrow
KeyUp DownArrow
Wait 10 |
Скрипт работает, если файл открыт SGViewer-ом по Ctrl-Q.
Но вопрос с запуском со своей программы остался открытым (чисто для информации)...
Last edited by Ciber SLasH on Sun Jul 28, 2013 00:52; edited 2 times in total |
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Thu Jul 25, 2013 17:35 Post subject: |
|
|
Ciber SLasH, читай документацию по API плагинов и пиши свою программу для их загрузки, всё просто. Некоторые плагины могут использовать что-то помимо интерфейса и работать некорректно без тотала, но думаю, таких меньшинство.
Совершенно непонятно, почему в приведенном примере программы функция ListLoad принимает лишь 2 параметра, когда у неё их 3. Один только этот факт - серьезное нарушение, особенно с учётом того, что функция STDCALL, т.е. в стек ты кладешь 2 параметра, а она извлекает 3 - вылет по завершении функции неминуем.
Code: | HWND __stdcall ListLoad(HWND ParentWin,char* FileToLoad,int ShowFlags);
function ListLoad(ParentWin:thandle;FileToLoad:pchar;ShowFlags:integer):thandle; stdcall; |
Кроме того, первым параметром должен быть дескриптор окна, внутри которого плагин сможет создать своё окно (вряд ли окно тотала или панель инструментов быстрого запуска сойдут за такое окно), поэтому правильнее будет в своей программе сначала создать окно, а потом вызвать ListLoad и передать ей дескриптор созданного окна. Если пишешь на дельфе и размер программы не важен, можешь создать форму и передать её дескриптор. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
Ciber SLasH
Joined: 20 Aug 2005 Posts: 209 Location: С.-Петербург
|
(Separately) Posted: Thu Jul 25, 2013 18:16 Post subject: |
|
|
MVV wrote: | Совершенно непонятно, почему в приведенном примере программы функция ListLoad принимает лишь 2 параметра, когда у неё их 3. |
Прочёл в хэлпе "ShowFlags: You may ignore these parameters if they don't apply to your document type."
и подумал, что его можно опустить. Только сейчас допёр, что его можно игнорить в самом плагине, но в заголовке функции он должен присутствовать.
Загрузить файл в SGViewer смог, а вот при закрытии формы всё те же ошибки "память не может быть read", "run-time error".
Code: | implementation
{$R *.dfm}
function ListLoad(parentWnd: HWND; FileToLoad: PChar; ShowFlags: integer): HWND; stdcall; external 'SGViewer.wlx';
procedure ListCloseWindow(plugWnd: HWND); stdcall; external 'SGViewer.wlx';
const
LCP_FITTOWINDOW = 2;
var
hPlug: HWND;
procedure TForm1.FormActivate(Sender: TObject);
begin
try
hPlug := ListLoad(Form1.Handle, 'D:\tmp\1.bmp', LCP_FITTOWINDOW);
finally
//
end;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ListCloseWindow(hPlug);
end;
end.
|
|
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
|
Back to top |
|
|
Ciber SLasH
Joined: 20 Aug 2005 Posts: 209 Location: С.-Петербург
|
(Separately) Posted: Thu Jul 25, 2013 20:19 Post subject: |
|
|
В SGViewer есть ListCloseWindow - показывает FileInfo.
А закрыть по другому никак - у SGViewer-а нет закрывалок:
Даже, если не вызывать ListCloseWindow, а просто закрыть форму по крестику - ошибки те же. |
|
Back to top |
|
|
ProgMan13
Joined: 19 Aug 2009 Posts: 334
|
(Separately) Posted: Thu Jul 25, 2013 21:49 Post subject: |
|
|
MVV wrote: | Попробуй закрывать листер по кнопке, а не по закрытию формы, чтобы посмотреть, в какой момент ошибка - при закрытии листера или при закрытии приложения. |
Ciber SLasH wrote: | А закрыть по другому никак - у SGViewer-а нет закрывалок: |
1. У SGViewer есть закрывалка, если её включить в настройках.
2. MVV имел ввиду свою кнопку в приложении. Но надо использовать главное меню.
3. С последней программой у меня никаких ошибок. |
|
Back to top |
|
|
MVV
Joined: 15 Oct 2009 Posts: 4811 Location: Ростов-Дон
|
(Separately) Posted: Thu Jul 25, 2013 21:49 Post subject: |
|
|
Вызывать ListCloseWindow как раз обязательно, раз плагин её экспортирует. Заголовка у окна SGViewer естественно нет, это дочернее окно, и закрываться оно должно само после вызова ListCloseWindow.
Я говорил вот о чём: если выгрузить плагин, не закрывая приложения, будут ли ошибки? Попробуй загружать/выгружать плагин динамически через LoadLibrary/GetProcAddress/FreeLibrary. _________________ TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel… |
|
Back to top |
|
|
Ciber SLasH
Joined: 20 Aug 2005 Posts: 209 Location: С.-Петербург
|
(Separately) Posted: Thu Jul 25, 2013 22:40 Post subject: |
|
|
Ларчик просто открывался
Оказалось у меня вываливался в ошибки при закрытии SGViewer при статическом запуске библиотеки.
Перешёл на динамический запуск:
Code: | implementation
{$R *.dfm}
type
TListLoad = function (parentWnd: HWND; FileToLoad: PChar; ShowFlags: integer): HWND; stdcall;
TListCloseWindow = procedure (plugWnd: HWND); stdcall;
const
LCP_FITTOWINDOW = 2;
DLLName = 'SGViewer.wlx';
var
hPlug: HWND;
hDLL: THandle;
ListLoad: TListLoad;
ListCloseWindow: TListCloseWindow;
procedure TForm1.FormActivate(Sender: TObject);
begin
hDLL := LoadLibrary(DLLName);
@ListLoad := GetProcAddress(hDLL, 'ListLoad');
@ListCloseWindow := GetProcAddress(hDLL, 'ListCloseWindow');
hPlug := ListLoad(Form1.Handle, 'D:\tmp\1.bmp', LCP_FITTOWINDOW);
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ListCloseWindow(hPlug);
FreeLibrary(hDLL);
end;
|
ошибки исчезли.
Никакие найденные окна не хотят работать с SGViewer-ом, т.е. при вызове ListLoad с передачей дескриптора найденного окна (FindWindow('TTOTAL_CMD', nil)) - картинка не загружается. Нужно создавать своё окно и передавать его дескриптор в ListLoad.
PS: OS Win2003 Server Enterprice R2 SP2 Ru x86
PPS: rundll32 и winapiexec не помогли в данном вопросе.
PPPS: вопрос темы решён написание своей программы (но можно заюзать WLX_Host, который тоже прекрасно справился с заданием), благодарю MVV за наводку на динамический запуск плагина. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|