Jump to content
You must now use your email address to sign in [click for more info] ×

Suggestion for alternative aflaunch.exe functionality


Recommended Posts

@Mark Ingram

I found the command line switches on aflaunch.exe made it clumsy to use in some cases and impossible to use in others (where the 3rd party app will not allow the user to specify arguments to the external editor to choose which app is invoked and where you're wanting to use, say, Designer instead of Photo; an example would be XNViewMP).

I hacked together my own launcher and I figured I'd share the code with you since it's easier to use and works with all Affinity apps and every 3rd party app I've tried. It's polymorphic in the sense that the launcher application will choose the Affinity app to launch as a function of its own basename.

I imagine you're using similar code to launch the app in your aflaunch, so this code is simply to highlight a little functionality which does away with needing to pass command line switches to decide which app to invoke.

Rename the executable AffinityPhoto2.exe and it will launch Photo.exe. Rename it AffinityDesigner2.exe and it will launch Designer.exe, etc.

I think this would be a useful enhancement to your aflaunch.exe - one executable can launch all 3 Affinity apps without requiring command line switches. The code below is a hack, but feel free to use any of it if you wish - I assert no copyright. Caveat emptor - there may be bugs. 

 

#include <ShObjIdl.h>
#include <atlbase.h>
#include <appmodel.h>
#include <strsafe.h>
#include <processenv.h>
#include <tchar.h>
#include <wchar.h>

PCWSTR CommandLineArguments()
{
    // GetCommandLineA returns quoted arguments if there are spaces
    // Check if the first character is a quote
    // Then find the first occurrence of '\" '
    // or if unquoted, ' ', to locate the beginning of the arguments

    LPWSTR cmdline = GetCommandLineW();
    PCWSTR s = nullptr;

    if (*cmdline == '\"') 
    {
        (s = StrStrW(cmdline, L"\" ")) ? s += 2 : nullptr;
    }
    else 
    {
        (s = StrStrW(cmdline, L" ")) ? s++ : nullptr;
    }
    return s;
}

HRESULT LaunchApp(LPCWSTR AUMID)
{
    HRESULT hr = CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);

    if (SUCCEEDED(hr))
    {
        CComPtr<IApplicationActivationManager> AppActivationMgr = nullptr;

        if (SUCCEEDED(hr)) 
        {
            hr = CoCreateInstance(
                CLSID_ApplicationActivationManager, 
                nullptr, 
                CLSCTX_LOCAL_SERVER, 
                IID_PPV_ARGS(&AppActivationMgr)
            );         
        }
        if (SUCCEEDED(hr)) 
        {
            DWORD pid = 0;
            PCWSTR args = CommandLineArguments();
            hr = AppActivationMgr->ActivateApplication(AUMID, args, AO_NONE, &pid);
        }
    }

    CoUninitialize();
    return hr;
}

WCHAR *GetErrorMessage(HRESULT lResult)
{
    static WCHAR buf[512];

    DWORD cchMsg = FormatMessage(

        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        lResult,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        buf,
        512,
        NULL
    );

    return cchMsg ? buf : nullptr;
}

LPCWSTR basename(LPCWSTR name)
{
    WCHAR* p = StrRChrW(name, NULL, L'\\');
    return p ? p + 1 : name;
}

LPCWSTR GetAppAMUID(const WCHAR* argv0)
{
    LPCWSTR exename = basename(argv0);
    
    if (lstrcmpiW(exename, L"AffinityDesigner2.exe") == 0) 
    {
        return L"SerifEuropeLtd.AffinityDesigner2_3cqzy0nppv2rt!SerifEuropeLtd.AffinityDesigner2";
    }
    else if (lstrcmpiW(exename, L"AffinityPublisher2.exe") == 0) 
    {
        return L"SerifEuropeLtd.AffinityPublisher2_3cqzy0nppv2rt!SerifEuropeLtd.AffinityPublisher2";
    }
    else  
    {
        // default in case the user changes the executable name to something unrecognizable
        return L"SerifEuropeLtd.AffinityPhoto2_3cqzy0nppv2rt!SerifEuropeLtd.AffinityPhoto2";
    }
    return nullptr;
}


int wmain(int argc, WCHAR *argv[])
{
    LPCWSTR appname = basename(argv[0]);
    HRESULT hr = LaunchApp(GetAppAMUID(appname));

    if (FAILED(hr)) 
    {    
        wprintf(L"%s: %s\n", argv[0], GetErrorMessage(hr));
    }
    return FAILED(hr) ? 1 : 0;
}

 

Link to comment
Share on other sites

  • 1 month later...

Hello @rvst,

how do you compile this to an exe file?
Are there some explanations or links available for explaining the process?

 

Sketchbook (with Affinity Suite usage) | timurariman.com | artstation store

Windows 11 Pro - 23H2 | Ryzen 5800X3D | RTX 3090 - 24GB | 128GB |
Main SSD with 1TB | SSD 4TB | PCIe SSD 256GB (configured as Scratch disk) |

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use | Privacy Policy | Guidelines | We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.