NCSwitch Plugin developer's manual

This document offers essential information about NCSwitch Plugin development.

Section Summary

About "NCSwitch Plugin"

"NCSwitch Plugin" is a program module that extends NCSwitch features. It enables to save and restore various setting items that NCSwitch built-in functions cannot restore.

The following figure explains about structures and roles of NCSwitch Plugin.

Structures of NCSwitch Plugin
# Description
1 NCSwitch collects configuration values of setting items that are supported by NCSwitch built-in functions.
2 NCSwitch Plugin collects configuration values of setting items that aren't supported by NCSwitch built-in functions. (In this case, it is "Application X")
3 NCSwitch Plugin sends configuration values to NCSwitch. (ref. API specification - IPlugin::GetSystemConfiguration)
4 NCSwitch saves configuration values received from NCSwitch Plugin to config.xml file.
5 NCSwitch reads configuration values from config.xml file.
6 NCSwitch restores configuration values of setting items that are supported by NCSwitch built-in functions.
7 NCSwitch Plugin receives configuration values that have been sent to NCSwitch at #3. (ref. API specification - IPlugin::SetSystemConfiguration)
8 NCSwitch Plugin restores configuration values of setting items that aren't supported by NCSwitch built-in functions. (In this case, it is "Application X") (ref. API specification - IPlugin::SetSystemConfiguration)

Sort of NCSwitch Plugin

Ini file plugin

Purpose

Saving and Restoring any entry into any ini file.

Preparations

You should specify entries (section name and item name) that will be saved and restored.

How to develop

Create plugin.xml file based on format below:
Plugin.xml format
Tag Attribute Description
NCSwitchPlugin Refer to plugin.xml format for more details of attributes.
NCSwitchPlugin
 /Module
ref "Spiralware.Inifile"(fixed value)
NCSwitchPlugin
 /Module/TargetOS
Refer to plugin.xml format for more details of attributes.
NCSwitchPlugin
 /Module/Parameter
name
"ini file identifier" + '.' (dot) + "ini file property name"
  • "ini file identifier"
    It is private name for identifying ini file. (it consists of arbitrary characters in alpha-numeral)
    Each ini file should be named uniquely.
  • ini file properties
    name value
    IniFileName ini file name
    file name of ini file
    IniFilePath ini file path
    If the ini file may be located one of several different paths, each possible path is delimited with ',' (comma).
    NCSwitch will search ini file through the entries, in order, until NCSwitch finds it.
    Ini file path can contain meta characters below:
    Value of environment variables
    '%' + (variable name) + '%'
    Value from another ini file entry
    '$(' + (ini file identifier) + ':[' +(section name) + ']' + (item name) + ')'
    If your plugin needs to make a user set the ini file path, this value remains empty.
    TargetItem Ini file entries (You can set multiple values delimited by comma.)
    You can define entries with one of following formats:
    Specified item into ini file [(section name)](item name)
    All items of specified section into ini file [(section name)]*
    All sections and all items into ini file *
value property value of ini file
plugin.xml sample
<?xml version="1.0" encoding="Shift_JIS" ?>
<NCSwitchPlugin 
name="Opera Network Settings" 
 description="Switch homepage and proxy settings of Opera" 
    support="support@spiralware.jp"
  <Module ref="Spiralware.Inifile">
    <!-- opera6.ini --> 
    <Parameter name="Config.IniFileName" value="ini file for Opera(opera6.ini)" /> 
    <Parameter name="Config.IniFilePath" value="%APPDATA%\Opera\Opera\profile\opera6.ini,%PROGRAMFILES%\Opera\profile\opera6.ini" /> 
    <Parameter name="Config.TargetItem" value="[User Prefs]Home URL,[Proxy]*" /> 
    <!-- accounts.ini --> 
    <Parameter name="MailConfig.IniFileName" value="ini file for Opera(accounts.ini)" /> 
    <Parameter name="MailConfig.IniFilePath" value="$(Config:[Mail]Mail Root Directory)\accounts.ini" /> 
    <Parameter name="MailConfig.TargetItem" value="[User Prefs]Home URL,[Proxy]*" /> 
  </Module>
