Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Возможен ли запуск плагинов отдельно от TC?

 
Post new topic   Reply to topic    Total Commander Forum Index -> Плагины Total Commander printer-friendly view
View previous topic :: View next topic  
Author Message
Ciber SLasH



Joined: 20 Aug 2005
Posts: 209
Location: С.-Петербург

Post (Separately) Posted: Wed Jul 24, 2013 23:08    Post subject: Возможен ли запуск плагинов отдельно от TC? Reply with quote

Приветствую всех!
Подскажите пожалуйста, возможен ли запуска плагинов из командной строки или из другой программы?
В частности хотел запустить 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
View user's profile Send private message
Avada



Joined: 01 Aug 2008
Posts: 10261
Location: Россия, Саратов

Post (Separately) Posted: Thu Jul 25, 2013 00:03    Post subject: Reply with quote

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
View user's profile Send private message
Ciber SLasH



Joined: 20 Aug 2005
Posts: 209
Location: С.-Петербург

Post (Separately) Posted: Thu Jul 25, 2013 11:55    Post subject: Reply with quote

В ходе поиска решения проблемы, нашёл интересную программу 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
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4811
Location: Ростов-Дон

Post (Separately) Posted: Thu Jul 25, 2013 17:35    Post subject: Reply with quote

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
View user's profile Send private message
Ciber SLasH



Joined: 20 Aug 2005
Posts: 209
Location: С.-Петербург

Post (Separately) Posted: Thu Jul 25, 2013 18:16    Post subject: Reply with quote

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
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4811
Location: Ростов-Дон

Post (Separately) Posted: Thu Jul 25, 2013 19:11    Post subject: Reply with quote

А в SGViewer есть ListCloseWindow? Может, надо вызывать DestroyWindow?
Попробуй закрывать листер по кнопке, а не по закрытию формы, чтобы посмотреть, в какой момент ошибка - при закрытии листера или при закрытии приложения.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…
Back to top
View user's profile Send private message
Ciber SLasH



Joined: 20 Aug 2005
Posts: 209
Location: С.-Петербург

Post (Separately) Posted: Thu Jul 25, 2013 20:19    Post subject: Reply with quote

В SGViewer есть ListCloseWindow - показывает FileInfo.
А закрыть по другому никак - у SGViewer-а нет закрывалок:

Даже, если не вызывать ListCloseWindow, а просто закрыть форму по крестику - ошибки те же.
Back to top
View user's profile Send private message
ProgMan13



Joined: 19 Aug 2009
Posts: 334

Post (Separately) Posted: Thu Jul 25, 2013 21:49    Post subject: Reply with quote

MVV wrote:
Попробуй закрывать листер по кнопке, а не по закрытию формы, чтобы посмотреть, в какой момент ошибка - при закрытии листера или при закрытии приложения.
Ciber SLasH wrote:
А закрыть по другому никак - у SGViewer-а нет закрывалок:

1. У SGViewer есть закрывалка, если её включить в настройках.
2. MVV имел ввиду свою кнопку в приложении. Но надо использовать главное меню.
3. С последней программой у меня никаких ошибок.
Back to top
View user's profile Send private message
MVV



Joined: 15 Oct 2009
Posts: 4811
Location: Ростов-Дон

Post (Separately) Posted: Thu Jul 25, 2013 21:49    Post subject: Reply with quote

Вызывать ListCloseWindow как раз обязательно, раз плагин её экспортирует. Заголовка у окна SGViewer естественно нет, это дочернее окно, и закрываться оно должно само после вызова ListCloseWindow.

Я говорил вот о чём: если выгрузить плагин, не закрывая приложения, будут ли ошибки? Попробуй загружать/выгружать плагин динамически через LoadLibrary/GetProcAddress/FreeLibrary.
_________________
TCFS2 + TCFS2Tools: Полноэкранный режим и многое другое (обсуждение)
WINCMD.RU: AskParam, CopyTree, NTLinks, Sudo, VirtualPanel…
Back to top
View user's profile Send private message
Ciber SLasH



Joined: 20 Aug 2005
Posts: 209
Location: С.-Петербург

Post (Separately) Posted: Thu Jul 25, 2013 22:40    Post subject: Reply with quote

Ларчик просто открывался Very Happy
Оказалось у меня вываливался в ошибки при закрытии 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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> Плагины Total Commander All times are GMT + 4 Hours
Page 1 of 1

 
Jump to:  
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