Page 2 of 3

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Fri Feb 16, 2018 5:56 pm
by magreenblatt
Are you using multi_threaded_message_loop = true currently? Are you specifying a browser_subprocess_path and implementing the subprocess exe as shown at https://bitbucket.org/chromiumembedded/ ... executable ? If you're doing all of that then perhaps the subprocess is crashing -- check your logs.

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Fri Feb 16, 2018 6:17 pm
by abizeau
Im using the code as the cefsimple_win.cc:

Code: Select all
// Enable High-DPI support on Windows 7 or newer.
        CefEnableHighDPISupport();

        void* sandbox_info = NULL;
        // Provide CEF with command-line arguments.
        CefMainArgs main_args(hInstance);

        // CEF applications have multiple sub-processes (render, plugin, GPU, etc)
        // that share the same executable. This function checks the command-line and,
        // if this is a sub-process, executes the appropriate logic.
        int exit_code = CefExecuteProcess(main_args, NULL, sandbox_info);
        if ( exit_code >= 0 )
        {
            // The sub-process has completed so return here.
            return exit_code;
        }

        // Specify CEF global settings here.
        CefSettings settings;

        //settings.single_process = true;

        // SimpleApp implements application-level callbacks for the browser process.
        // It will create the first browser instance in OnContextInitialized() after
        // CEF has initialized.
        CefRefPtr<SimpleApp> app(new SimpleApp);

        // Initialize CEF.
        CefInitialize(main_args, settings, app.get(), sandbox_info);

        // Run the CEF message loop. This will block until CefQuitMessageLoop() is
        // called.
        CefRunMessageLoop();

        // Shut down CEF.
        CefShutdown();


The only thing I changed is the settings.single_process = true; (commented or not).

I understand the CefInitialize & CefShutdown should not be there now but inside a PluginCEFRunner.dll which will be delay loaded as said previously, and Im about to develop it.

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Mon Feb 19, 2018 12:10 pm
by abizeau
I tried to do as you said. Create a dll with the following exported function :

Code: Select all
__declspec( dllexport ) void __stdcall PluginDLLRunner_InitCEF(HINSTANCE hInstance)
{
    // Enable High-DPI support on Windows 7 or newer.
    CefEnableHighDPISupport();

    void* sandbox_info = NULL;

    // Provide CEF with command-line arguments.
    CefMainArgs main_args(hInstance);
   
    // CEF applications have multiple sub-processes (render, plugin, GPU, etc)
    // that share the same executable. This function checks the command-line and,
    // if this is a sub-process, executes the appropriate logic.
    int exit_code = CefExecuteProcess(main_args, NULL, sandbox_info);
    if ( exit_code >= 0 )
    {
        // The sub-process has completed so return here.
        return;
    }

    // Specify CEF global settings here.
    CefSettings settings;   
    settings.log_severity = LOGSEVERITY_VERBOSE;

    // SimpleApp implements application-level callbacks for the browser process.
    // It will create the first browser instance in OnContextInitialized() after
    // CEF has initialized.
    CefRefPtr<SimpleApp> app(new SimpleApp);

    // Initialize CEF.
    CefInitialize(main_args, settings, app.get(), sandbox_info);

}

__declspec( dllexport ) void __stdcall PluginDLLRunner_ShutdownCEF()
{
    // Shut down CEF.
    CefShutdown();
}

__declspec( dllexport ) void __stdcall PluginDLLRunner_CreateCEFWindow()
{
    // Run the CEF message loop. This will block until CefQuitMessageLoop() is
    // called.
    CefRunMessageLoop();
}


where the dllmain.cpp looks like this

Code: Select all
BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
    switch ( ul_reason_for_call )
    {
        case DLL_PROCESS_ATTACH:
        {
            PluginDLLRunner_InitCEF(static_cast<HINSTANCE>( hModule ));
        }
        break;
        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
        {
            PluginDLLRunner_ShutdownCEF();
        }
        break;
    }
    return TRUE;
}


And trying to call the PluginDLLRunner_CreateCEFWindow() when Photoshop want to start the plugin.

The thing is, the program is stuck on the CefInitialize() when the dll start. And I actually don't see anything in the callstack or either the output. Nothing is log. I have to kill the debugger to get out. What am I doing wrong ?

And I re-read one of your previous post

The implementation of DoCefInitialize calls CefInitialize with CefSettings.multi_threaded_message_loop = true and browser_subprocess_path pointing to a separate exe for subprocesses.


Do I really need multi thread message loop ? Do I really need to create a sub process ? I would prefer to create my PS_Plugin + PluginDLLRunner, where the CEF is init and shutdown using the dll attach/deattach. And I would also like to have a 3rd exported function to call the windows when needed.

Sorry for all those questions, but Ithink CEF could be a powerful tool for my plugin, but the integration is a big complex.