</NCSwitchPlugin
There is an ini file plugin sample at "Spiralware.Opera" directory that is located at plugin root directory.

Registry plugin

Purpose

Saving and Restoring any entry into Windows registry.

Preparations

You should specify entries (key path and value name) that will be saved and restored.

How to develop

Create plugin.xml file based on format below:
Plugin.xml format
Tag Attribute Description
NCSwitchPlugin Refer to plugin.xml format for more details of attributes.
NCSwitchPlugin
 /Module
ref "Spiralware.Registry" (fixed value)
NCSwitchPlugin
 /Module/TargetOS
Refer to plugin.xml format for more details of attributes.
NCSwitchPlugin
 /Module/Parameter
name Registry key path which will be saved and restored
value Must be one of following formats
Format Description
"DATA=" + (name as registry value) Saving and Restoring only specified registry values. (You can set multiple values delimited by comma.)
The value name sets empty if it is "default value".
"ALL_DATA" Saving and Restoring all values into specified registry key
"ALL_SUBKEY" Saving and Restoring all values and sub keys into specified registry key
plugin.xml sample
<?xml version="1.0" encoding="Shift_JIS" ?>
<NCSwitchPlugin 
name="Start Menu:Internet and Mail" 
 description="Switch program to launch with [Internet] or [Mail] on [Start] menu."
    support="support@spiralware.jp">
<Module ref="Spiralware.Registry">
    <Parameter name="HKEY_CURRENT_USER\SOFTWARE\Clients\StartMenuInternet" value="DATA=" />
    <Parameter name="HKEY_CURRENT_USER\SOFTWARE\Clients\Mail" value="DATA=" />
</Module>
</NCSwitchPlugin>
There is a registry plugin sample at "Spiralware.DefaultBrowser" directory that is located at plugin root directory.

Custom plugin

Purpose

You can develop your own saving and restoring features by using COM components based on API specification of NCSwitch Plugin. You should develop custom plugin only if your requirements cannot come true with ini file plugin or registry plugin.

Preparations

Before you start developing a custom plugin, You should consider following:

