hm.NETは秀丸メールでは動作しない?No.09141
powerofdreams さん 20/01/22 10:30
 
はじめまして。お世話になります。

hm.NET (秀丸マクロ用 .NET Framework ライブラリ)は、
秀丸エディターのみ動作する。ということでしょうか。

秀丸メールで動作させると「秀丸メールのプロセスで保護違反が発生しました。秀丸
メールは異常終了します。」と表示され、動作させることができません。
秀丸エディタでは動作します。

お返事いただければ幸いです。よろしくお願いいたします。

[ ]
RE:09141 hm.NETは秀丸メールでは動作しなNo.09142
秀丸担当 さん 20/01/23 10:53
 

hm.NETは、秀丸エディタにしか無い方法を使っているはずなので、秀丸メールでは動
作しないと思います。
異常終了してしまうのはまずいので、マクロ先頭に以下のような感じで動作させない
ようにしておくと現状で落ちるのを防ぐことができると思います。
if( platform & 0x800000 ) {
  message "秀丸メールでは動作しません";
  endmacro;
}

プログラム的には、マクロヘルプの「目次− DLL側から秀丸エディタの関数呼び出
し」のところにある関数をhm.NET側から呼んでいるはずだと思います。
(というかこれらの関数は、hm.NET作者のvscode-lifeさんとのやりとりでできたも
のです)
これはhidemaru.exeにある関数で、メインスレッドで呼ばれることを想定しています。
秀丸メールにはこれらの関数は無くて、また秀丸メールはマルチスレッドでエディタ
ウィンドウが複数存在するので、仕組み的にもこれらの関数をそのまま適用すること
はできないため、現状では秀丸メールでは動作しないようにしていただくしかなさそ
うです。

[ ]
RE:09142 hm.NETは秀丸メールでは動作しなNo.09143
powerofdreams さん 20/01/23 12:47
 
お返事ありがとうございます。

内容承知いたしました。
エディタのマクロはメールでも使えると思っていたので、
エディタ側でプログラムを作成して、メールにもっていったところ動かなかったので
まさかと思い問い合わせさせていただいたのですが、お返事みて諦めつきました。

やはり秀丸メールを使用して、DLLからマクロを呼ぶ方法はなにかお心当たりありま
せんでしょうか。
これまたエディタ用のマクロかもしれませんが、DLL側から秀丸エディタの関数呼び
出し(Hidemaru_EvalMacro)を試そうとしたのですが、
ヘルプを見ても使い方が分からなくて。。。
hm.netのようなDLLなしになぜ自作のDLLから秀丸エディタの関数が呼び出せるのか
な?とか。。。
hello worldも組めない状況です。

秀丸メールでDLLやEXEなどから秀丸マクロを呼べる方法があれば、アドバイスいただ
けると助かります。

よろしくお願いいたします。


[ ]
RE:09143 hm.NETは秀丸メールでは動作しなNo.09144
秀丸担当 さん 20/01/23 16:45
 

秀丸エディタで、Hidemaru_EvalMacroを使う場合は、以下のような感じになります。

//マクロ
loaddll @"C:\Folder\DllFuncTest.dll";
#param=123;
#result=dllfunc( "DllFuncTest",#param);
endmacro;

