Monthly Archives: May 2015

Create your own Greenshot plugin

Greenshot

When you have to make screenshots on a daily bases, to add in a manual, to report issues, to share views with colleagues, you’’ll find that the default screenshot capabilities of Windows aren’t sufficient enough.

Therefor I’m already a long time user of the open source Greenshot product. It gives you the possibility to capture a region, edit the image and then copy/paste or use one of the existing plugins to upload the picture to JIRA, Office, …

For a project I’ve wanted to create a new plugin so we can add screenshot to our work log without have to take the screenshot, save the image somewhere and then go to the web application and upload the file. As there is no (or I didn’t found it) documentation how to create your own plugin, I started to digging in the existing code base.

In this post you’ll find the steps you’ll have to do to create your own plugin.

One remark, I’m a very happy user of Greenshot, and must say, even without documentation, the code base is clearly well build up and professional!

Setting up development

First go to https://bitbucket.org/greenshot/greenshot to fetch the latest source code. (if you’re using git: git clone https://bitbucket.org/greenshot/greenshot.git in a git console)

After you downloaded the source code, go to the greenshot folder and open up Greenshot.sln. I’m using Visual Studio 2013 that’s is going to upgrade the existing projects.  If you want to contribute, be sure to read the instructions on the bitbucket page!

In Visual Studio the project would look like the screenshot below:

image

Add a new project

Right click on the Greenshot solution and choose to add a new project.

image

Choose to create a class library and give it a name. (in my case GreenshotDemoPlugin). Be sure to select the .NET 2.0 framework as the rest of the project is build in 2.0.

image

After the project is added to your solution open up the properties of the project (right click on project and then select properties). In the Build Events tab edit the post build event command line and paste the next statements in:

mkdir “$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)”
copy “$(ProjectDir)bin\$(Configuration)\$(TargetFileName)” “$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\*.gsp”
copy “$(ProjectDir)bin\$(Configuration)\$(ProjectName).pdb” “$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\”
mkdir “$(SolutionDir)bin\$(Configuration)\Languages\Plugins\$(ProjectName)”
copy “$(ProjectDir)\Languages\*.xml” “$(SolutionDir)bin\$(Configuration)\Languages\Plugins\$(ProjectName)\”

image

This will make sure after you build the project, it is automatically copied and placed into the greenshot plugin folder of your development environment as a gsp package file (I suppose gsp stands for GreenShotPlugin). The last statement is only useful if you add multiple languages to your plugin. Hit save and close the properties window.

Last but not least, add a reference to the GreenshotPlugin by right clicking the references node in your plugin project and browse to the correct project and click add.

image

Run Rebuild on  the solution and you’ll see in the output window that for every plugin a new folder is created under ../Greenshot/bin/debug/plugins. You probably will see the GreenshotDemo Plugin folder there too.

Base classes

Now that the project is set up, we can start to add the necessary classes for our plugin.

Configuration class

We’ll start with the configuration class that will help us with storing the necessary settings in the Greenshot config file so we can retrieve them later in the process.

Right click your plugin project and choose to add a new class. Call it DemoConfiguration.cs. Make the class public accessible and overwrite from the IniSection  class from the Greenshot.IniFile namespace.

Add the properties you’ll will need to upload your images to your server or application. I’ve added the following properties: Url, Timeout, UploadFormat, UploadJpegQuality, UploadReduceColors (shameless copy from another existing plugin).

For every setting add an IniProperty annotation with the name of the setting, the description and a default value. At last, add the IniSection annotation on top of your configuration class and set the name and description. The full class is below:

Connector class

The connector class will be used to manage the connection to your webservice or REST service and how that the pictures need to be uploaded.

Add a new class to your plugin project and name it DemoConnector.cs. Make your class public and inherit from IDisposable. To be able to write to the log file you’ll have to add a reference to Log4Net. As different versions of Log4Net can cause some problems you best reference the Log4Net DLL that is included in the Greenshot Lib folder (Greenshot/Lib)