How to develop

  1. Create a COM dll contains a class implementing IPlugin.
    IPlugin implementation sample
    // PluginImpl.h : CPluginImpl declaration

    #pragma once

    //A header file auto generated from SpiralwarePower.idl by MIDL compiler.
    #include "SpiralwarePower.h"

    // Import NCSwitch type library
    #import "libid:FEEE0494-3BCC-4C6F-AE1B-89D796F46922" raw_interfaces_only, raw_native_types, named_guids

    // CPluginImpl - implementing IPlugin interface
    class ATL_NO_VTABLE CPluginImpl :
        public CComObjectRootEx<CComSingleThreadModel>,
        public CComCoClass<CPluginImpl, &CLSID_PluginImpl>,
        public NCSwitchLib::IPlugin
    {
    public:
        CPluginImpl()
        {
        }

        DECLARE_REGISTRY_RESOURCEID(IDR_PLUGINIMPL)

        BEGIN_COM_MAP(CPluginImpl)
            COM_INTERFACE_ENTRY(IPlugin)
        END_COM_MAP()

        DECLARE_PROTECT_FINAL_CONSTRUCT()

        HRESULT FinalConstruct()
        {
            return S_OK;
        }

        void FinalRelease()
        {
        }

    public:
        // IPlugin Methods
        STDMETHOD(Initialize)(NCSwitchLib::IPluginSite * site)
        {
    ///Hold object references sent by NCSwitch into instance variables.
            m_spPluginSite = site;
            m_spPluginSite->get_Parameter(&m_spParameter);
            m_spPluginSite->get_Configuration(&m_spConfiguration);

    // Register IPropertyPage object if this plugin needs user inputs.
            // CComPtr<IPropertyPage> spPage;
            // spPage.CoCreateInstance(_T("XXX.XXX"));
            //
            // CComPtr<NCSwitchLib::IPluginPages> spPages;
            // m_spPluginSite->get_PluginPages(&spPages);
            // spPages->Add(spPage);

            return S_OK;
        }

        STDMETHOD(GetSystemConfiguration)(long * result)
        {
    //Get current power settings of OS
            CString sPowerSchemeId = this->GetActivePwrScheme();
            
            if (! sPowerSchemeId.IsEmpty())
            {
    //Succeeded
                *result = 1;

    //Send values to NCSwitch.
                m_spConfiguration->put_Item(CComBSTR(_T("PowerSchemeId")), CComBSTR(sPowerSchemeId));
            }
            else
            {
    //Failed
                *result = 0;
            }
            
            return S_OK;
        }

        STDMETHOD(SetSystemConfiguration)(long * result)
        {
            USES_CONVERSION;

    //Hold values that are read in GetSystemConfiguration into variables.
            CComBSTR bsId;
            m_spConfiguration->get_Item(CComBSTR(_T("PowerSchemeId")), &bsId);

    //Apply power settings of OS.
            if (this->SetActivePwrScheme(OLE2T(bsId)))
            {
    //Succeeded (need no reboot)
                *result = 1;
            }
            else
            {
    //Failed
                *result = 0;
            }

            return S_OK;
        }

    private:
        CString GetActivePwrScheme();
        bool SetActivePwrScheme(LPCTSTR pszSchemeId);

        CComPtr<NCSwitchLib::IPluginSite> m_spPluginSite;
        CComPtr<NCSwitchLib::IDictionary> m_spConfiguration;
        CComPtr<NCSwitchLib::IDictionary> m_spParameter;
    };

    OBJECT_ENTRY_AUTO(__uuidof(PluginImpl), CPluginImpl)
  2. Create plugin.xml file based on plugin.xml format
    plugin.xml sample
    <?xml version="1.0" encoding="Shift_JIS" ?>
    <NCSwitchPlugin
    name="Power Options" 
    description="Switch active power scheme"
        support="support@spiralware.jp">

      <Module codeBase="Spiralware.Power.dll" classId="{7B2F451A-6DC3-4175-A22D-F85E6295ACED}">
      </Module>

    </NCSwitchPlugin>
    There is a custom plugin sample at "Spiralware.Power" directory that is located at plugin root directory. (Visual C++ 2005 project)

How to test your NCSwitch Plugin

Testing for saving function

  1. Develop NCSwitch Plugin (ref. Sort of NCSwitch Plugin )
  2. Locate your NCSwitch Plugin at "plugins" directory (ref. Organization of files).
  3. Start NCSwitch Wizard and proceed saving procedure.

    "Setting items" page will show you your NCSwitch Plugin into the item list.

    If not, your NCSwitch Plugin has any trouble. Possible reasons are below:
    • Plugin.xml has been invalid XML format.

      If you open this plugin.xml with Internet Explorer, invalid location will be shown. Correct it.

    • Your IPlugin object fails to be created (only custom plugin)

      NCSwitch cannot find the class definition of your IPlugin object because "codeBase" or "classId" of "Module" element 's attributes have been wrong. As the result of it, your IPlugin object fails to be created. Correct values of these attributes.

      NCSwitch cannot create your IPlugin object because IPlugin::Initialize method call has failed. Debug source code of your IPlugin class.

  4. Confirm saved settings.

    After you have saved your configurations, a shortcut created by NCSwitch will be on your desktop. There is config.xml path written in property page of the shortcut.

    To read config.xml, you can check out the contents of saved settings. Confirm their values are same as you expected.

