SETUP. First of all,
please check that you find side by side wizapi32.dll and scriptez.dll
in the same folder. Then, you need to register the COM scriptez.dll file under Windows like
this: regsvr32.exe scriptez.dll ( from within a command line
prompt - aka DOS console black window ) which will display the following
message box. Sometimes, to resolve the
reason why registration fails under Windows 8.x and Windows 10, DOS console
should be started as an Administrator user before running regsvr32.exe
scriptez.dll Otherwise, in the case where
registering fails because of administrative restrictions (due to a
lockdown policy) on a computer, you can use and configure manifest XML
files such like here.
Moreover, thanks to the Registration-free
technology which was introduced
into Windows XP SP2 up to recent Windows flavours, you can actually embed a manifest file into a target .exe file with Manifest
Tool (mt.exe) in order to facilitate side by side deployment of
applications. Indeed, you can additionally
use another tool application called Manifest
File Maker (aka ManifestFileMaker.exe
which is included with the Setup package) to find and/or to generate
interactively manifest files for any application and any COM DLL file: ScriptEZ.API component can be
instantiated with two ways. The first one creates the main object
which contains IAPI interface where properties and methods can
directly be invoked; the second one creates the main object and installs a callback
interface named _IAPIEvents where client code must or can
implement some of callback functions, so the component will be asynchronously
able to forward or to exchange status, messages and behaviour at runtime. (1) Instantiating ScriptEZ.API object with VBScript: ’ Example 1: instantiate
component object Set ScriptEZ = WScript.CreateObject("ScriptEZ.API") ’ Or Set ScriptEZ = CreateObject("ScriptEZ.API") ’ Example 2:
instantiate component object with callback interface Set ScriptEZ = WScript.CreateObject("ScriptEZ.API","ScriptEZ_") ScriptEZ.AppRegister ' Activate Remoting Control Interface … Function
ScriptEZ_AppEventHelp()
ScriptEZ_AppEventHelp = CStr(“Self documentation here”) End
Function (2) Instantiating ScriptEZ.API object with Visual
Basic 6.0: Execute “Project/References” command, browse and select ‘ScriptEZ
1.0 Type Library’ as following: ‘ Example 1 Option Explicit Public ScriptEZ As API ' Form load event Public Sub Form_Load()
Set ScriptEZ = New API
ScriptEZ.AppRegister ' Activate Remoting
Control Interface End Sub ‘ Example 2 Option Explicit Public WithEvents ScriptEZ
As API ' Form load event Public Sub Form_Load()
Set ScriptEZ = New API ScriptEZ.AppRegister ' Activate Remoting Control Interface End Sub Private Function
ScriptEZ_AppEventHelp() As String
ScriptEZ_AppEventHelp = "Hello World !"
+ vbLf + "...I am a VB6 Application." End Function (3) Instantiating ScriptEZ.API object with PHP 5.3.x: // Example 1 // create component object $ScriptEZ = new
COM("ScriptEZ.API"); // Example 2 class
ScriptEZ_EventHandlers {
// Remoting Control Interface
function AppEventHelp()
{
$AppEventHelp = " **** Supported AppEvents ****"
. "\n" . "AppEventID = 3" . "\t" . "to exit" . "\n";
return $AppEventHelp;
} … } // create component object and event sink
class $ScriptEZ = new
COM("ScriptEZ.API"); $sink
= new ScriptEZ_EventHandlers(); $ScriptEZ->AppRegister(); // Activate Remoting Control Interface // install event sink class com_event_sink($ScriptEZ,
$sink, "_IAPIEvents"); (4) Instantiating ScriptEZ.API object with C/C++: HRESULT hr; //
Init MTA (Multi Thread Apartment) hr
= ::CoInitializeEx(NULL,COINIT_MULTITHREADED); CIAPIEventsSink *pIAPIEventsSink; DWORD dwAdvise; //
instantiate a ScriptEZ.API object hr
= CoCreateInstance(CLSID_API,NULL,CLSCTX_INPROC,IID_IAPI,(void**)&pIAPI); if(hr == S_OK) {
pIAPI->SetConsoleTitle(L"ScriptEZ.API Demo App in C++: TCP/IP
& ThreadPool Usage");
/// Installing connection point (callback in COM/DCOM way) IConnectionPointContainer *pcpc = NULL; IConnectionPoint *pcp = NULL; hr = pIAPI->QueryInterface(IID_IConnectionPointContainer,(void**)&pcpc);
if(SUCCEEDED(hr)) {
hr = pcpc->FindConnectionPoint(DIID__IAPIEvents,&pcp);
if(SUCCEEDED(hr))
{
pIAPIEventsSink = CreateIDispatchEventObjectEx<CIAPIEventsSink>(DIID__IAPIEvents);
hr = pcp->Advise((IUnknown*)pIAPIEventsSink,&dwAdvise);
} } } (5) Instantiating ScriptEZ.API object with .NET Framework
can be done through COM Interop. (please, refer to provided samples in VB.NET…) (6) Instantiating ScriptEZ.API object with C#: Here is an excerpt of code in C# from a simple Console Application
(provided among other samples) which is using ScriptEZ.API component’s methods and properties. It is illustrating
the use of the remote control
interface, the use of a
thread pool, the use of auto-restarting
app mechanism (crash resilience) and so on, from ScriptEZ.API. using System; using System.Threading; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using SCRIPTEZLib; namespace ConsoleApp {
class Program
{ public static SCRIPTEZLib.API scriptEZ; public static COMEventSink comSink; public static
System.Runtime.InteropServices.ComTypes.IConnectionPoint icp; public static int cookie; public static bool exitApp = false; public static int[] task_exec_counter = new int[7];
// Multi-threaded context.... [MTAThread] static void Main(string[] args) { Thread oThread = new Thread(new ThreadStart(ThreadStart)); oThread.SetApartmentState(ApartmentState.MTA); oThread.Start(); while (!exitApp) { ///
Yielding control Thread.Sleep(10); } if (comSink.watchDogProcessID > 0) { scriptEZ.Terminate(comSink.watchDogProcessID); } // 4. Uninstall COM Event Sink icp.Unadvise(cookie); oThread.Abort(); } /// <summary> ///
.NET thread procedure /// </summary> public static void ThreadStart() { ///
Instantiating the COMponent object scriptEZ = new SCRIPTEZLib.API(); if (scriptEZ != null) { ///
Mapping affinity to CPU Core1 scriptEZ.SetCPUCoreAffinity("0"); ///
Just an echo scriptEZ.Echo("Who said...that
COM became \"has been\" ?!"); ///
Setup Remote Control Interface scriptEZ.AppRegister(""); /// Instantiating
and setting up the COM Event Sink (callback) comSink = new COMEventSink(); comSink.scriptEZ =
scriptEZ;
System.Runtime.InteropServices.ComTypes.IConnectionPointContainer icpc; //
1. Search for Connection point container icpc =
(System.Runtime.InteropServices.ComTypes.IConnectionPointContainer)scriptEZ; Guid IID_IAPIEvents = typeof(_IAPIEvents).GUID; //
2. Search for a Connection point
icpc.FindConnectionPoint(ref IID_IAPIEvents, out icp); //
3. Handshaking COM Event Sink with the Connection point icp.Advise(comSink,
out cookie); ///
Create a pool of 4 threads for executing 2 jobs int threadPool = scriptEZ.get_CreateTaskQueueObject(4); for (int i = 1; i <= 7; i++) { scriptEZ.get_AddTask(threadPool,i);// Task#i } } }
}
/// <summary>
/// Implementing _IAPIEvents callback interface (early
binding)
/// Note that all functions must be declared and defined, even though NOT
USED.
/// </summary>
class COMEventSink : _IAPIEvents
{ public int watchDogProcessID = 0; public SCRIPTEZLib.API scriptEZ; //////// Application /////////// public string AppEventHelp() { string task_exec = "Tasks
execution counter:\n"; for (int i = 0; i < 7; i++) { task_exec = task_exec + " .TaskID " + (i+1).ToString() + " executed " + Program.task_exec_counter[i].ToString() + " times\n"; } return "Welcome in a
COM World !\n<Enter>\n" + " -9 to exit gracefully the program\n" + " 8 to
enable auto-restart feature\n" + (watchDogProcessID > 0
? "\nWatchdog
Process ID: " +
watchDogProcessID.ToString():"") + "\n" + task_exec;
} public void onAppEvent(int EventID) { switch (EventID) { case -9: Program.exitApp = true; break; case 8 : if(watchDogProcessID == 0) watchDogProcessID
= scriptEZ.get_AppAutoRestart(""); break; default: break; } } public int onTimer(int IDTimerEvent) { return 0; } //////// Thread pool /////////// public int onRun(int
task_local_storage) { scriptEZ.Sleep(300); Program.task_exec_counter[task_local_storage - 1]++;
System.Console.WriteLine(" TaskID:" + task_local_storage + " Pooled Thread ID: " + scriptEZ.GetCurrentPooledThreadId +
(task_local_storage == 2 ? " (Who said that COM has been ?!)":"")); if (task_local_storage == 2) { int currentProcessID = scriptEZ.GetCurrentProcessId; int ram = (scriptEZ.get_ProbeMemoryStatus(currentProcessID)); scriptEZ.SetConsoleTitle("Own used memory: " + ram.ToString() + " Bytes | Thread number:
" + scriptEZ.get_ProbeMemoryStatus(-4) + " | Open Handle number: " + scriptEZ.get_ProbeMemoryStatus(-7)); } return 1; } public void onAbort(int appID) { } //////// TCP/IP /////////// public int onConnectionRequest(int
hSocketClientObjectProxy) { return 0; } public int onConnectionState(int hOwnerSocket, string state_desc, int error_number) { System.Console.Write(state_desc + ":" + error_number.ToString() ); return 0; } public int onData(int hOwnerSocket, int raw_data, int data_size) { return 0; } //////// Named Pipe /////////// public int onConnectionRequestNamedPipe(int hNamedPipeClientObjectProxy) { return 0; } public int onConnectionStateNamedPipe(int hOwnerNamedPipe, string state_desc, int error_number) { System.Console.Write(state_desc + ":" + error_number.ToString()); return 0; } public int onDataNamedPipe(int hOwnerNamedPipe, int raw_data, int data_size) { return 0; } //////// ServerDoc Application /////////// public int onServerDocData(int DataRows, int RowCount, int DataSize) { return 0; } public int onServerDocStatus(int Status) { return 0; } } } |
|