Using CEF inside a Photoshop Plugin instead of basic HWND

Having problems with building or using CEF's C/C++ APIs? This forum is here to help. Please do not post bug reports or feature requests here.

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

Postby magreenblatt » Fri Feb 16, 2018 5:56 pm

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.
magreenblatt
Site Admin
 
Posts: 10181
Joined: Fri May 29, 2009 6:57 pm

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

Postby abizeau » Fri Feb 16, 2018 6:17 pm

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.
abizeau
Techie
 
Posts: 34
Joined: Thu Feb 15, 2018 7:07 pm

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

Postby abizeau » Mon Feb 19, 2018 12:10 pm

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
abizeau
Techie
 
Posts: 34
Joined: Thu Feb 15, 2018 7:07 pm

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

Postby magreenblatt » Mon Feb 19, 2018 12:41 pm

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.
magreenblatt
Site Admin
 
Posts: 10181
Joined: Fri May 29, 2009 6:57 pm

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

Postby abizeau » Mon Feb 19, 2018 1:23 pm

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 ?
abizeau
Techie
 
Posts: 34
Joined: Thu Feb 15, 2018 7:07 pm

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

Postby magreenblatt » Mon Feb 19, 2018 1:30 pm

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.
magreenblatt
Site Admin
 
Posts: 10181
Joined: Fri May 29, 2009 6:57 pm

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

Postby abizeau » Mon Feb 19, 2018 4:16 pm

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 !
abizeau
Techie
 
Posts: 34
Joined: Thu Feb 15, 2018 7:07 pm

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

Postby abizeau » Tue Feb 20, 2018 1:13 pm

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.
abizeau
Techie
 
Posts: 34
Joined: Thu Feb 15, 2018 7:07 pm

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

Postby magreenblatt » Tue Feb 20, 2018 1:20 pm

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
magreenblatt
Site Admin
 
Posts: 10181
Joined: Fri May 29, 2009 6:57 pm

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

Postby programaudio2 » Sun Jul 12, 2020 5:56 pm

Would you be able to share the code of how you got the dll's and exe to display properly?
programaudio2
Newbie
 
Posts: 3
Joined: Mon Jul 06, 2020 12:36 pm

PreviousNext

Return to Support Forum

Who is online

Users browsing this forum: Google [Bot] and 41 guests