Testing for restoring function

  1. Double click the shortcut created at Testing for saving function in order to start restoring procedure.

    A status window shows you a restoring plan and indicates results of restoring processes in real time.

NCSwitch Plugin reference

Organization of files

NCSwitch Plugin consists of following files: After you have copied a directory containing these files into "plugins" directory, NCSwitch will load it at startup. (No COM registration into Windows registry needs.)

File name Required Description
plugin.xml A file storing configuration of NCSwitch Plugin itself (ref. plugin.xml)
***.dll A COM dll module based on NCSwitch Plugin API
Custom plugin needs it.
plugin.png × Icon image of NCSwitch Plugin. (32 x 32 pixel)
plugin_*.xml × A file storing configuration of NCSwitch Plugin (Localized Version)
It is useful that a NCSwitch Plugin switches configuration depending on NCSwitch locale. (Japanese: "plugin_ja.xml", English: "plugin_en.xml")
If there is no file corresponding to NCSwitch locale, NCSwitch will read "plugin.xml".
It is recommended that plugin identifier follows preferred form in order to avoid naming collision:
(Preferred Form: organization name or individual name) + '.' (dot) + (arbitrary name))

plugin.xml

Plugin.xml format
Tag Attribute Description
NCSwitchPlugin name Plugin name
description Plugin description
support URL or email address to contact
version 《*1.1》 "1.1" (fixed value (version of plugin.xml schema))
type 《*1.1》
  • "NORMAL": This plugin will start restoring after all NCSwitch built-in items has finished restoring.
  • "BOOTSTRAP": This plugin will start restoring before NCSwitch built-in items.
requireAdministrator 《*1.1》
  • "TRUE": This plugin needs administrator's privileges.
  • "TRUE": This plugin doesn't need administrator's privileges.
NCSwitchPlugin
 /Module
codeBase File name as a COM dll module based on NCSwitch Plugin API
classId A class implementing IPlugin interface(CLSID)
ProgID (ex. "SpiralwarePower.PluginImpl.1") is obsoleted. CLSID must be used.
NCSwitchPlugin
 /Module/TargetOS
minVersion 《*1.1》 Minimum version of Windows OS on which this plugin will work
((Internal version of Windows OS) + "-" + (Number of service pack))
[Version string sample]
"" (empty): No limit
"5.0-4": This plugin will work Windows 2000 SP4 or later.
"5.2-0": This plugin will work Windows Server 2003 or later.
"6.0-0": This plugin will work Windows Vista or later.
maxVersion 《*1.1》 Maximum version of Windows OS on which this plugin will work
((Internal version of Windows OS) + "-" + (Number of service pack))
[Version string sample]
"" (empty): No limit
"5.1-1: This plugin will work WindowsXP SP1 or earlier.
NCSwitchPlugin
 /Module/Parameter
name Configurations of NCSwitch Plugin
These configurations can be read via IPluginSite::Parameter by your custom plugin.
value
《*1.1》 - An attribute added since plugin.xml version 1.1. (NCSwitch Professional 1.0.0 or higher)

API specification

NCSwitch Plugin API is based on COM specification.

NCSwitch type library

After NCSwitch Professional has been installed, following type library that defines API has been registered.
File NCSwitchLib.dll (It is located at the directory where NCSwitch has been installed.)
LibID FEEE0494-3BCC-4C6F-AE1B-89D796F46922

IPlugin

This interface provides two functions, saving and restoring. Your NCSwitch Plugin Implements this interface. NCSwitch calls it.
Inherit interfaces IUnknown
ProgID NCSwitchLib.IPlugin
IID AAA4726C-53EF-49a5-B0B4-0D0F1F4F5BCE
IPlugin::Initialize
Initialize your NCSwitch Plugin object. After your NCSwitch Plugin object has been created, this method will be called only once.
HRESULT Initialize([in] IPluginSite* site);
Arguments site - An object that can be used to communicate with NCSwitch Professional.
Return S_OK - Succeeded
Comments
  • an IPluginSite object referred by site argument should be holden with instance variables or others.
    (This object will be used at GetSystemConfiguration or SetSystemConfiguration method following.)
  • If a NCSwitch Plugin has form windows that can be used to get user inputs when NCSwitch Wizard is in process, these windows should be registered for IPluginSite::PluginPages property.