As we are inheriting from IDisposible whe have to implement the Dispose method. Next to that, we add a constructor and an AddAttachment method. The last method is where you’ll define what needs to be done to have the image uploaded to your system. For my test system I have to send a ticketnr (for now I added a value for test, we’ll update it later), the name of the file and the image itself as base64 string.

In the constructor we copy the URL of the config settings in a local Url parameter to use in our AddAttachment method.

Plugin class

Next we’ll create a plugin class, the base of our new custom plugin. Add a new class in your plugin project and name it DemoPlugin.cs. Make the class public accessible and inherit from the IGreenshotPlugin interface from the Greenshot.Plugin namespace.

The IGreenshotPlugin interface has 6 methods defined we’ll need to implement in our class.

image 

Next to the 6 methods, I’ve added a few private properties: IGreenshotHost, our new created connector (DemoConnector), PluginAttributes and our Configuration class (DemoConfiguration)

The first method to implement is the Initialize method. There we receive the host from greenshot and the plugin attributes that we assign to our local properties of our class. Also we read the configuration settings from our configuration class and return true.

The configure method we’ll leave empty, as we do with the Destinations method. (we’ll come back to this after we created the Destination class). in the Processors method we’ll yield a break statement.

We’ll add a public getter for our connector too, that we’ll need to access from the Destination class we’re going to create next.

The Shutdown and Dispose methods are fairly self explaining as you can see in the class below:

Destination class

The last class we have to add is out Destination class where we bind the plugin and the connector together.

Add a new class and name it DemoDestination, make the class plublic accesible and inherit from the AbstractDestination class from the GreenshotPlugin.Core namespace.

From the abstract class we’ll obligated to implement the ExportCapture method and the Designation and Description parameters.

image

In the Designation and Description properties I fill out some random text (ideal you will be using the resource file to serve multiple languages but that can be added later on).

The ExportCapture method is the main method where we’ll define what will happen if we make a screenshot with Greenshot. We gather the necessary information about the screenshot (name and settings) and call our connector to upload the screenshot as shown below.

We’ll need to add a reference to the System.Windows.Forms namespace because we’ll make use of a buildin form of Greenshot that has a link to the forms namespace. (also for the messagebox we want to show).

Few last smaller adjustments

We’re almost there. We now created all necessary class for a (very) basic plugin. With some small adjustments we can and run our plugin for the first time.

Open up the DemoPlugin class again. In the Destinations method we now can add our new created DemoDestination. Alter the method as shown here:

Next (and this took me a while to figure out), your plugin will not be recognized by Greenshot if you don’t put a Plugin attribute in your Assemblyinfo.cs class. So open up this file and add line 17. ([assembly: Plugin(“GreenshotDemoPlugin.DemoPlugin”, true)])

Run and test

If you implemented everything properly then you can now just press the run button (mark the Greenshot project as startup project if that’s not the case yet).

You’ll see the Greenshot icon appear in your windows tray icons, hit the print screen button and mark an area on your screen. If you release your left mouse button a context menu should appear. In all the choices you have their (depending on what plugins are installed) you should have an “Upload to Demo system) item.

Select the item and your screenshot should be uploaded to your demo system.

image

If you have any exceptions or problems you can always look into the Greentshot.log file that default is created in the folder “C:\Users\YOURUSERNAME\AppData\Local\Greenshot\”.

Your plugin should also be in the list of plugins, right click on the Greenshot icon in your tray and left click and select preferences. On the Plugin tab your plugin should appear (but you can’t make any setting changes).

image

Source and last comment

You can find all created classes and settings on my Github page https://github.com/BartDM/GreenshotPlugin/tree/master/GreenshotDemoPlugin.

Off course is this only a rudimental plugin that we’ve created. In a next post we’ll add some screens so the end user can enter some data and can alter some settings from the UI.