This project has moved. For the latest updates, please go here.
End-User | Network Administrator | Developer

This subsection of the documentation is aimed at software developers interested in Path Copy Copy. It is divided into two parts: developers looking to build Path Copy Copy from source, and developers looking to create their own Path Copy Copy commands (also known as plugins).

Getting the source

Path Copy Copy uses Mercurial for its source control. For those of you not familiar with it, Mercurial is a distributed version control system - this means that each developer has a full copy of the repository on his/her machine. (HgInit might be a good place to start if you're new to Mercurial.)

There are two ways to get the source for Path Copy Copy in order to build it. The first one is to use a Mercurial client to clone the Path Copy Copy repository. The clone URL to use is https://hg01.codeplex.com/pathcopycopy. You can use any Mercurial client to do this. On Windows, TortoiseHg is a popular graphical Mercurial client that works well.

Developer_GettingTheSource_CloneRepoTortoiseHg.png
Cloning the Path Copy Copy repository with TortoiseHg

Once the clone operation completes, you can go in your chosen destination folder and see all Path Copy Copy project files.

The second way to get the source is to download a pre-packaged revision. You can do so by going to the Source Code tab and click on the Download link just under Latest Version on the right-hand side. After agreeing to the license, you will be able to download a complete version of the Path Copy Copy project files as a ZIP archive. Simply unzip it anywhere to be able to use it.

Whatever mean you choose to get the source, once you have it, you should probably read the README.TXT in the root directory. This file is a quick list of most other files in the Path Copy Copy source tree and is aimed at developers to read.

Building the shell extension

Path Copy Copy has been developed using Microsoft Visual Studio. Although it might be possible to adapt the source to build it with another tool, it has never been attempted. Make sure you meet the minimum prerequisites listed on the right before you attempt to build any part of the source.

Path Copy Copy is divided into two components, each with its own Visual Studio solution: the shell extension (responsible for adding the menu items in the shell's contextual menu) and the settings application (launched with the user chooses Settings in the menu - see End-User tab). In order to build the shell extension, open the PathCopyCopy.sln file.

Developer_BuildingShellExt_PathCopyCopySln.png
The PathCopyCopy solution

This solution contains two projects: PathCopyCopy and TestPlugins. The second project simply contains plugin implementations used for testing purposes and are never shipped with Path Copy Copy. Thus, this project is out of the scope of this documentation. Feel free to examine it if you want.

The Path Copy Copy shell extension is written in C++ and uses ATL. It is made of several different source files. Although this documentation won't dig into the structure of the code itself, feel free to do so on your own if you want to learn how Path Copy Copy works (especially the PathCopyCopyContextMenuExt class and the various Plugins).

The PathCopyCopy project has two configurations, Debug and Release, as well as two platforms, Win32 and x64. The Debug configuration should only be needed if you intend to trace into the Path Copy Copy code, so most likely, you will want to select Release. Also, it is important that each version of Path Copy Copy is built in 32-bit (Win32 platform) and 64-bit (x64 platform) formats, so as to be able to run on any system.

Once you are ready to build the shell extension, simply choose Batch Build... under the Build menu, check both Release|Win32 and Release|x64 solution config of the PathCopyCopy project, and click Build. Building should not take long depending on the speed of your computer.

Developer_BuildingShellExt_BatchBuilding.png
Using Batch Build to build both versions of PathCopyCopy

The output files, including the final PathCopyCopy.dll, are written in the bin directory under the root source directory. Object files will be in the obj directory, next to bin. Note that the build mechanism will automatically register the DLL, as the shell extension is a COM object.

Building the settings application

When the user selects the Settings... item in the Path Copy Copy submenu, the shell extension launches the Settings application to let the user modify the options. This application has its own Visual Studio solution named PathCopyCopySettings.sln. This solution contains a single project that is written in C# and targets .NET Framework 2.0.

Developer_BuildingSettingsApp_PathCopyCopySettingsSln.png
The PathCopyCopySettings solution

The Settings project is a Windows Forms project whose central source file is named MainForm. The other source files contain code to deal with the user settings and plugins. Again, this documentation won't dig into the code. Feel free to explorer if you want to see how settings are changed.

The PathCopyCopySettings solution again has two configurations, Debug and Release, but a single platform named AnyCPU. This is because a .NET application is platform-agnostic by default. In our case, it will run as a 32-bit application if the user is on a 32-bit system, and as a 64-bit application if on a 64-bit system. Again, the Debug configuration is only needed to trace in the code, so Release should be used in most circumstances.

Once you are ready to build the settings application, select Release from the configuration dropdown and Build Solution from the Build menu. The output and object files will be saved in the same place as the shell extension project's, alongside those files. Please note that although the project is platform-agnostic, it is first built in Win32 and then a post-build step is used to copy it to x64 so that both versions of the shell extension will be successfully able to find the application. The application file is named PathCopyCopySettings.exe.

After both projects have been built, Path Copy Copy should be ready to use. Since the COM object has been registered after building, simply right-clicking on a file or folder should show up the Path Copy Copy menu items.

Building the installer

For those who may need to modify Path Copy Copy and redistribute the modified version, building the installer may be needed. Path Copy Copy's setup has been built using the Inno Setup tool. In order to build the installer, make sure you have Inno Setup installed. You also need the Inno Setup Preprocessor, a free add-on. The simplest way to get it all in one package is to use the QuickStart Pack (see the Inno Setup download page).

Building the Path Copy Copy setup is easy. Simply open the Setup.iss file located in the Installer directory under the root source directory and choose Compile from the Inno Setup Compiler toolbar. (Note that if you installed InnoIDE using the QuickStart Pack, it will open instead of the Inno Setup Compiler. The same Compile command exists in its toolbar, however, and works the same way.)

Developer_BuildingInstaller_CompilingIsc.png
Compiling the Path Copy Copy setup using Inno Setup Compiler

Once the compilation completes, go back to the Installer directory and a new directory named Output will have been created. It will contain the setup application, named PathCopyCopyVersionNumber.exe.

This concludes the documentation to build Path Copy Copy from source. Those of you wishing to develop custom plugins can continue to the next section.

Plugin development

Path Copy Copy has been designed with a modular architecture. Each command seen in the contextual menu is called a plugin internally. It is possible to create and distribute custom plugins in the form of COM objects implementing custom Path Copy Copy interfaces. In this chapter, the sample C++ plugin project will be shown, but it should be possible to write custom plugins in any programming language using any environment, as long as it supports COM object development.

Note: it is assumed here that you are familiar with the C++ language and the development of COM objects using the ATL library. Learning to do this is outside the scope of this documentation. Please refer to web tutorials for more information.

Path Copy Copy ships with a sample Visual C++ project that implements a complete plugin. There are two places where it can be found:
  • In Path Copy Copy's installation directory, under Samples\Plugins\COM\C++.
  • In Path Copy Copy's source tree, under Samples\SampleCOMPluginCpp.
The sample comes with a Visual Studio 2008 solution containing a single project, itself containing only one important class named SamplePathCopyCopyPlugin. It also uses a file named PathCopyCopy_i.h that is very important as it contains the definintions of Path Copy Copy's custom interfaces.

Developer_PluginDevelopment_SampleCOMCppProject.png
The sample C++ COM plugin project

Opening SamplePathCopyCopyPlugin.h will display the declaration of the COM plugin class. In order to showcase them all, the class implements all three Path Copy Copy interfaces.

Developer_PluginDevelopment_SampleClassIntf.png
The sample plugin class' declaration with the Path Copy Copy interfaces

In order to be usable by Path Copy Copy, your plugin COM object needs to implement at least the IPathCopyCopyPlugin interface. The other interfaces are optional and can be implemented only if needed.

IPathCopyCopyPlugin interface


    // IPathCopyCopyPlugin interface
    STDMETHOD(get_Description)(BSTR *p_ppDescription);
    STDMETHOD(get_HelpText)(BSTR *p_ppHelpText);
    STDMETHOD(GetPath)(BSTR p_pPath, BSTR *p_ppNewPath);
Base interface that is required for all Path Copy Copy plugins. In contains three methods:
  • get_Description: Must return the plugin's description string. Will be displayed in the contextual menu to identify the plugin.
  • get_HelpText: Can return a help text that will be shown in the shell's status bar when the cursor hovers over the plugin's contextual menu item. It is legal to return NULL or an empty string for this.
  • GetPath: Main work method invoked by Path Copy Copy when it needs to get the path for a particular file or folder. This method can be called repeatedly if the user selected a group of files. It receives the full path to the file as input and must return a path, modified as needed.

IPathCopyCopyPluginGroupInfo interface


    // IPathCopyCopyPluginGroupInfo interface
    STDMETHOD(get_GroupId)(ULONG *p_pGroupId);
    STDMETHOD(get_GroupPosition)(ULONG *p_pPosition);
Optional interface that can be implemented when working on a group of plugins so that they are kept next to each other in the contextual menu. If this interface is not implemented, all custom plugins end up in the same "group" in the menu. This interface allows plugins to group together and determine ordering. It contains two methods:
  • get_GroupId: Must return the group ID (see below) of the group of plugins to which this plugin belongs to. All plugins with the same group ID will appear in the same block in the contextual menu, surrounded by separators.
  • get_GroupPosition: Must return the zero-based position of the plugin within the group. Path Copy Copy will display plugins in ascending order of group position when displaying the group.
Plugin groups are identified by an ID that is a 32-bit unsigned integer. Since there is no real way to know which IDs are already in use, developers are encouraged to specify their group ID using a four-char code, like this:

    STDMETHODIMP MyPlugin::get_GroupId(ULONG *p_pGroupId)
    {
        *p_pGroupId = 'MYGP';
        return S_OK;
    }
Furthermore, group IDs composed of all lowercase letters are considered reserved for internal use.

IPathCopyCopyStateInfo interface


    // IPathCopyCopyPluginStateInfo
    STDMETHOD(Enabled)(BSTR p_pParentPath, BSTR p_pFile, VARIANT_BOOL *p_pEnabled);
Optional interface that allows a plugin to specify its state in the contextual menu. It contains a single method:
  • Enabled: Called when the contextual menu is built to know if the plugin's entry should be enabled or not. The method receives two information to decide: the path of a file that was selected by the user, and the path of its parent directory. In order to be disabled, the method must return S_OK and set the VARIANT_BOOL parameter to VARIANT_FALSE; any other combination of results will leave the plugin enabled.

Plugin registration

Once your plugin has been developed, it needs to be registered as a COM object as well as with Path Copy Copy. In order to do this, the Path Copy Copy contextual menu extension COM object includes two methods to register and unregister a plugin. One place to do this is in the DllRegisterServer override of your ATL module.

    // In dllmain.h
    class CMyModule : public CAtlDllModuleT< CMyModule >
    {
    public :
        DECLARE_LIBID(...)
        DECLARE_REGISTRY_APPID_RESOURCEID(...)

        HRESULT DllRegisterServer(BOOL bRegTypeLib = TRUE) throw();
        HRESULT DllUnregisterServer(BOOL bUnRegTypeLib = TRUE) throw();
    };
    // In dllmain.cpp
    HRESULT CMyModule::DllRegisterServer( BOOL bRegTypeLib /*= TRUE*/ ) throw()
    {
        HRESULT hRes = CAtlDllModuleT< CMyModule >::DllRegisterServer(bRegTypeLib);
        if (SUCCEEDED(hRes)) {
            CComPtr<IPathCopyCopyContextMenuExt> cpPccExt;
            hRes = cpPccExt.CoCreateInstance(__uuidof(PathCopyCopyContextMenuExt));
            if (SUCCEEDED(hRes)) {
                cpPccExt->RegisterPlugin(__uuidof(MyPlugin));
            }
        }
        return hRes;
    }

    HRESULT CMyModule::DllUnregisterServer( BOOL bUnRegTypeLib /*= TRUE*/ ) throw()
    {
        HRESULT hRes = CAtlDllModuleT< CMyModule >::DllUnregisterServer(bUnRegTypeLib);
        if (SUCCEEDED(hRes)) {
            CComPtr<IPathCopyCopyContextMenuExt> cpPccExt;
            hRes = cpPccExt.CoCreateInstance(__uuidof(PathCopyCopyContextMenuExt));
            if (SUCCEEDED(hRes)) {
                cpPccExt->UnregisterPlugin(__uuidof(MyPlugin));
            }
        }
        return hRes;
    }
IMPORTANT NOTE: Please do NOT try to reverse-engineer Path Copy Copy's plugin registration internals and how plugins are saved. This is not guaranteed to be stable from version to version. The registration interface, however, is guaranteed to always exist.

Questions?

This concludes the developer documentation for Path Copy Copy. If you have further questions regarding any aspect of development (the source, the build system, plugin development, etc.) please don't hesitate to post in the Discussions section.


Last updated for version 9.2

Last edited Dec 12, 2012 at 10:56 PM by clechasseur, version 25