IPlugin::GetSystemConfiguration
Save setting values.
HRESULT GetSystemConfiguration([out, retval] long* result);
Arguments result - A result of processing(0:Failed、1:Succeeded)
Return S_OK - Succeeded
Comments
  • Setting values read in this method should be written in IPluginSite::Configuration property of the IPluginSite object has received at Initialize method.
  • In case of failing, you should call IPluginSite::Prompt method to send error messages. Result argument of this method should be set "0" (failed). (Return value should be S_OK.)
IPlugin::SetSystemConfiguration
Restore setting values.
HRESULT SetSystemConfiguration([out, retval] long* result);
Arguments result - a result of processing(0:Failed, 1:Succeeded (need no reboot), 2:Succeeded (need reboot))
Return S_OK - Succeeded
Comments
  • Setting values that have been stored at GetSystemConfiguration method previously can be read from IPluginSite::Configuration property of the IPluginSite object received on Initialize method.
  • IPluginSite::Prompt method can show a user any messages about restoring. these messages will be shown on A status window of NCSwitch Professional.
  • In case of failing, you should call IPluginSite::Prompt method to send error messages. Result argument of this method should be set "0" (failed). (Return value should be S_OK.)

IPluginSite

This interface provides conversation with NCSwitch Professional.
Inherit interfaces IDispatch
ProgID NCSwitchLib.IPluginSite
IID 34A6BD3A-3A1A-4697-9287-BF1A432FA66D
IPluginSite::Locale
Retrieve string that stands for locale of NCSwitch Professional.
[propget, id(1)] HRESULT Locale([out, retval] BSTR* pVal);
Arguments pVal - Locale of NCSwitch Professional ("ja": Japanese, "en": English)
IPluginSite::Parameter
Retrieve configurations of the NCSwitch Plugin.
[propget, id(2)] HRESULT Parameter([out, retval] IDictionary** pVal);
Arguments pVal - Configurations of the NCSwitch Plugin
Comments Configurations of the NCSwitch Plugin corresponds to values of <Parameter> tag into plugin.xml.
IPluginSite::Configuration
Read/write setting values via associated array.
[propget, id(3)] HRESULT Configuration([out, retval] IDictionary** pVal);
Arguments pVal - A setting value
Comments
  • Setting values are written in this property by IPlugin::GetSystemConfiguration method implementation.
  • Setting values are read from this property by IPlugin::SetSystemConfiguration method implementation.
IPluginSite::PluginPages
Retrieve a list of form windows, and add a form window into the list.
[propget, id(4)] HRESULT PluginPages([out, retval] IPluginPages** pVal);
Arguments pVal - A list of form windows as PropertyPage objects.
Comments Form windows will be used only if it is necessary to get user inputs when NCSwitch Wizard is in process.
IPluginSite::Prompt
Send status messages or error messages.
[id(20)] HRESULT Prompt([in] long priority, [in] BSTR message);
Arguments
priority - A sort of message (0:Information, 1:Warning, 2:Notice)
content of the message
Comments This method will be called by any IPlugin methods implementations of your plugin.
IPluginSite::ConfigurationXml 《*Version2 or later》
Read/write setting values via XML
[propget, id(5)] HRESULT ConfigurationXml([out, retval] BSTR* pVal);
[propput, id(5)] HRESULT ConfigurationXml([in] BSTR pVal);
Arguments pVal - Setting values as XML form
Comments This property is different from IPluginSite::Configuration. This form is a XML, another is an associated array. NCSwitch Plugin can use these either way (or both).
  • Setting values are written in this property by IPlugin::GetSystemConfiguration method implementation.
  • Setting values are read from this property by IPlugin::SetSystemConfiguration method implementation.
