CLR AddIn Model in Paint.Net – 2 (AddIn discovery)
Paint.Net can host multiple AddIns. We can let the user pick which AddIn to use. To discover all the AddIns on the machine, we provided a few really simple APIs to do that.
First, host needs to know where to discover all the AddIns and Pipelines (pipelines are components that can connect Host and AddIn. We will discuss this in future blogs). Second, we need the Host to know what kind of AddIn it is expecting to load. Below is the code that I implemented in AddInSelectorConfigDialog.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.AddIn.Hosting;
namespace PaintDotNet.Effects
{
public partial class AddInSelectorConfigDialog : EffectConfigDialog
{
public AddInSelectorConfigDialog()
{
InitializeComponent();
string path = @"D:\demo\PaintDotNetAddInContract\PDNEffectAddIn";
string[] warnings = AddInStore.Rebuild(path);
Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(AddInHSV), path);
foreach (AddInToken token in tokens)
comboBox.Items.Add(token);
Refresh();
}
protected override void InitialInitToken()
{
theEffectToken = new AddInSelectorConfigToken();
}
protected override void InitTokenFromDialog()
{
AddInSelectorConfigToken effectToken = (AddInSelectorConfigToken)base.theEffectToken;
effectToken.AddInToken = (AddInToken)comboBox.SelectedItem;
base.InitTokenFromDialog();
}
private void btnSelect_Click(object sender, EventArgs e)
{
if (comboBox.SelectedItem != null)
{
AddInSelectorConfigToken effectToken = (AddInSelectorConfigToken)base.theEffectToken;
effectToken.AddInToken = (AddInToken)comboBox.SelectedItem;
FinishTokenUpdate();
this.Close();
}
}
}
}
AddInStore.Rebuild is the process that Host trys to figure out which pipelins and addins are available under the path. This is usually a time consuming process due to the cost inspecting all the asseblies. Host does not want to do this frequently. Host can also call AddInStore.Update as well. We cache all the information on the hard disk as well to speed things up. That is why you can find two additional files are saved under the path. They are PipelineComponents.Store and AddIns\AddIns.store. We only update the cache when changes are detected.
Collection<AddInToken> tokens = AddInStore.FindAddIns(typeof(AddInHSV), path); is the API to discover all the AddIns that can be invoked through AddInHSV ( HSV stands for Host Side View, which is an abstract class) AddInToken is a datastructure that represents an entity which can be activated by activation APIs. AddInToken has information like name of the AddIn, dll locations etc.
The rest of code is quite similar to other PDN effect code. We allow user to select which token to use based on the name of the AddIn. Then we save the AddInToken in AddInSelectorConfigToken so that it can be passed around as parameters later.
Our next topic will be about Host Side View.
Comments
Anonymous
January 06, 2007
Why does AddInStore.FindAddIns take a Type parameter? Would it not be better to make the method generic?Anonymous
January 13, 2007
En parlant de System.AddIn , Jason He est justement en train de publier sur son blog une série de postAnonymous
January 13, 2007
To answer dono's question, I like the suggestion in deed. However, I heard two reasons not to do so. First, FxCop would complain if the API does not use the gneric type as a parameter. Second, generic type might not give back the right type all the time. Frankly, I am not convinced by either side yet.