But just to let you know, if I just log the in/out of PluginDLLRunner_InitCEF and PluginDLLRunner_ShutdownCEF. those are called only once, at Photoshop startup and shutdown, that is excellent :)

Regards,
Alex

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Mon Feb 19, 2018 12:41 pm
by magreenblatt
abizeau wrote:Do I really need multi thread message loop ? Do I really need to create a sub process ?

That depends on whether you want it to work or not ;)

abizeau wrote:the program is stuck on the CefInitialize() when the dll start

You shouldn't call CefInitialize from inside DllMain. You'll need to somehow delay the execution until after DllMain completes.

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Mon Feb 19, 2018 1:23 pm
by abizeau
Okay, I achieve to make the CefInitialize happen only once and outside the DllMain.

1) But same thing happen for the Shutdown, I also need to get it out of the dllmain ? I will try to check how to do it, but it seems harder to do it.

But I still get only a White windows, and Im not sure to understand why I need to use a sub-process... I dont need such a thing, I need to interact with Photoshop and not just creating another .exe stand-alone.

Otherwise, if you think it my only solution, I need to :

2) Photoshop will provide an image to my Plugin as Input, can I send it to the sub-process ?
3) When sub-process close, I need to return the output (filtered image) to Photoshop, can I retrieve or output data on sub-process close to the Plugin dll ?

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Mon Feb 19, 2018 1:30 pm
by magreenblatt
abizeau wrote:Im not sure to understand why I need to use a sub-process

You need to use a separate sub-process exe because otherwise it will try to re-launch Photoshop.exe. See https://bitbucket.org/chromiumembedded/ ... -processes

abizeau wrote:Photoshop will provide an image to my Plugin as Input, can I send it to the sub-process ?

You can use asynchronous JavaScript bindings or the network layer.

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Mon Feb 19, 2018 4:16 pm
by abizeau
Okay ! Everything works now.

I have my PhotoshopPlugin.dll, my PluginCEFHelper.dll that export the function to Init/Shutdown/CreateWindows with CEF (still have problem with shutdown, but I can check that later on) and I have my PluginSubProcess.exe to run the sub process.

This works perfectly. I changed few things such as I dont use the multi_threaded_message_loop = true, because I want to have my CefBrowserHost::CreateBrowser and CefRunMessageLoop() called when I need it and maybe multiple times.

So I need control on Windows creation, but only on Initialization :)

This works perfectly. I'm about to read about the Async JS binding and Network layer to make the integration in-between Photoshop and my CEF process.

Thanks a lot Marshall !

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Tue Feb 20, 2018 1:13 pm
by abizeau
Hello Marshall,

I face some problem again, might be a misunderstanding from me, but I need to clarify the point.

Right now when I execute my CEF, it looks like this:

Photoshop.exe (which have loadLibrary on PluginHelper.dll)
PluginRunner.exe x2 (which are the sub-process that have the small int main(argc, argv) similar to what you show in General Usage).

So in the PluginRunner.exe x2, I assume I have a Browser Process and a Render Process (as I understand).

In one your previous message, you said:

abizeau wrote:
Photoshop will provide an image to my Plugin as Input, can I send it to the sub-process ?

You can use asynchronous JavaScript bindings or the network layer.


But I don't understand how a PluginRunner.exe (render or browser) could send an IPC to Photoshop.exe to retreive the image.

Photoshop.exe process had the PluginHelper.dll load, and in this dll I have the following:

Code: Select all
bool PluginCEFHelper::CreateCEFWindows(const std::string url)
{
    OutputDebugString(L"PluginCEFHelper - Shows the window.\n");

    m_app->GenerateWindows(url);

    // Run the CEF message loop. This will block until CefQuitMessageLoop() is
    // called.
    CefRunMessageLoop();

    return false;
}


where m_app is CefRefPtr<PluginApp>, and where GenerateWindows() function is simply a function taking an URL and creating a CefBrowserHost::CreateBrowser();

So how could I send the input image to the process ? Should my GenerateWindows() take the URL + the image pointer ?

If so, you could I return the image after the CefRunMessageLoop() ?

Im kinda of lost right now in all those processes, but its working smooth for now, except that I can retrieve the image.

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Tue Feb 20, 2018 1:20 pm
by magreenblatt
Photoshop.exe is the main process. PluginRunner.exe is all sub-processes (probably renderer and GPU). IPC is handled by the Chromium/CEF code running in each process. For a general overview see https://bitbucket.org/chromiumembedded/ ... cation-ipc

Re: Using CEF inside a Photoshop Plugin instead of basic HWN

PostPosted: Sun Jul 12, 2020 5:56 pm
by programaudio2
Would you be able to share the code of how you got the dll's and exe to display properly?