IPluginSite::PreviousConfiguration 《*Version2 or later》
Retrieve setting values that have stored previously.
[propget, id(6)] HRESULT PreviousConfiguration([out, retval] IDictionary** pVal);
Arguments pVal - A setting value
Comments This property provides setting values that have been stored previously by IPlugin::GetSystemConfiguration method implementation. This property is useful that your plugin decides to set default values on form windows according to previous setting values.
IPluginSite::Version 《*Version2 or later》
Retrieve version number of IPluginSite.
[propget, id(7)] HRESULT Version([out, retval] long* pVal);
Arguments pVal - Version number (2:NCSwitch 3.1 or NCSwitch Professional 1.0 )
IPluginSite::GetPrivateFilePath 《*Version2 or later》
Retrieve full path of a file that is used to write/read setting values.
[id(21)] HRESULT GetPrivateFilePath([in] BSTR name, [out, retval] BSTR* pPath);
Arguments name - File identifier pPath - Full path of a file
Comments
  • If setting values will be large (about 100KB or above), this method should be used rather than IPluginSite::Configuration or IPluginSite::ConfigurationXml. You can exchange setting values via file.
  • A file this method provides will be written by IPlugin::GetSystemConfiguration method implementation. (IPlugin::GetPrivateFilePath method returns full path of a file that is empty (0 byte) and writable.
  • A file this method provides will be read by IPlugin::SetSystemConfiguration method implementation. (IPlugin::GetPrivateFilePath returns full path of a file that can be read and contains setting values written by IPlugin::GetSystemConfiguration method implementation.

IDictionary

This interface provides associated array features to read/write various values, such as NCSwitch Plugin configurations, setting item values, and so on.
Inherit interfaces IDispatch
ProgID NCSwitchLib.IDictionary
IID F3520743-F03B-4D49-9BBB-013887F45419
IDictionary::Item
Read/write an item into associated array.
[propget, id(0)] HRESULT Item([in] BSTR key, [out, retval] BSTR* pVal);
[propput, id(0)] HRESULT Item([in] BSTR key, [in] BSTR newVal);
Arguments key - Item key string
pVal - Current item value
newVal - New item value
IDictionary::Count
Retrieve count of associated array.
[propget, id(1)] HRESULT Count([out, retval] long* pVal);
Arguments pVal - Count of form windows.
IDictionary::IsExist
Check whether the key has been already exist in associated array.
[id(2)] HRESULT IsExist([in] BSTR key, [out,retval] VARIANT_BOOL* pVal);
Arguments key - Item key string
pVal - TRUE: The key is already exist. /FALSE: The key isn't exist.
IDictionary::Clear
Clear all items (key and value pairs) in associated array.
[id(3)] HRESULT Clear();
Arguments (None)

IPluginPages

This interface provides a list where form windows are registered.
Inherit interfaces IDispatch
ProgID NCSwitchLib.IPluginPages
IID 4E11DE89-2E12-4890-95B4-30EE9FD63CF9
IPluginPages::Item
Retrieve a form window.
[propget, id(0)] HRESULT Item([in] long index, [out, retval] IPropertyPage** pVal);
Arguments index - Index
pVal - Retrieved item
IPluginPages::Count
Retrieve count of form windows.
[propget, id(1)] HRESULT Count([out, retval] long* pVal);
Arguments pVal - Count of form windows.
IPluginPages::Add
Register a form window.
[id(2)] HRESULT Add([in] IPropertyPage* newVal);
Arguments newVal - Form window(PropertyPage)
Comments
  • To register two and above form windows, you can call this method per form window.
IPluginPages::Clear
Delete all items into collection.
[id(3)] HRESULT Clear();
Arguments (None)