//DLL側の関数
extern "C" __declspec( dllexport )
INT_PTR DllFuncTest( INT_PTR nParam ) {
    HINSTANCE hinstExe = GetModuleHandle( NULL );
    BOOL (WINAPI* pfnHidemaru_EvalMacro)( WCHAR* pwsz );
    *(FARPROC*)&pfnHidemaru_EvalMacro= GetProcAddress( hinstExe, "Hidemaru_E
valMacro" );
   
    if( pfnHidemaru_EvalMacro) {
        return pfnHidemaru_EvalMacro( L"message \"Hello DLL\"" );
    }
    return 1;
}


秀丸メールの場合はHidemaru_EvalMacroは使えないです。
全く別の方法として、「目次− DLL側から秀丸エディタの関数呼び出し−マクロ実行
するメッセージ」の、WM_REMOTE_EXECMACRO_FILEやWM_REMOTE_EXECMACRO_MEMORYがあ
りますが、このメッセージはEvalとは違ってマクロ実行中は実行できないです。
つまり、マクロから自作DLLをdllfuncで呼んで、その中でWM_REMOTE_EXECMACRO_MEMO
RYをSendMessageするという方法は使えないです。
マクロを実行していないときに、何らかの自作プログラムからWM_REMOTE_EXECMACRO_
MEMORYを呼ぶということであればできるはずと思います。

[ ]
RE:09144 hm.NETは秀丸メールでは動作しなNo.09145
powerofdreams さん 20/01/23 21:55
 
お世話になります。
コードまでご提示いただいて本当にありがとうございます。
とんでもないお時間をいただいてようで、ありがたく思っています。

触ったことがない言語なので、素直に動かず試行錯誤トライしています。
まず、秀丸エディタで、このコードを動作させてみて、
こういうものかと。ノウハウができたら、本目的の「WM_REMOTE_EXECMACRO_MEMORY」
というものを
秀丸メールで試してみたいと思います。
チンプンカンプンで頭抱えていますが、どうにか秀丸メールで動かしたいので頑張っ
てみます。
また結果を報告させてください。

取り急ぎありがとうございました。

[ ]
RE:09145 hm.NETは秀丸メールでは動作しなNo.09146
powerofdreams さん 20/01/23 23:17
 
いただいたコードが動きまして、事の重大さが分かりました。
秀丸メールからdllfuncでDLLが呼べないのは難しいですね。。。


>マクロを実行していないときに、何らかの自作プログラムからWM_REMOTE_EXECMACRO
>_MEMORYを呼ぶということであればできるはずと思います。

これは以下のようなイメージでいけそうでしょうか?
1.秀丸メールからrunで自作exeを実行する
2.自作exeではWM_REMOTE_EXECMACRO_MEMORYを呼ぶ
3.WM_REMOTE_EXECMACRO_MEMORY内でマクロを実行する

なんか違うような気がしますが、どうにかならないかと考えてみたのですが。。。

[ ]
RE:09146 hm.NETは秀丸メールでは動作しなNo.09147
powerofdreams さん 20/01/24 10:57
 
連投すみません。

>2.自作exeではWM_REMOTE_EXECMACRO_MEMORYを呼ぶ

これは私にはハードルが高そうで諦めます。
何か別の方法がないか、検討してみます。

相談に乗っていただきありがとうございました。

[ ]
RE:09147 hm.NETは秀丸メールでは動作しなNo.09148
秀丸担当 さん 20/01/24 12:42
 

自作EXEプログラムからマクロを呼ぶ目的というのが、どういう目的かによりますが、
マクロ内容が動的に変化するものではなく、単に固定のマクロを実行するだけでよけ
れば、秀丸メールの本体EXEであるTurukame.exeの起動オプション/xでマクロを実行
するだけでもいいかもしれないです。


"C:\Program Files\HidemaruMail\TuruKame.exe" /x test.mac

---------

外部のEXEからSendMessageでメッセージを送るのは、不可能ではないですが、プロセ
スをまたぐとメモリのアドレスが変わるので、だいぶん凝ったコードが必要になりま
す。
蛇足かもしれないですが、参考までにサンプルを書いておきます。
以下のような感じにすると外部のプロセスのメモリに書き込んで、そのアドレスを渡
したりできます。
EXE側の例はC++ですが、C++でやるにしても普通は使わないようなメモリの読み書き
が必要になってしまいます。

//マクロ側のサンプル
runex @"C:\Folder\OutprocessSample.exe " + hex(hidemaruhandle(0))
 , 0; //0 : 非同期
endmacro;


//EXE側のサンプル
#include <windows.h>

#define WM_HIDEMARUINFO (WM_USER + 181)
#define HIDEMARUINFO_GETTABWIDTH 0

#define WM_REMOTE_EXECMACRO_MEMORY (WM_USER + 272)

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCm
dShow ) {
    //引数に16進数のウィンドウハンドルを文字列で指定
    HWND hwndHidemaru = (HWND)strtol(lpCmdLine,NULL,16);
    if( hwndHidemaru ) {
        //まずはプロセスをまたいでも関係無いような、数値だけの受け渡しが成功
しているかどうかを確認
        int cTab = (int)SendMessage( hwndHidemaru, WM_HIDEMARUINFO, HIDEMARU
INFO_GETTABWIDTH, 0 );
        TCHAR sz[100];
        wsprintf( sz, TEXT("cTab %d"),cTab);
        MessageBox(0,sz,0,MB_TOPMOST);
       
        //プロセスをまたいで文字列の受け渡しができるかの確認
        static WCHAR wszMacroText[] = L"message \"Hello OUTPROCESS\";";
        DWORD dwProcessId = 0;
        GetWindowThreadProcessId( hwndHidemaru, &dwProcessId );
        HANDLE hProcess = OpenProcess( PROCESS_VM_OPERATION | PROCESS_VM_REA
D | PROCESS_VM_WRITE, FALSE, dwProcessId );
        if( hProcess ) {
            void* pVirtual = (void*)VirtualAllocEx(hProcess, NULL, 4096, MEM
_RESERVE | MEM_COMMIT, PAGE_READWRITE );
            if( pVirtual ) {
                SIZE_T dwWritten = 0;
                WORD w = 4096;
                WriteProcessMemory( hProcess, pVirtual, wszMacroText, (wcsle
n( wszMacroText ) + 1) * sizeof(WCHAR), &dwWritten );
                SendMessage( hwndHidemaru, WM_REMOTE_EXECMACRO_MEMORY, 0, (L
PARAM)pVirtual );
            }
            if( pVirtual ) {
                VirtualFreeEx( hProcess, pVirtual, 0, MEM_RELEASE );
            }
            CloseHandle( hProcess );
           
        }
    }
    return 0;
}


サンプルでwParamの返り値の取得を試そうとしたのですが、うまく動作しないことが
わかってしまって、調べて修正しようと思います。
あと、WM_REMOTE_EXECMACRO_MEMORYの代わりに、WM_REMOTE_EVALMACROのようなメッ
セージを新しく作って、Eval相当のことができたらいいかもしれないです。
これだとマルチスレッドでも判別してdllfuncでも可能かもしれないです。
まず秀丸エディタのほうで試してみて、それから秀丸メールに反映となって先の話に
なってしまうかもしれないですが、将来的なこととして検討したいと思います。


[ ]