Monday, April 06, 2009

How to get COM+ call times from VB and VBScript

How to get COM+ call times from VB and VBScript
Posted on Tuesday, April 12, 2005 5:39 PM
Original Article : http://www.egilh.com/blog/archive/2005/04/12/655.aspx

I posted earlier on how to get the com+ call times the unofficial way. Someone asked for a VB example so I put together a com+ call time toolkit that contains the com+ call time tracker and a VBScript example client. You can do a lot of neat stuff with it:

* Use it a ASP page to monitor the call time of your components live
* Use Cacti to show how average call time changes during the day.
* Use the COM+ Admin API to automatically shut down/recycle components with high call times

Installation

* Download the egilh Com+ Tracker
* Extract the files
* Register the DLL in COM+ or run regsvr32 EgilhComTracker.dll in the directory where you extracted the files

Usage
The egilh.ComTracker object only has one method: string getStatistics()

It returns a xml formatted string that contains information about all the running applications. The XML has the following layout:
/applications
/application
/classes
/class

Example:





{98CDBB6E-3CAF-46F2-ABE6-EABECD6AA4EB}

10

1792



0

0

1

1







Test.Sleep.1

1

0

-1

1

120

0

0









Test client
The following VB code shows the call times for all classes registered in com+ on the local machine.

Dim oTracker 'As Object

Dim sResult 'As String

Dim oDOM 'As DOMDocument30

Dim oNode 'As MSXML2.IXMLDOMNode



'Get the com+ call times

Set oTracker = CreateObject("egilh.ComTracker")

sResult = oTracker.getStatistics()

Set oTracker = Nothing



'Display call times

Set oDOM = CreateObject("MSXML2.DomDocument.3.0")

oDOM.loadXML (sResult)

For Each oNode In oDOM.selectNodes("/applications/application/classes/class")

WScript.echo oNode.selectSingleNode("progID").Text & _

" call time: " & oNode.selectSingleNode("responseTime").Text

Next




Feel free to drop a few cents in the tip jar if this post saved you time and money

Feedback
# re: How to get COM+ call times from VB and VBScript
5/3/2005 7:52 PM by Brian Skiles

You rock. You totally rock. I've been looking all day for information on how to get the call time to COM+ components programatically, and you've created the perfect tool. This is the only place I've found any helpful information, and it went beyond helpful to the point that it does everything I need. Thank you very much for creating this component.


# re: How to get COM+ call times from VB and VBScript
5/3/2005 10:29 PM by Egil Hogholt

Glad you found what you were looking for!

Let me know if you have suggestions for improving the component or if you find any bugs.


# re: How to get COM+ call times from VB and VBScript
5/5/2005 5:03 PM by Brian Skiles

I have no suggestions, as the XML document is the perfect return value and it has all of the information I need. I've been using it for a couple of days and it's working perfectly. Thanks again!



# re: COM Call Timers: the official way
5/12/2005 9:41 AM by /egilh




# re: How to get COM+ call times from VB and VBScript
7/9/2005 11:25 PM by Renato

How can i get the application name from the guid??


# re: How to get COM+ call times from VB and VBScript
7/28/2005 9:27 PM by Egil Hogholt

Sorry for the delay in getting back to you. Work as been very busy after coming back from vacation.

I never faced the problem before as the COMAdminCatalog APIs I use for recycling etc accept the GUID -OR- the application name.

You can use the following VBSCript to get the application name from the GUID:
Dim Catalog
Set Catalog = CreateObject("COMAdmin.COMAdminCatalog")

' Get list of COM+ applications
Set Applications = Catalog.GetCollection("Applications")
Applications.Populate

'List all GUIDs/Names
For Each AppObject In Applications
WScript.Echo AppObject.Key & "=" & AppObject.Name
Next


# re: How to get COM+ call times from VB and VBScript
8/4/2005 5:14 PM by David

Is It possible execute vb script from a host and get COM+ parameters from another host in the same domain?

Thanks, your tracker is good.


# re: How to get COM+ call times from VB and VBScript
8/5/2005 9:31 AM by Egil Hogholt

Everything is possible!

If you use VB instead of VBScript you can do it very easily. Just pass the optional "ServerName" argument. For example:
Set oTracker = CreateObject("egilh.ComTracker", "Server1")


The WScript.CreateObject() method does not accept a machine name so it is more difficult. If you only have one remote machine, you can do this:
- right click on the com+ package with egilh.ComTracker and choose "Export…"
- choose "Application proxy"
- install the generated proxy application on you machine
Note that this only works for -one- remote machine

There are other workarounds as well:
- Create an ASP page on each machine that calls egilh.ComTracker. Call the asp file from you pc using msxml and parse the output
- Schedule a script to run on each machine that writes to a file (or db). You can then read the generated data via the network
- Copy a vbscript file on each machine and use WSHController.CreateScript("cmd line", "machine name") to run the script remotely from your PC.

The simplest solution is to write a small application in VB6 or another "serious" language that allows you to create remote objects on the machine you specify



# re: How to get COM+ call times from VB and VBScript
8/9/2005 10:32 AM by David

I use VBScript to run Comtracker so I choose your second option: create a proxy application on client host to get call times.

When I access to Com+ application on client console I do'nt see any call to the components when in the sever host they are running. In client console call parameters are empty and components seem no run when I'm sure that they are been called in server host. On client host, "egilh.ComTracker" parses only components under "System Application" group that are running but doesn't give information about components in "my application".

I know there are other solutions (you show them in last post) but I prefer do'nt write on any file or database.

Thanks for your attention.


# re: How to get COM+ call times from VB and VBScript
8/9/2005 11:33 AM by Egil Hogholt

It seems like a configuration issue.

The comtracker must be installed in a COM+ "server application" on the server:
- Right click comtracker on the server in Component Services
- In the "Activation" tab. Select the "Server application" option as the "Activation type"
- In the Identity tab. Make sure it does not use the "interactive user" but one of the following:
Win2k3: System account, Local Service
Win2k: Use a valid domain user and password

Can you please double check that you created an "Application Proxy" and not a standard install package?
- Right click the comtracker on your PC
- Go to the "Activation" tab
- Verify that the "Remote Server name" contains the name of the server



# Blog anniversary
8/22/2005 11:06 PM by /egilh




# re: How to get COM+ call times from VB and VBScript
10/10/2005 6:48 PM by jtmoney

is it possible to automatically restart a component if it's call time reaches a certain value?


# re: How to get COM+ call times from VB and VBScript
10/11/2005 9:42 AM by Egil Hogholt

There is no built in way in Windows/COM+ to do this but you can do it with the comtracker:
- use egilh.comtracker to get the call times
- use the COM+ Admin APIs to shut down or recycle applications with high call times

The COM+ Admin API can be used from an NT service that polls the comtracker or you can schedule a VB Script to run every X minutes.

I will post an article later today on how to do this.


# How to shut down COM applications with high call times with VB and VBScript
10/11/2005 11:06 AM by /egilh




# re: How to get COM+ call times from VB and VBScript
10/12/2005 2:26 PM by John Ludring

When I run it, it says "getStatistics not supported by object". Any ideas?


# re: How to get COM+ call times from VB and VBScript
10/12/2005 2:44 PM by John Ludring

When i try to register your .dll, it just goes into a loop and tries to continueously register it, any ideas?


# re: How to get COM+ call times from VB and VBScript
10/12/2005 3:22 PM by John Ludring

Can you post the source code for the .dll?


# re: How to get COM+ call times from VB and VBScript
10/12/2005 3:56 PM by Egil Hogholt

John; which Operating System are you using and how did you register the comtracker?

Let me know if the following steps work for you:
- Add a new Application with the "Component Services" console:
- Name: Comtracker
- Type: Server Application
- User: "Local Service" on Win2k3. Specify a user + password on Win2k
- Add egilhComtracker.dll to the new application

The complete source code for the DLL is not available. All the info you need can be found in this post: http://www.egilh.com/blog/archive/2005/02/25/557.aspx


# re: How to get COM+ call times from VB and VBScript
11/15/2005 10:04 PM by dio

Hi Egil,
After looking and looking and looking all over the web I finally found your blog (10x god!!!)
Great code !!!

(I am using the C# code which was given in one of the comments...)
Is there a way to create AppData of a remote server ? (using c# and without installing the dll on the remote server)

again - thank you for your code (and to your friend in microsoft...hhh)




# re: How to get COM+ call times from VB and VBScript
11/15/2005 10:28 PM by Egil Hogholt

Hi Dio, I am glad you found the code useful!

You have to install the DLL (my pre-compiled DLL in this post or the .NET version) on -each- machine where you want to collect the data. You can then call the component from a central data collection machine using DCOM or other methods for calling remote components. The DLL talks to the local COM+ environment to get the call time information so it -must- run on the machine where you collect the data.

I am afraid I have to disappoint a second time: I -wish- someone in Microsoft gave me this information as it would have saved me a lot of hard work. I spent a lot of time hunting in the SDKs and the undocumented entry points in the com+ DLLs before I found what I needed to get the call time information.


# re: How to get COM+ call times from VB and VBScript
12/30/2005 3:47 PM by Erickson

Great!!! I search this information for a week. Thank you! But, I tried to use your function in a console application compiled in Visual C++ 6.0/Windows XP SP2 and whenever I run application I receive the message "abnormal program termination". Is There anything I want to configure in Visual C++ 6.0, any Dll to import?

Thank you again.


# re: How to get COM+ call times from VB and VBScript
12/31/2005 10:25 AM by Egil Hogholt

Does the VB Script example above work? If it works, there is a problem in your client program. I will send you a mail offline to see if we can resolve the problem.


# re: How to get COM+ call times from VB and VBScript
2/1/2006 5:35 PM by Egil Hogholt

Problem solved; the code was missing CoInitialize() which is required when calling COM+ objects like the COM+ Tracker


# re: COM Call Timers: the official way
2/1/2006 6:40 PM by /egilh




# egilhComTracker: Free component to track com call times with
2/2/2006 8:23 PM by /egilh




# re: How to get COM+ call times from VB and VBScript
2/20/2006 6:05 AM by BD

hi there i not that good with scripting but could someone show me how to get call times for specific Program ID or method calls.


# re: How to get COM+ call times from VB and VBScript
2/20/2006 8:32 AM by Egil Hogholt

You can only get call times per object, not for the individual methods in that object.

The com+ tracker returns information about all running applications. You can use the script in the post above and modify the loop like this to filter a particular prog id:

For Each oNode In oDOM.selectNodes("/applications/application/classes/class")
If "my.progid" = LCase(oNode.selectSingleNode("progID").Text) then
WScript.echo oNode.selectSingleNode("progID").Text & _
" call time: " & oNode.selectSingleNode("responseTime").Text
End If
Next


# re: How to get COM+ call times from VB and VBScript
2/22/2006 11:56 AM by BD

Thank you so much that was what i was after, not familiar with XML and didn't know the syntaxes to parse out a particular program's call time.

Once again thank you


# re: How to get COM+ call times from VB and VBScript
2/22/2006 11:31 PM by BD

Sorry to bother again, could you be able to provide an example vb script to only retrieve data from a particular application. Just say if Application GUID = xxxxxxx-xxxx-xxxx-xxxxx-xx-xxxx then get all all the response times for each component of that application.



thanks
BD



# re: How to get COM+ call times from VB and VBScript
2/23/2006 9:55 PM by Egil Hogholt

Even simpler.

If you only want -one- application, you can modify the loop from this:
For Each oNode In oDOM.selectNodes("/applications/application/classes/class")

To this:
For Each oNode In oDOM.selectNodes("/applications/application[@guid='{xxxxxxx-xxxx-xxxx-xxxxx-xx-xxxx}']/classes/class")

NB! XML is case sensitive so you must spell the GUID correctly.



# re: How to get COM+ call times from VB and VBScript
2/24/2006 12:40 AM by BD

Cool thanks heaps, didn't really know how to put in the correct xpath better start learning some XML basics. thanks again


# re: How to get COM+ call times from VB and VBScript
5/30/2006 1:26 PM by Igor

Hi Egil,
first, Thank's for You for very good and useful tool,
and, my question:
may this tool (egilhCOMTracker.dll) be cause for: routinely (1-2 times per day),
com+ statistics from mmc (component services) not show..
com+ applications are runing (our user are working ..:-),
but statistics is not show..
Restart system application lead to correct this problem (on some time..)
Our system Win2003EE (withot SP1) and we are runing egilhCOMTracker.vbs
sufficiently frequently (1 time per 5 seconds - for our com+ monitoring system)
For Win2000 machines we are not have similar problems..
May be a com+ 1.5 bug ?
Yours sincerely,
Igor Matukin, Russia.



# re: How to get COM+ call times from VB and VBScript
5/30/2006 10:16 PM by Egil Hogholt

I have not seen this problem before myself but I will check and let you know ASAP.


# re: How to get COM+ call times from VB and VBScript
5/31/2006 8:26 AM by Igor

Hi Egil,
Thank's, we are download and install for test environment
Windows Server 2003 Post-Service Pack 1 COM+ 1.5 Hotfix Rollup Package 8
(http://support.microsoft.com/?kbid=912818
http://download.microsoft.com/download/a/a/b/aab2fc8c-7fb1-4b6a-a4ce-5a77f174af57/WindowsServer2003-KB912818-v3-x86-ENU.exe)
In KB 910730 (Hotfix Rollup Package 7) see .. FIX: Statistics may not display correctly for some COM+ applications on a computer that is running Windows Server 2003..
FIX: A COM+ application stops responding, and desktop icons and the taskbar may not appear as expected on a computer that is running Windows Server 2003..
..end etc.
Yours sincerely,
Igor Matukin, Russia.


# re: How to get COM+ call times from VB and VBScript
5/31/2006 9:58 AM by Egil Hogholt

Looks like it should fix your problem. Please let me know if it works or not.

Thanks,
Egil


# re: How to get COM+ call times from VB and VBScript
8/15/2006 3:49 PM by Andy Jones

Is there a way of amending the app to get the call times from another system? Ie, run it on my local machine but get the values of another system on the same network?


# re: How to get COM+ call times from VB and VBScript
8/16/2006 12:18 PM by Egil Hogholt

You can collect remote data with the existing ComTracker. First you have to install the ComTracker on all the machines you want to collect data from. Then you can use DCOM to create the object on the remote machine(s).

The syntax depends on which programming language you use. With VB, you can write it like this:
Set oTracker = CreateObject("egilh.ComTracker", "Server1")

The object then runs and returns data from the remote machine.


Let me know if that is an acceptable solution for you or if I should extend the egilh.ComTracker with a getRemoteStatistics("ServerName") method.



# re: How to get COM+ call times from VB and VBScript
8/22/2006 10:54 AM by Ardian


I am trying tu use your component from a remote server (Set oTracker = CreateObject("egilh.ComTracker", "Server1")
) but this call doesn't work. Any idea to help me?
thank you.


# re: How to get COM+ call times from VB and VBScript
8/22/2006 11:39 AM by Egil Hogholt

What error message do you get?


# re: How to get COM+ call times from VB and VBScript
8/22/2006 1:02 PM by Ardian


The error is:
test.vbs(7, 1) Microsoft VBScript runtime error: ActiveX component can't create object: 'Egilh.ComTracker'



# re: How to get COM+ call times from VB and VBScript
8/22/2006 1:50 PM by Egil Hogholt

Did you register the egilh.ComTracker component on both machines?

The component will run on the remote machine but it must be installed locally as well so DCOM knows which methods it implements.



# re: How to get COM+ call times from VB and VBScript
8/22/2006 2:04 PM by Ardian


yes the component is registered in both machines, and dcom is enabled. My account is administrator on both machines. Locally all is working fine on both machines.


# re: How to get COM+ call times from VB and VBScript
8/22/2006 3:42 PM by Egil Hogholt

Hm...
Some more questions to narrow down the problem
- are you able to launch other components registered on the remote machine?
- is the component registered in "Component services" or did you register it with regsrv32?
- if it is in component services; does the application hosting the component start when you call it from the remote machine?






# re: How to get COM+ call times from VB and VBScript
8/22/2006 4:30 PM by Ardian


-yes i can create other objects in the remote server.
-the component is registered with regsvr32 command.
-i tried to call it under the "component services", the application hosting the component doesn't started.
-i am using win 2000 servers for my test.
-error in the event viewer:
DCOM got error "Class not registered " from the computer server1 when attempting to activate the server:
{8D7E7FDC-4D16-48DF-BDC9-B2C0493E36BF}


# re: How to get COM+ call times from VB and VBScript
8/22/2006 5:19 PM by Egil Hogholt

It looks like the component is registered with two different class IDs which is strange since it is the same DLL.

Can you look in the registry on -both- machines to see which component uses the class ID {8D7E7FDC-4D16-48DF-BDC9-B2C0493E36BF}?
You should find it under HKEY_CLASSES_ROOT\CLSID\

It could be a registration problem; i.e. it is registered in "component services" on the client but not on the server. If so, the following steps on both machines should fix it:
- remove the component from "component services"
- run regsvr32 /u egilhComTracker.dll
- run regsvr32 egilhComTracker.dll

If you want to use "component services" you have to follow the steps earlier in this post and generate an "application proxy".


# re: How to get COM+ call times from VB and VBScript
9/6/2006 4:41 PM by cyboman

Hey, thanks for doing this. I noticed that on my system (Win2000 server) when I regsvr32 the dll I get

"LoadLibrary("egilhComTracker.dll") failed - Access is denied."

I tried it on another system and it works though.

Also, when I load it in to com services on my system I get.

"The DLL could not be loaded. Check to make sure all required application runtime files and other dependent DLLs are available in the component DLL's directory or the system path."

Any idea. Thanks.





# re: How to get COM+ call times from VB and VBScript
9/6/2006 10:49 PM by Egil Hogholt

The first error sounds like a security error. Can you please verify that you have administrator rights on the Win2k machine where you try to register the component?

The problem could also be that some of the the C++ run time dlls required by the component is missing. Can you please check if you have the following files in \windows\system32 directory?
atl71.dll
msvcr71.dll
msvcp71.dll



# re: How to get COM+ call times from VB and VBScript
9/15/2006 10:20 PM by cyboman

Thanks for responding. I do have those files and I am in the administrator group on this computer. I should also mention that I don't have this problem with the DLL files I compile with VB. I was able to get this dll to register on another computer however. My computer isn't exactly in great health (I have to reboot it every day) so maybe I will just develop my solution on a different machine. Thanks.

COM+ Call Timers: the unofficial way

COM+ Call Timers: the unofficial way
Posted on Friday, February 25, 2005 5:32 PM
Original Article at : http://www.egilh.com/blog/archive/2005/02/25/557.aspx
Not satisfied with the official way, I went looking for a simpler way. The Component Services Console displays the data so the information must be there somewhere. It is a waste of time and resources me to collect the data and calculate the call times when the information I want is already available.

As it turns out the unofficial way is a lot simpler to implement than the official way.

Step 1: include the comsvc.dll library
// ComSvcs library for internal com+ method call tracking
#import "c:\windows\system32\comsvcs.dll" exclude("IAppDomainHelper")

Step 2: get the statistics

* Get an instance of the internal com+ tracker: COMSVCSLib::IGetAppDataPtr ptrAppData(_T("{ecabafb9-7f19-11d2-978e-0000f8757e2a}"));
* Get a list of applications and lop through them: ptrAppData->GetApps(&nAppData, &appData);
o Get the application data you are interested in: calls per second, total calls, etc
o Get a list of classes in the application and loop on them, extracting the information you want: ptrAppData->GetAppData(oneApp.m_idApp, &nClsIDs, &aClsidData);

Example
This simple routine builds a XML string the brutal way with the com+ performance information (most error handling code removed for clarity)

/*

Get the statistics from the hidden COM+ interface

*/

void CTracker::getStatistics(BSTR *output)

{

const unsigned long MAX_APP_DATA = 500;

const unsigned long PUSH_RATE = 1000;



unsigned long nAppData = MAX_APP_DATA;

LPSTR lpString;

LPWSTR lpwString;



COMSVCSLib::appData *aAppData;



CString csStatistics = "";



// Get an instance of the internal com+ tracker objet

COMSVCSLib::IGetAppDataPtr ptrAppData(_T("{ecabafb9-7f19-11d2-978e-0000f8757e2a}"));

csStatistics.Append("\r\n");



// Step through the list of running application

ptrAppData->GetApps(&nAppData, &aAppData);

for (unsigned long idxApp=0; idxApp < oneapp =" aAppData[idxApp];" appstatistics =" oneApp.m_AppStatistics;">GetAppData(oneApp.m_idApp, &nClsIDs, &aClsidData);

csStatistics.AppendFormat(_T("\r\n"));

for (unsigned long idxClass = 0 ; idxClass < oneclass =" aClsidData[idxClass];" output =" csStatistics.AllocSysString();">
/// Summary description for ComMonitor.
///
public class ComMonitor
{
static public void GetData()
{
// Get an instance of the internal com+ tracker objet
Type comPlusTrackerType = Type.GetTypeFromCLSID(new System.Guid("{ecabafb9-7f19-11d2-978e-0000f8757e2a}"));
COMSVCSLib.IGetAppData getAppData = (COMSVCSLib.IGetAppData)Activator.CreateInstance(comPlusTrackerType);

// Step through the list of running application
uint appCount;
IntPtr appDataPtr = new IntPtr();
unsafe
{
getAppData.GetApps(out appCount, new IntPtr(&appDataPtr));
}
int appDataSize = Marshal.SizeOf(typeof(COMSVCSLib.appData));
for(int appIndex=0; appIndex> 8);
}
string s= System.Text.UnicodeEncoding.Unicode.GetString(buf);
return s;
}
}
}


# re: COM+ Call Timers: the unofficial way
6/3/2005 4:09 PM by Mark

Whoops, forgot to Release the getAppData COM object. Add this at the end:

Marshal.ReleaseComObject(getAppData);


# re: COM+ Call Timers: the unofficial way
6/6/2005 9:45 AM by Egil Hogholt

Thanks for sharing the C# version!



# re: COM+ Call Timers: the unofficial way
7/8/2005 11:50 PM by Renato

Im trying to compile this c# source usingo this command line:

csc /r:\WINNT\system32\comsvcs.dll test.cs

But im getting this error:

fatal error CS0009: Metadata file 'c:\WINNT\system32\comsvcs.dll' could not be
opened -- 'There isn't metadata in the memory or stream'

does anyone could help me?


# re: COM+ Call Timers: the unofficial way
7/26/2005 8:48 AM by Muhammad Rizwan

Egil Hogholt u seems to be an angel for us. You have solved my assignment. You are great.

Thanks,

Rizwan


# re: Renato problem
7/26/2005 9:05 AM by Muhammad Rizwan

Renato ,
First of all you have to you use Microsoft "TlbImp.exe" tool to create "Interop.COMSVCSLib.dll" file from "comsvcs.dll" file.

Then u can compile with Visual Studio .NET 2003 Command Prompt like that:

csc /unsafe /reference:Interop.COMSVCSLib.dll /out:TestExe.exe test.cs

I hope it helps you clarify ur thoughts.

Regards,
Rizwan
Ultimus Inc.


# re: COM+ Call Timers: the unofficial way
7/26/2005 9:55 PM by Egil Hogholt

Thanks Rizwan for sharing the solution to the C# issue.

I am up to my neck in work after my vacation (http://www.egilh.com/blog/archive/2005/07/17/1171.aspx) so I still have to catch up with all the comments and request for help.


# re: COM+ Call Timers: the unofficial way
9/22/2005 8:29 PM by Renato

Thanks, Muhammad... i tried to add a reference to COMSVCSLib with visual studio .net and it worked fine... and im using the toguether with COMAdminCatalog to get the application names...

Buuuuttt now there is a new question: im getting a few counters, like response time, with 4294967295 (full usigned long).... whats it mean? can you help me?

thanks...

Renato


# re: COM+ Call Timers: the unofficial way
9/23/2005 10:18 AM by Egil Hogholt

Can you post the entire XML fragment of the counter?

4294967295 is the unsigned value of -1 which I believe is an error value. Do you always see the value 4294967295 for the same counter or do you only see it once in a while, for example when a package is being recycled?


# How to shut down COM applications with high call times with VB and VBScript
10/11/2005 11:06 AM by /egilh




# How to recycle com applications with high call times using .NET
10/11/2005 12:06 PM by /egilh




# re: How to get COM call times from VB and VBScript
10/12/2005 4:56 PM by /egilh




# How to track down performance problems in COM applications
10/26/2005 4:41 PM by /egilh




# re: COM+ Call Timers: the unofficial way
12/12/2005 11:02 PM by Iddo

After reading this great page I decided to make a little tool based on the C# source code.
I posted the entire solution and a little article at CodeProject web site.
"Comonitor - A COM+ Monitor" - http://www.codeproject.com/csharp/ComonitorProject.asp
Thank you Egil for your great code which inspired me to create this tool.

Iddo


# re: COM+ Call Timers: the unofficial way
12/13/2005 7:26 PM by Egil Hogholt

Way cool!

The following posts show how to recycle or shut down applications for those that want to implement their own version:
- VBScript: http://www.egilh.com/blog/archive/2005/10/11/1328.aspx
- .NET: http://www.egilh.com/blog/archive/2005/10/11/1331.aspx


# egilhComTracker: Free component to track com call times with
2/2/2006 8:23 PM by /egilh




# egilhComTracker: Free component to track com call times with
2/3/2006 8:43 AM by /egilh




# re: COM+ Call Timers: the unofficial way
2/6/2006 10:45 PM by Igor

First, I want to thank Egil and Mark for sharing their great code. Mark's C# code is almost what I need.
I want to monitor call times on a series of remote servers where COM+ applications are installed. I found a few suggestions on the related thread ("How to get COM+ call times from VB and VBScript"), but I don't feel any of those would work for me. What I need is some way to connect to a remote server without doing anything on the server itself. After all, COM+ explorer is capable of connecting to remote servers and getting all information that you can see there for your local computer. When you use ComAdmin classes and want to connect to a remote server, one line of C#

new ComAdmin.ComAdminCatalog().Connect(servername);

(after you added a reference to comadmin.dll) brings you there. I expect to have something similar in comcvcs.dll, but I cannot find it.

Thank you for any suggestion,
Igor


# re: COM+ Call Timers: the unofficial way
2/7/2006 3:58 PM by Egil Hogholt

Comsvcs is a COM object so you can call it on a remote machine using DCOM. Pass the server name you want to reach as an argument to GetTypeFromProgID() or GetTypeFromCLSID()

Modify the C# code above like this:
Type comPlusTrackerType = Type.GetTypeFromCLSID(
new System.Guid("{ecabafb9-7f19-11d2-978e-0000f8757e2a}"),
"myserver");



# re: COM+ Call Timers: the unofficial way
2/8/2006 1:54 AM by Igor

Thanks a lot, Egil. That was fast and to the point, as simple as I hoped, and, the main thing, perfectly working as expected.

This is what I finally got. I took Mark's C## code and made the following changes:
- I added Main function that gets the server name from the command line, which should now be [ server=]. If server parameter is omitted, the local computer is implied. Otherwise, the application tries to connect to the remote computer.
- I added some exception handling that would most likely come into play when the server name is misspelled.
- Using COMAdmin objects, I got the names of the applications and the progIDs of the components. That makes it much handier to browse the output.
- I had to make a light fix to GetString method and a few other lines to make them work for me.

To compile the code, you need to allow, as Mark indicated, unsafe code and to add references to the 2 COM objects: comsvcs.dll and comadmin.dll.

using System;
using System.Runtime.InteropServices;
using COMSVCSLib;
using COMAdmin;

namespace ptdpc
{
public class ComMonitor
{
static public void GetData(string server)
{
try
{
// Get an instance of the internal com+ tracker object
Type comPlusTrackerType = Type.GetTypeFromCLSID(new System.Guid(
"{ecabafb9-7f19-11d2-978e-0000f8757e2a}"),server);
IGetAppData getAppData = (IGetAppData)Activator.CreateInstance(comPlusTrackerType);

ICOMAdminCatalog catalog = (ICOMAdminCatalog)new COMAdminCatalogClass();

if (server != null)
{
catalog.Connect(server);
}
ICatalogCollection apps = (ICatalogCollection)catalog.GetCollection("Applications");
apps.Populate();

// Step through the list of running application
uint appCount;
IntPtr appDataPtr = new IntPtr();
unsafe
{
getAppData.GetApps(out appCount, new IntPtr(&appDataPtr));
}
int appDataSize = Marshal.SizeOf(typeof(COMSVCSLib.appData));
for(int appIndex=0; appIndex> 8);
}
return System.Text.UnicodeEncoding.Unicode.GetString(buf).TrimEnd('\0');
}

[STAThread]
static void Main(string[] args)
{
const string prefix = "server=";
string server = null;
foreach (string arg in args)
{
if (arg.StartsWith(prefix))
{
server = arg.Substring(prefix.Length);
break;
}
}
GetData(server);
}

static ICatalogObject FindCatalogObjectByValue(ICatalogCollection coll, string name, string val)
{
ICatalogObject iObj = null;
foreach (ICatalogObject obj in coll)
{
if (obj.get_Value(name).ToString() == val)
{
iObj = obj;
break;
}
}
return iObj;
}
}
}



# re: COM+ Call Timers: the unofficial way
2/8/2006 7:21 AM by Egil Hogholt

Cool.

Thanks for sharing the updated code.


# re: COM+ Call Timers: the unofficial way
3/14/2006 5:32 PM by David

This is great info. Exactly what I was looking for. Does anyone know of any issues using the COMPlusTrackerType on Windows 2000 Server? I have used ComAdmin.dll and had to import the type library separately for windows 2000 vs. 2003.

Any help is greatly appreciated.


# re: COM+ Call Timers: the unofficial way
3/14/2006 8:08 PM by Egil Hogholt

I have not tested the code on Win2k. Let me know if you have problems, and I will test it on a Win2k virtual machine.


# re: COM+ Call Timers: the unofficial way
3/14/2006 8:59 PM by David

Hi Egil. Thanks for the reply.

After submitting my post I went ahead and tested it on Win2k. XP & 2003 work with no issues but when attempting to run on Win2k I'm getting the following error "Value cannot be null. Parameter name: type"






# re: COM+ Call Timers: the unofficial way
3/15/2006 8:00 PM by Egil Hogholt

Hi David.
I was at a conference today so I did not have a chance to test it on Win2k. I will try it on Win2k tomorrow to see if the GUID has changed or if it is not supported.

The official way [http://www.egilh.com/blog/archive/2005/02/24/552.aspx] works on Windows 2000 for sure. The problems I encountered with the official approach could be bugs in my code or due to the extreme load on the machines.



# re: COM+ Call Timers: the unofficial way
3/15/2006 10:20 PM by David

Thanks Egil. Just to make sure you are aware, I used the c# code under .Net framework 1.1 on all 3 platforms.


# re: COM+ Call Timers: the unofficial way
3/16/2006 10:42 AM by Egil Hogholt

I tried the egilhComTracker [http://www.egilh.com/blog/articles/ComTracker.aspx] on Win2k (SP4) and it works like a charm as I use the old com interfaces that are win2k compatible.

I used the code by Igor as a base and did the following:
- copied the following files from a Win2k system to my Win2k3 dev machine to a win2k directory; winnt\system32\com\comadmin.dll + winnt\system32\comsvcs.dll
- ran tlbimp win2k\comsvcs.dll
- ran tlbimp win2k\comadmin.dll
- added a reference to the generated COMAdmin.dll and COMSVCSLib.dll in my Visual Studio 2003 project
- build
- deploy the program, COMAdmin.dll and COMSVCSLib.dll

The same program works fine on Win2k and Win2k3. The interop type libraries generated from win2k work fine on win2k3 but not the other way around.

Please let me know if it works or not for you. Leave your e-mail address in the contact form http://www.egilh.com/blog/contact.aspx if you have problems making it work.


# re: COM Call Timers: the official way
3/21/2006 4:05 PM by /egilh




# re: COM+ Call Timers: the unofficial way
6/14/2006 1:21 PM by Filippo

Great code, thanks for sharing.
I ran the original code and all I get is a list (incomplete) of the components in the "System applications" application.

ptrAppData->GetApps(&nAppData, &aAppData) return just that. I thought about a permissioning issue but using COMAdmin in C# lists all my applications...

Any hint ?

Thanks again for sharing.


# re: COM+ Call Timers: the unofficial way
6/14/2006 1:52 PM by Egil Hogholt

The code only returns the objects that are active. COMAdmin on the other hand returns all configured applications.


# re: COM+ Call Timers: the unofficial way
6/14/2006 3:19 PM by Filippo

Ah, I see... Thanks for replying me.

Active means at least a component in the application is running I guess. I want to check for components that breaks and have an high call time, but I guess if the parent application is not there it means that any component is not running hence it's ok so far....

Great code again !


# re: COM+ Call Timers: the unofficial way
2/26/2007 7:03 PM by leeh

This is good stuff. I'm new to COM, but I was able to get the C++ code working on my local computer. Now I'd like to get it working remotely, similar to the way the COM+ MMC lets you see apps on other servers. I believe this may be easier to do using the C# example, but I need something that I can call from VB6. Any suggestions?

Many Thanks!


# re: COM+ Call Timers: the unofficial way
2/26/2007 9:12 PM by Egil Hogholt

You can easily collect data from remote servers in VB6 by:
- installing the free com+ tracker [http://www.egilh.com/blog/articles/ComTracker.aspx] on the server machines
- collecting data centrally by calling the object on the remote machine: Set oTracker = CreateObject("egilh.ComTracker", "Server1")

The com+ tracker runs on, and returns data from, the remote machine.


# re: COM+ Call Timers: the unofficial way
3/6/2007 9:20 AM by nat

Thanks for this great solution.

I have this scenario:
I've a Com+ application made by a lot of com objects. I'd like to track the shutdown of this application, particularly I'd like to log the call time of the objects before the shutdown, so I'm thinking about the IComAppEvents implementation, in particulary the OnApp(forced)shutdown, in wich I'm thinking to invoke the getStatistics of ComTracker. I've read about COM+ event, but I've not understood how to apply it to the IComAppEvents. Any suggestion?


# re: COM+ Call Timers: the unofficial way
3/6/2007 4:21 PM by Anil

Hi Egilh... what an useful stuff... thanx a lot....

I've deployed it as windows application... I wraped this code into a function which returns me an arraylist with all the COM+ stats in local/remote machine...it works fine as windows app... but the problem occured when I tried to make it as C# class library... when I tried to build its throwing following error...

"Assembly generation failed -- Referenced assembly 'Interop.COMSVCSLib' does not have a strong name"

can u please help me on this...




# re: COM+ Call Timers: the unofficial way
3/6/2007 8:16 PM by Egil Hogholt

Hi Anil.
You must sign the COM interop assembly for COMSVCSLib.

This Microsoft KB article explains how to do it in C# and VB.NET:
http://support.microsoft.com/kb/313666



# re: COM+ Call Timers: the unofficial way
3/6/2007 8:25 PM by Egil Hogholt

Hi nat.
Your approach would give you the call times at the exact moment when the application is shut down. But it is fairly complex to do unless you are a skilled C++ programmer and you are familiar with Loosely Coupled Events. This post [http://www.egilh.com/blog/archive/2005/02/24/552.aspx] gives an introduction to the topic. Combined with the COM+ Spy example in the Platform SDK you should be able to do what you want.

I suggest a simpler approach unless you need the exact call times; call the getStatistics method every X seconds to get a snapshot of the situation. The data will not be 100% accurate but it should be good enough for most uses.



# re: COM+ Call Timers: the unofficial way
4/16/2007 10:21 AM by Anil

Hi Egil,
thnx a lot for ur previous reply 'n sry for delayed response.

I have this scenario:

I have implemented this (getting COM statistics) as a COM+ component (a .net class library-C#, registered to COM+) along with few other methods to get the list of all configured COM+ applications on a remote server and to start & stop selected COM+ application. 'm calling these methods from a
coldfusion (.cfm) page, by creating an instance of that component.

Everything worked fine when I deployed it on XP.
But when I deployed it on Windows 2003 server, the object count of this component kept on increasing on every method call and never reduced till I did shut down / restart COM+ application.

I'm releasing every object / comobject 'm creating in the class (COM+ component)
using marshal.releasecomobject() in finally block of each method, I even tried forcing GC in the finally block.

'm releasing instance of the component in the coldfusion page also.

it is COM+ 1.5 'm using, there is version difference in Component Services of XP machine (Version: 03.00.00.4414) and Windows 2003 machine (Version: 2001.12.4720.1830).

'm not able figure out the cause for this increase in object count.
Is there anything that holds the reference of these com objects, which has to be taken care of??

'n one more thing I have to mention here,
I've created interops (RCW) for COMSVCS.dll and COMADMIN.dll using "tlbimp" and 've put these in GAC,
other wise coldfusion is unable to execute those methods.

can u please help me on this..........



# re: COM+ Call Timers: the unofficial way
4/16/2007 11:28 AM by Egil Hogholt

If I have understood correctly; coldfusion calls your component registered in COM+ and the object count of this component keeps rising.

Try to add these two calls in the finally block of the methods registered in COM+:
ContextUtil.DeactivateOnReturn = true;
ContextUtil.SetComplete();

It tells COM+ that your component is done so it can deactivate your component.



# re: COM+ Call Timers: the unofficial way
5/14/2007 9:07 PM by Pete

Hi !

I was looking over Mark's code and I think that would be what I need... but I need it in VB.NET, do you think the convertion is possible ? I've been trying to translate it, and the bug I'm at is on that line :

Dim comPlusTrackerType As Type
comPlusTrackerType = Type.GetTypeFromCLSID(New System.Guid("{ecabafb9-7f19-11d2-978e-0000f8757e2a}"))

Dim getAppData As COMSVCSLib.IGetAppData
getAppData = CType(Activator.CreateInstance(comPlusTrackerType), COMSVCSLib.IGetAppData)

Dim appCount As System.UInt32
Dim appDataPtr As IntPtr

Dim aAppData As IntPtr
aAppData = IntPtr.Zero
==> getAppData.GetApps(appCount, aAppData)

I get the following error message :

An unhandled exception of type 'System.Runtime.InteropServices.COMException' occurred in comtrackervbnet.dll

Additional information: A null reference pointer was passed to the stub.



can you help me out ? I don't quite get how those objects work ...







# re: COM+ Call Timers: the unofficial way
5/17/2007 9:01 PM by Pete

I think I found out what's wrong (there are a lot of things but...) the main problem is on that part

Dim appDataPtr As IntPtr
Dim pAppData() As comsvcslib.CAppData
Dim aAppData As New IntPtr
Dim gh As GCHandle = GCHandle.Alloc(aAppData, GCHandleType.Pinned)
Dim AddrOfaAppData As IntPtr = gh.AddrOfPinnedObject()

getAppData.GetApps(appCount, AddrOfaAppData)


I got it into the debugger, and ... well... normally the value of aAppData should be modified after the GetApps call, but it is not, and it stays 0 .... so basically the Marshalling is done with a pointer that starts at 0 in the memory and Marshal.PtrToStructure is converting "garbagelike" memory to the apps/classes, that's why I don't get any info ...

any idea on how to modify it to work ? (at least I saved you the trouble of finding this problem.... ahah)


# re: COM+ Call Timers: the unofficial way
5/18/2007 9:29 AM by Egil Hogholt

This code works fine in C#
unsafe
{
IntPtr intPtrAppDataPtr = new IntPtr(&appDataPtr);
getAppData.GetApps(out appCount, intPtrAppDataPtr);
}

The VB-like code doesn't work in C# either:
GCHandle gh = GCHandle.Alloc(appDataPtr, GCHandleType.Pinned);
IntPtr intPtrAppDataPtr = gh.AddrOfPinnedObject();
getAppData.GetApps(out appCount, intPtrAppDataPtr);

I will have a look this weekend and let you know what I find


# re: COM+ Call Timers: the unofficial way
5/18/2007 12:05 PM by Egil Hogholt

Hi Pete.
I think I found the problem:
Dim appCount As System.UInt32
Dim appDataPtr As New IntPtr

Dim gh As GCHandle = GCHandle.Alloc(appDataPtr, GCHandleType.Pinned)
Dim intPtrAppDataPtr As IntPtr = gh.AddrOfPinnedObject()
getAppData.GetApps(appCount, intPtrAppDataPtr)

'This is the magic line: it reads that data back from the pinned pointer
appDataPtr = New IntPtr(Marshal.ReadInt32(intPtrAppDataPtr))




# re: COM+ Call Timers: the unofficial way
5/18/2007 2:24 PM by Pete

whoa, thanks Egil ! you're a god !
I found some other mistakes, but now it works completely (herE's the full code below) I commented out some of the stats I don't need to reduce the string size, you can always uncomment them !

Imports System
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.EnterpriseServices
Imports interop

'
' Summary description for ComMonitor.
'


Public Class ComMonitor : Inherits ServicedComponent

Public Function GetData() As String

' Get an instance of the internal com+ tracker objet
Dim comPlusTrackerType As Type
Dim getAppData As comsvcslib.IGetAppData
Dim appCount As System.UInt32
Dim appDataPtr As IntPtr
Dim pAppData() As comsvcslib.CAppData
Dim aAppData As New IntPtr
Dim appDataSize As Integer
Dim csStatistics As StringBuilder
Dim appIndex As Integer
csStatistics = New StringBuilder

Dim gh As GCHandle = GCHandle.Alloc(aAppData, GCHandleType.Pinned)
Dim AddrOfaAppData As IntPtr = gh.AddrOfPinnedObject()

comPlusTrackerType = Type.GetTypeFromCLSID(New System.Guid("{ecabafb9-7f19-11d2-978e-0000f8757e2a}"))
getAppData = CType(Activator.CreateInstance(comPlusTrackerType), comsvcslib.IGetAppData)
getAppData.GetApps(appCount, AddrOfaAppData)
aAppData = New IntPtr(Marshal.ReadInt32(AddrOfaAppData))
appDataSize = Marshal.SizeOf(GetType(comsvcslib.appData))

csStatistics.Append("")

For appIndex = 0 To System.Convert.ToInt64(appCount)

Dim appData As comsvcslib.appData

appData = Marshal.PtrToStructure(New IntPtr(aAppData.ToInt32() + System.Convert.ToInt32((appIndex * appDataSize))), GetType(comsvcslib.appData))

' Application information
csStatistics.Append("")
csStatistics.Append("" & GetPackageNameByPID(appData.m_dwAppProcessId) & "")
'csStatistics.Append("" + GetString(appData.m_szAppGuid) + "")
csStatistics.Append("" & System.Convert.ToInt64(appData.m_idApp) & "")
csStatistics.Append("" & System.Convert.ToInt64(appData.m_dwAppProcessId) & "")

'csStatistics.Append("")
'csStatistics.Append("" + appData.m_AppStatistics.m_cCallsPerSecond.ToString() + "")
'csStatistics.Append("" + appData.m_AppStatistics.m_cTotalCalls.ToString() + "")
'csStatistics.Append("" + appData.m_AppStatistics.m_cTotalClasses.ToString() + "")
'csStatistics.Append("" + appData.m_AppStatistics.m_cTotalInstances.ToString() + "")
'csStatistics.Append("
")

Dim nClsIDCount As UInt32
Dim clsIDDataPtr As IntPtr
Dim gh1 As GCHandle = GCHandle.Alloc(clsIDDataPtr, GCHandleType.Pinned)
Dim AddrOfclsIDDataPtr As IntPtr = gh.AddrOfPinnedObject()

getAppData.GetAppData(appData.m_idApp, nClsIDCount, AddrOfclsIDDataPtr)
clsIDDataPtr = New IntPtr(Marshal.ReadInt32(AddrOfclsIDDataPtr))

Dim clsIDDataSize As Integer

clsIDDataSize = Marshal.SizeOf(GetType(comsvcslib.CLSIDDATA))

csStatistics.Append("")

Dim clsIDIndex As Integer
For clsIDIndex = 0 To System.Convert.ToInt64(nClsIDCount) - 1

Dim clsIDData As comsvcslib.CLSIDDATA

clsIDData = Marshal.PtrToStructure(New IntPtr(clsIDDataPtr.ToInt64() + (clsIDIndex * clsIDDataSize)), GetType(comsvcslib.CLSIDDATA))

csStatistics.Append("")
csStatistics.Append("" & GetComponentNameByCLSID(clsIDData.m_clsid.ToString()) & "")
csStatistics.Append("" & clsIDData.m_clsid.ToString() & "")
'csStatistics.Append("" & clsIDData.m_cBound.ToString() & "")
'csStatistics.Append("" + clsIDData.m_cInCall.ToString() + "")
'csStatistics.Append("" + clsIDData.m_cPooled.ToString() + "")
'csStatistics.Append("" + clsIDData.m_cReferences.ToString() + "")
csStatistics.Append("" & System.Convert.ToInt64(clsIDData.m_dwRespTime) & "")
'csStatistics.Append("" + clsIDData.m_cCallsCompleted.ToString() + "")
'csStatistics.Append("" + clsIDData.m_cCallsFailed.ToString() + "")
csStatistics.Append("
")
Next

csStatistics.Append("
")
csStatistics.Append("
")
Marshal.FreeCoTaskMem(clsIDDataPtr)
gh1.Free()
Next
csStatistics.Append("
")
Marshal.FreeCoTaskMem(aAppData)
Marshal.ReleaseComObject(getAppData)
gh.Free()

Return csStatistics.ToString()
End Function
Function GetPackageNameByPID(ByVal PID As UInt32) As String

Dim retVal As String
Dim GrpObj As comsvcslib.MtsGrp
Dim dcomType As Type
Dim dcomObj As Object
Dim obj As Object
Dim eventObj As comsvcslib.COMEvents
Dim i As Integer
retVal = ""
GrpObj = Nothing
dcomType = Type.GetTypeFromProgID("mts.MtsGrp")
dcomObj = Activator.CreateInstance(dcomType)
GrpObj = DirectCast(dcomObj, comsvcslib.MtsGrp)
obj = Nothing
eventObj = Nothing
For i = 0 To GrpObj.Count - 1

GrpObj.Item(i, obj)
eventObj = DirectCast(obj, comsvcslib.COMEvents)
If (eventObj.GetProcessID() = System.Convert.ToInt64(PID)) Then
retVal = eventObj.PackageName
GetPackageNameByPID = retVal
End If
Marshal.ReleaseComObject(obj)
obj = Nothing
Marshal.ReleaseComObject(eventObj)
eventObj = Nothing
Next

Marshal.ReleaseComObject(dcomObj)
dcomObj = Nothing
GetPackageNameByPID = "UNKNOWN"

End Function

Function GetComponentNameByCLSID(ByVal CLSID As String) As String
Dim compName As String
Dim RK As Microsoft.Win32.RegistryKey
Dim oRegValue As Object
compName = ""
RK = Microsoft.Win32.Registry.ClassesRoot
RK = RK.OpenSubKey("CLSID\\{" + CLSID + "}\\ProgID")
oRegValue = RK.GetValue("")
If oRegValue = Nothing Then
compName = "UNKNOWN"
Else
compName = oRegValue.ToString()
End If
Return compName
End Function

Function GetString(ByVal arr() As UInt16) As String
Dim buf(arr.Length * 2) As Byte
Dim i As Integer
Dim s As String
Dim pos As Integer
For i = 0 To arr.Length - 1
buf(i * 2) = CByte(Convert.ToInt32(arr(i)) And 255)
buf(i * 2 + 1) = CByte(System.Convert.ToInt64(arr(i)) >> 8)
Next
s = System.Text.UnicodeEncoding.Unicode.GetString(buf)
pos = s.IndexOf("\0", 1, s.Length - 1)
If (pos > 0) Then
s = s.Remove(pos, s.Length - pos)
End If
GetString = s
End Function
End Class


You are a life saver !

thanks a lot again !


# re: COM+ Call Timers: the unofficial way
5/18/2007 2:31 PM by Pete

PS : I don't know if you can, but I would delete the post I did with the code that doesn't work, just so no one gets fooled... hehe


# re: COM+ Call Timers: the unofficial way
5/18/2007 3:43 PM by Egil Hogholt

I have deleted the old VB.NET code that didn't work.

Thanks for sharing the code.


# re: COM+ Call Timers: the unofficial way
2/13/2008 4:34 PM by Pete

Hello Egil !

it's been quite a while since I posted, but I was wondering something about the code of this function....

What components does it check exactly ?

Does it check all the components and packages under the COM+ Applications folder in the Component Services window ?

Or is it only then ones under the System Applications package ?

Or is it only the components that there are data available ?

I'm having people that want to know the package name of the classes that are getting call times over a set threshold... so I need to change the DLL I think... do I ?




# re: COM+ Call Timers: the unofficial way
2/13/2008 7:46 PM by Egil Hogholt

Hi Pete.
I will do my best to answer your questions below. Please let me know if I forgot something.

The Com+ tracker checks all the RUNNING applications under the COM+ Applications folder in the Component Services window. So you may see few/no data if you run it on a test machine.

There is no need to modify the DLL to get the package name. The DLL returns the GUID of the application which you can use with the ComAdmin to do all sorts of interesting stuff like automatically shutting down the component.

VBScript example: http://www.egilh.com/blog/archive/2005/10/11/1328.aspx
.NET example: http://www.egilh.com/blog/archive/2005/10/11/1331.aspx



# re: COM+ Call Timers: the unofficial way
4/9/2008 7:35 PM by Creez1

Are there definitions for the counters: Bound, Calls Completed, Calls Failed, In Call, Pooled, References, Response Times. Especially Bound and References. I am being tasked with monitoring our COM+ apps and I'm entirely clear what each counter is and where to establish thrsholds.


# re: COM+ Call Timers: the unofficial way
6/16/2008 2:59 AM by Noppadon

Hi,

I have a problem on getting com+ information on remote computer (UATSERVER1) using this command.

Set oTracker = CreateObject("egilh.ComTracker", "UATSERVER1")

It shows the following error.

Script: C:\Backup\Script\test.vbs
Line: 8
Char: 1
Error: ActiveX component can't create object: 'Egilh.ComTracker'
Code: 800A01AD
Source: Microsoft VBScript runtime error

I've already registered the egilhComTracker.dll on both client machine and on server (UATSERVER1). Calling the above command at the server itself is OK but failed on calling from other computer. Please help.

Best Regards,
Noppadon S.


# re: COM+ Call Timers: the unofficial way
6/27/2008 10:43 AM by Egil Hogholt

A couple of questions:
- which operating systems are you using on the machines
- how did you register the component?

My guess is that you cannot create the object because of security settings. DCOM settings are stricter in Win2k3 than Win2k for example so everything works locally but you encounter problems when you try to create an object remotely



# re: COM+ Call Timers: the unofficial way
6/30/2008 3:14 AM by Noppadon

Hi,

- The server (UATSERVER1) is Windows 2000 Advanced Server and the client trying to call the component from server is Windows XP. (creating object locally at server is OK but creating server's object remotely from client is failed)

- I'm using regsvr32 D:\script\egilhComTracker.dll command to register the component.

Which security setting should I check?

Thank you very much.


# re: COM+ Call Timers: the unofficial way
6/30/2008 2:19 PM by Egil Hogholt

You can review the security settings by running dcomcnfg.exe on the server.

I don't have access to a win2k machine, but if I remember correctly there are "Access Permissions" and "Launch and Activation Permissions.

The account that creates the component on the XP machine must have the rights to launch and access the component on the server.


# re: COM+ Call Timers: the unofficial way
7/22/2008 10:32 PM by chandresh

Hi,

I am looking for something in VB, also looking for to monitor on the remote system, without installing anything on the server.

Is this possible, or are there any ways to do the same.

Eagerly waiting for the reply.

If anyone know do forward me the way.

Thanks,
Chandresh


# re: COM+ Call Timers: the unofficial way
7/23/2008 8:29 AM by Egil Hogholt

You can do this in VB.NET but not in older versions of VB. Just create the comsvcslib.IGetAppData object on the remote machine and you should be OK.

I can update the com tracker to support getting data from remote machines if you think it would be useful.


# re: COM+ Call Timers: the unofficial way
7/23/2008 2:05 PM by chandresh

Thanks for your reply,

I am looking for something, but not too sure how to begin,
I wanted to have the entire configuration information of the com & dcom component & a way to restore them back.

I am not sure if someone is changing the same.

Is this possible to track and record them.

I am new to the field of programming.

Thanks once again for all your help and support.


# re: COM+ Call Timers: the unofficial way
7/23/2008 3:13 PM by Egil Hogholt

Does this help: http://msdn.microsoft.com/en-us/library/ms680546(VS.85).aspx

It lets you export the compoent with all the settings so you can install it later on the same machine or a different machine.

This article explains how you can do it programatically: http://msdn.microsoft.com/en-us/library/ms688248.aspx


# How to get calltime property of component (Com+ 1.5) ? keyongtech
1/22/2009 5:47 AM by Pingback/TrackBack

How to get calltime property of component (Com+ 1.5) ? keyongtech


VT's Zone

COM+ Call Timers: the official way
Posted on Thursday, February 24, 2005 9:15 PM
As the title suggests, there are more than one way to get access to the COM+ call timers. This post gives and overview of how to get the call times using the official Microsoft COM+ Instrumentation APIs.
Why mess with the COM+ call timers?
I had a serious problem with components accessing an Oracle DB using OLEDB. In certain cases we queries never ended. Query timeouts are not supported in the Oracle OLEDB nor Microsoft OLEDB provider and changing the resource constraints in Oracle did not improve the situation. If the query went in tilt, it stayed in tilt -forever-. That is a bad, bad, thing in a system with hundreds of calls per second.. We tracked down the problem to a specific case: the Oracle stored procedure never returned if the stored procedure "header" was OK but the stored procedure "body" was invalid. The stored procedure call waited forever for the the stored procedure to get recompiled. In normal situation it recompiled by itself but there were cases with linked DBs etc where the Oracle stored procedure body stayed invalid until someone recompiled it by hand.
We tried asynchronous queries but they did not fix the situation. If the query was stuck, it stayed stuck and the abort method hung as well. We found one way that did work: use a separate thread for the query and kill the thread if it took to much time. The query did not timeout anymore but the memory leaks were enormous when we brutally terminated the thread.
The only fix I found was to implement COM+ recycling on steroids. Monitor the call times and shut down (recycle on Win2k3) the com+ package if the call times got too high. The stored procedure was still broken but the rest of the system continued working. No memory leak problems either as the com+ process was shut down in an orderly manner.
How to get the com+ call timers - the official way
The Component Services Console displays all sort of useful information like the number of objects in call, average call time etc. But, there is no official way to get the com+ call timers directly. You have to do the dirty work yourself and calculate the average call times.
The COM+ Spy example in the \Samples\Com\Administration\Spy in the Platform SDK shows how to get all the COM+ information you desire. Below I show the basic steps but please download the Platform SDK for a complete working example.
The COM+ internal information is made available via Loosely Coupled Events. You subscribe to one or more COM+ events and implement the corresponding interface to get notified. There are a whole set of COM+ Instrumentation Interfaces. The important ones for COM+ call tracking are:
• IComAppEvents: OnAppActivation, OnAppShutdown, OnAppForceShutdown
• IComMethodEvents : OnMethodCall, OnMethodReturn, OnMethodException
They allow you to monitor COM+ application activation/shutdown and method call/return and provide you with all you need to calculate the call time. I used COM+ Spy as a skeleton and choose the following approach to tracking the call times:
• Implement a tracking object (CMethodMon in the example below) for each com+ application you want to monitor. The class:
o Implements the IComMethodsEvent interface to track call times
o Implements the IComAppEvents interface to clear the current calls when an application shuts down
o Subscribes to the IComMethodsEvent and IComAppEvents
o Has one timer that fires every X seconds (configurable). The timer:
? Calculates the average call time (highestCalltimes below)
? Take appropriate action if the call times are too high (shut down component etc)

IComMethodsEvents
This is THE interface for call time tracking. It is called when a method is called or returns and when an exception occurs. You get a lot of information in the COMSVCSEVENTINFO structure like the process ID, current time stamp etc.
Keeping track is quite simple:
• Create a stack for each activate object (OID stack):
• Push call information on the OID stack in OnMethodCall. In my case I only care about the call time so I only push the performance counter
• Pop from the OID stack in OnMethodReturn
// Stack definition (only contains the time stamp as that's all I care about in this app)
typedef map TimeMap;
imeMap m_map;

STDMETHODIMP CMethodMon::OnMethodCall (COMSVCSEVENTINFO * pInfo, ULONG64 oid, REFCLSID cid, REFIID rid, ULONG iMeth)
{
EnterCriticalSection(&m_csMapLock);
TimeStack * pStack = m_map[oid];
if (!pStack)
{
pStack = new TimeStack;
m_map[oid] = pStack;
}
pStack -> push_front(pInfo->perfCount);
LeaveCriticalSection(&m_csMapLock);
return S_OK;
}

STDMETHODIMP CMethodMon::OnMethodReturn (COMSVCSEVENTINFO * pInfo, ULONG64 oid, REFCLSID cid, REFIID rid, ULONG iMeth, HRESULT hr)
{
TimeStack * pStack = m_map[oid];
pStack -> pop_front();

// Remove the entry for the oid if it's call stack is empty
if (pStack -> empty())
{
delete pStack;
m_map.erase(oid);
}
return S_OK;
}

IComAppEvents
Only the OnAppShutdown event is of interest in the IComAppEvents:
STDMETHODIMP CMethodMon::OnAppShutdown(COMSVCSEVENTINFO * pInfo, GUID guidApp)
{
ClearCallTimes();
return S_OK;
}
void CMethodMon::ClearCallTimes()
{
EnterCriticalSection(&m_csMapLock);

// Clear all the call times
TimeMap::iterator iter;
for (iter = m_map.begin( ); iter != m_map.end( ); iter++ )
{
TimeStack *pStack = (TimeStack *) (*iter).second;

while (!pStack->empty())
{
pStack -> pop_front();
}
}
m_map.clear();
LeaveCriticalSection(&m_csMapLock);
}
Calculating the highest call time is straightforward:
unsigned long CMethodMon::highestCallTime(void)
{

long lHighestCallTime = 0;
LONGLONG PerformanceFrequency;
QueryPerformanceFrequency((LARGE_INTEGER *)&PerformanceFrequency);

LONGLONG lNow;
QueryPerformanceCounter((LARGE_INTEGER *) &lNow);

EnterCriticalSection(&m_csMapLock);

// Step through all the oid's currently in call
TimeMap::iterator iter;
for (iter = m_map.begin( ); iter != m_map.end( ); iter++ )
{
TimeStack *pStack = (TimeStack *) (*iter).second;

// Get the LAST element in the call stack as it will be the oldest element
if (pStack)
{
LONGLONG lOldest = pStack->back();
unsigned long lThisCallTime = (unsigned long)((1000*(lNow - lOldest))/
PerformanceFrequency);

if (lThisCallTime > lHighestCallTime)
{
lHighestCallTime = lThisCallTime;
}
}
}

LeaveCriticalSection(&m_csMapLock);

return lHighestCallTime;
}

There are known issues with the implementation above. Some error handling code has been removed and it does not take into account the fact that the PerformanceCounter will wrap sooner or later.

Issues with the official approach
The component gets called for each COM+ call (in the applications you monitor). Interesting in itself but you have to be a 110% sure you don't introduce deadlocks, memory leaks or anything else that affects the stability of the system.
I used the official approach for more than a year. It worked like a charm for weeks on end, but at random times I would get an enormous memory leak (>1GB) in the Windows RPC sub system on Win2k (I have not tried it on Win2k3). The leak may have been due to another process making heavy use of using COM+ notifications, a bug in my code or something else. It only happened when the machine was under heavy stress (100% CPU, and more than 1000 notifications per second for a few hours) so my -wild- guess is that other tasks got higher priority and the notifications continued to queue up until the system went in tilt.
The solution is not trivial to implement and requires the developer to know C++, ATL, COM admin APIs as well as Loosely Coupled Events. Finding skilled C++ COM+ programmers is hard so I decided to look for an easier to maintain solution. I will post the unofficial way I found tomorrow. It is a lot simpler and drops the source code from 1.500 lines of C++ to less than 150.

________________________________________
Feel free to drop a few cents in the tip jar if this post saved you time and money
Feedback
# re: COM+ Call Timers: the official way
5/12/2005 8:41 AM by Egil Hogholt

Several people have asked me for the source code or a DLL that implement the com+ call time tracking. The official way is complex and my implementation has memory leaks so I recommend using the unofficial way. These post have more info:

* COM+ Call Timers: the unofficial way (http://www.egilh.com/blog/archive/2005/02/25/557.aspx): source code in C++ of the com+ call time tracker function

* How to get COM+ call times from VB and VBScript (http://www.egilh.com/blog/archive/2005/04/12/655.aspx): free DLL that implements the unofficial way with example VB Script client

# re: COM+ Call Timers: the official way
2/1/2006 7:17 AM by Hai Son

Dear,
I'm an amateur COM Developer. I don't know where to start your code. Could you please to send me a sample project or tell me how to do.
Best Regards


# re: COM+ Call Timers: the official way
2/1/2006 5:40 PM by Egil Hogholt

I suggest that you start with the following post: "How to get COM+ call times from VB and VBScript"
http://www.egilh.com/blog/archive/2005/04/12/655.aspx

It has all the code and info you need to get the com+ call timers.

# re: COM+ Call Timers: the official way
2/2/2006 2:48 AM by Hai Son

Dear
I want to do something when user shutdown Com application by component service. Should I do something in function OnAppShutdown? I don't know how to insert function OnAppShutdown and how to make funtion OnAppShutdown run when user shut down Com application

# How can I implement OnAppShutdown?
2/2/2006 2:57 AM by Hai Son

Dear
I want to do something when user shutdown Com application by component service. Should I do something in function OnAppShutdown? I don't know how to insert function OnAppShutdown and how to make funtion OnAppShutdown run when user shut down Com application
What kind of ATL project should I create? What kind of ATL Object should I insert? What property of ATL Object should I set? Please show me all step before implement function OnAppShutdown.

Best Regard.

# re: COM+ Call Timers: the official way
2/2/2006 11:01 AM by Egil Hogholt

Correct.

You have to implement the IComAppEvents interface and do something useful in OnAppShutdown(). Subscribe to the IComAppEvents for the application(s) you are interested in.

This guide on MSDN explains how COM+ events work and how to use them in your application:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cossdk/html/1e0570ae-9099-465a-9133-72aa7d574932.asp

# egilhComTracker: Free component to track com call times with
2/2/2006 9:22 PM by /egilh



# re: COM+ Call Timers: the official way
2/3/2006 3:50 AM by Hai Son

Dear

.Net supported a effective way to handle COM+ Events.
Is there any ATL solution in Visual C++ 6.0?

# re: COM+ Call Timers: the official way
2/3/2006 7:40 AM by Egil Hogholt

ATL supports COM+ events. You have to create a multi threaded DLL and implement the interfaces described above.

Writing a full COM+ tutorial in the comments is difficult, so please leave your e-mail address in the contact form http://www.egilh.com/blog/contact.aspx if you need more information.

# re: COM Call Timers: the unofficial way
3/15/2006 9:01 PM by /egilh



# re: COM+ Call Timers: the official way
3/20/2006 12:02 PM by Mark

Hi Egil,
Is there a way to provide the COM+ Call
Timers as a remoting server/EnterpriseServices component .It throws a BadImageException on
account of "unsafe" keyword.

Regards

# re: COM+ Call Timers: the official way
3/21/2006 3:04 PM by Egil Hogholt

I guess you are referring to the "unofficial" .NET implementation http://www.egilh.com/blog/archive/2005/02/25/557.aspx as the official version is only available in C++

Are you sure you get a BadImageException because of the unsafe keyword? You normally get a BadImageException if you try to register a DLL with the wrong version of regsvcs. A DLL compiled with .NET 1.1 must be registered with regsvcs from .NET 1.1

# re: COM Call Timers: the unofficial way
3/6/2007 9:25 PM by /egilh



# re: COM+ Call Timers: the official way
3/28/2007 8:18 PM by Pedro Antunes

Hi Egil, Congratulations for your Page.

Do you know if we can implement this code in VB6? Do you have a translation of this code in VB or Delphi?

Thank you so much!

# re: COM+ Call Timers: the official way
3/28/2007 8:39 PM by Egil Hogholt

No, you cannot implement this in VB6. I am not sure about Delphi .

I suggest that you use the free COM+ tracker DLL which you can use from "any" language, VB, VBScript, Delphi, .NET, ...

Monday, July 07, 2008

New Kinetic SYM Flyte


After going through several reviews on gearless scooters (Pleasure, Activa, Pep+) , I picked up a Kinetic SYM Flyte for my wife on 07-July, 2008 from Unicorn Auto, Inner Ring Road, Bangalore. Flyte seems to be getting all the good reviews all over the internet.
Check out its features in the above image. These do provide an edge over the competition and makes the gearless scooter market more interesting.
I would have expected a little bigger petrol tank. It takes up only about Rs. 200 of petrol thats about 3.5 litres.
But in terms of the ride, I must say its very good. Smooth & quick as well.
The dealer suggests a mileage of about 38 or 40KM/l which after the 1st service is expected to increase to 45KM/l. Lets wait & see.
The first day I had an issue with the
- break light was burning continously without actually applying the break. This was tuned and now its fine.
- I had to use the choke to start the vehicle. Probably because of cold weather in Bangalore & also since the vehicle is 4 stroke.
- some water had got into the indicator buzzer (probably after a body wash) that made the small continuous beep noise when turing on the ignition. When it dried out it worked fine.

Also the dealer suggested to go for the normal tyres instead of the zap pattern tyres. He said Kinetic had received customer complaints about the zap tyres leading to skidding & wobbling, hence all new Flytes come now with the normal tyres. But from my analysis nobody has ever documented an issue with the zap pattern tyres & also they provide better road grip. It might be because the zap tyres are less in supply hence they are trying to push the normal tyres.

Below is the total price breakup of the vehicle,
Vehicle Cost : Rs. 38480
Comprehensive Insurance : Rs. 1153
L.R.T : Rs. 3386
Reg. Charges : Rs. 450
Accessories (Buzzer, Guard, Mat) : Rs. 1312
Total : Rs. 44781

Will update the rest of the findings as & when I ride more.
Probably SYM will help bail out Kinetic from dooms day.

Monday, January 15, 2007

Tweaking WinXP for Faster Perf.

Tweaking Windows XP Part 2
Disabling unused services on XP This is the step that is the quickest and surest way to speed up your OS, and prevents useless apps from hogging memory space all the time. Windows XP runs more than three-dozen services in the background, performing various background tasks needed for the many functions that Windows XP offers, you can choose to disable the features that you don't use, which is generally more like half of these services. To reach the services configuration utility, go to Control Panel > Administrative Tools > Services. This tool allows you to configure the way services start up, manually shutdown/restart services and check status. Check for all the services that are set to start "Automatically" and disable the following services, as they are easily dispensable. To disable a service, right click on the service, select properties, and set the startup type to disabled. If you feel unconfident about some service that you don't know what it does, set the status to manual, and when some app calls for it, it can be started manually.
Alerter - Notification for network events, triggered by a administrator generally, not needed in a home/gamer environment
Automatic Updates- Windows system file updates from Microsoft's website, disable this as manual update is a far better option for techies like us who prefer to be in control of what happens in their system.
ClipBook- Network sharing of clipboard, not needed unless you know what it does and actually use it.
DHCP Client- Receives TCP/IP configuration information from a DHCP server when your machine starts up/changes IPs. Not needed in a static IP / Non-networked environment. Distributed Link Tracking Client- NTFS file system link client for networked environs or multiple NTFS disks with links, never seen anybody use this. Distributed Transaction Coordinator- Required for running apps that are triggered 2000 off in response to a certain query, not needed if you don't run any network application server of any kind.
Error Reporting Service- Reports application errors to Microsoft. Not needed. Fast User Switching Compatibility- Allows having two simultaneous users logged on to the same machine, disable to gain extra memory.
Fax Service- If you find this on your machine, disable it.
FTP Publishing Service - Same as above, not needed unless you actually use Microsoft's FTP service.
Help and Support- Used to look for help information on Windows, contact support from right inside Windows with all the information. We don't contact anybody else for our problems; we solve it ourselves, so disable it. It automatically starts up if you click the help button on start menu, so shut it down once you've made that mistake.
IIS Admin- If you don't run a webserver on IIS, disable this.
IMAPI CD-Burning COM Service- Windows XP's not-so-hot CD Burning service. Shut this down and use a decent tool like Nero or Easy CD Creator.
Indexing Service- It is used to speed up file searches, and context sensitive searches, but takes a whole lot of resources, and whenever you write a file to a disk, indexes it, not recommended, turn this off.
IPSEC Services- No use if you don't use your machine to connect to a VPN, shut this down and disable it.
Logical Disk Manager - Set this one to manual. Messenger- Sends/receives short messages from other Windows machines on the network, if you don't know what "net send" command does, disable this. MS Software Shadow Copy Provider- Disable this too. Net Login- Disable, used only in domain based networked environs.
NetMeeting Remote Desktop Sharing- If you don't use NetMeeting, shut this one down. Network DDE- Disable it, used as a supporter for ClipBoard. Network DDE DSDM- Used as a supporter to Network DDE, disable this too.
Network Location Awareness (NLA)- Disable if you don't use Internet Connection Sharing. NT LM Security Support Provider- Shut this down if you're not running any services like Terminal Server, Telnet etc.
Performance Logs and Alerts- Useful for checking background app and general system performance parameters, disable to save quite a lot of resources. All we need is active app performance from games.
Portable Media Serial Number- If you have a portable MP3 player that you in conjunction with Windows Media Player 7, this is needed. But if your mp3 player uses its own custom software or you don't have an MP3 player, disable this.
Print Spooler- If you don't own a printer, or use it occasionally, set this to manual. You can always turn it on when you need that single page printout.
Protected Storage - used to provide safe storage of passwords to IE's auto complete feature, if you don't use that feature, disable this.
QoS RSVP - Disable this, won't do you any good unless you have a QoS capable application and an adapter driver that supports TCP/IP QoS.
Remote Access Auto Connection Manager- If you have a dial-up connection to the Internet, let this be on, otherwise, turn off.
Remote Access Connection Manager- Same as above. Remote Desktop Help Session Manager- Again, not needed.
Remote Registry Service- A big security risk, if you are on a public network, disable this for sure.
Removable Storage- Disable this one if you don't use Windows' built in media catalogue or media management. Routing and Remote Access- Disable this one if you don't know what it is, and don't use it. It supports Internet Connection Sharing; so if you use that, don't shut this own. Secondary Logon- Disable this too.
Security Accounts Manager- If you don't use any multi-user features of your machine, go ahead and disable this. It's a security risk too. Server - If you don't want any windows file/print-sharing happening on your machine other than your custom FTP servers etc. then feel free to stop this one.
Smart Card - Disable this one too, smart card authentication module. Smart Card Helper- Same as above. SSDP Discovery Service- A security risk, disable it.
System Event Notification- Disable this, of more use when on a networked environment, or running a critical service. System Restore Service- Biggest space hogger, disable this for sure. Task Scheduler- Some anti virus apps use this to schedule automatic scans, if you don't want those to take place, disable this.
TCP/IP NetBIOS Helper Service- This one is a sureshot security risk if you are on a public network, disable it for security reasons.
Telephony- Keep enabled if you are on a dial-up connection, otherwise disable to gain extra memory.
Telnet- Another security risk, disable this too.
Terminal Services- Shut down if you don't use remote logon, remote assistance, and fast user switching.
Themes - Another memory hog, but this is what make Windows XP look pretty. Choice is yours, functionality or speed? Disable to gain more than 5 megabytes of memory. Uninterruptible Power Supply- UPS management via serial port, if you don't have a UPS that is connected to your PC via anything other than a power cable, disable this.
Universal Plug and Play Device Host - Another security breach possibility, even Microsoft says this is unsecured. Disable this.
Upload Manager - Disable. Volume Shadow Copy- Used by MS Backup tools, if you don't use any of them, disable this.
WebClient- Disable this. It has got nothing to do with Internet surfing. Windows Image Acquisition (WIA)- If you don't have a digital camera or scanner, disable this too.
Windows Time- Atomic clock time sync service, disable it if you want to do all that time setting manually.
Wireless Zero Configuration- If you don't use 802.11B wireless, and auto-roaming, disable this.
WMI Performance Adapter- Disable this, no use in general environments. This really makes you realize how many relatively useless things are there in Windows XP.

Tuesday, December 12, 2006

Completed OCA

Wow, just completed Oracle 10g Administration1 certification exam. Secured 87%.
Now I am an Oracle Certified Associate.

App Center Test (ACT) & Web App Stress (WAS)

Yesterday I was playing around with the Application Center Test (ACT) bundled with initial versions of VS.NET. While I found that all the GETs to my web applications were processed fine all the POSTS were failing. POSTs were throwing error 500 from the web server.

I guess it is an issue with the Viewstate. So I googled around and found an article on msdn that had a manual code fix tio handle viewstate in ACT.
http://msdn2.microsoft.com/en-US/library/ms979202.aspx

Now even with the code fix, the POSTS were failing. On analysing I found that the GET request was returning so more content that the Response.Body was removing all the characters after a certain length. Hence the viewstate was not captured for the POST.

I just left it there and picked up Web application Stress (WAS)
WAS works perfectly but the only issue is that I am unable to add performance counters for niether the local machine nor the remote machine. I do have admin access to all these machines. Hence I need to manually handle the perf counters through the Perf mon tool.

Any thoughts on this.

Saturday, November 11, 2006

My Educational Projects

IC741 OP-AMP Simulator
-------------------------
The basic initiative behind the development of this project was to provide a rock solid framework towards how the IC-741 operational amplifier works. Is basic objective is to simulate the operation of the op-amp in various commonly used configurations.

This sort of application further emphasizes on the applications of the op-amp in diverse areas. These include signal processing (both analog and digital), signal mixing, clamping and clipping.

Further it also throws light on the various runtime parameters, which affect the behavior of the op-amp. A few of these parameters are the feedback resistor, amplitude, frequency of the input signal and other passive electronic components.

Features
Supports multiple op-amp configurations
Inverting Amplifier
Non-inverting Amplifier
Differentiator
Integrator
Logarithmic Amplifier
Summing Amplifier
Differential Amplifier
Unity Follower
Allows configuring variables such as type of input (AC or DC), frequencies of input waveforms, amplitudes of input waveforms, values of input and feedback resistors.
Also allows specifying the format of input wave such as sine, cosine, tan, DC etc
Runtime display of intermediate current and voltages of OP-AMP.
Generation of continuous input and output waveforms.
Allows varying the gain of the amplifier for all input waveforms.

Tools & Technologies
JDK 1.2.2, Swing, AWT, Java Enabled Browser

Dazzle Sphere (OpenGL 3D Game)
--------------------------------

The Story
Everybody is familiar with the towers of Hanoi puzzle. This is a self-made idea on the lines of towers of Hanoi with increased realism in a 3D environment.
It's a hell out there. There are lot of opposing choices and beliefs. This has led to state of instability. Everything seems to go out of control. All seem to be in their own domain. Someday someone gonna set things right.
Would u be the one?

Pockets with mixed colors trouble the unstable 3D sphere. Get the colors separated into individual pockets in minimum time and prove your worth.

Goal of the game
The goals of Dazzle sphere are divided into a series of objectives. During the game a new objective is provided. The ultimate goal would be to clear all the levels as they approach with the minimum amount of time.

Game Structure
Dazzle Sphere contains 7 levels, each of which has to be completed in order to proceed to the next level. Remember that once you leave a level you cannot return unless you reload a saved game from that level. Therefore it is important to occasionally save your intermediate results and restore it later.

Main Menu
Use the up and down arrow keys to navigate and press the enter key to select.
Each menu function brings up a list of secondary menu items.

New Game : Starts a new game
Save Game : Saves the current position of the game
Load Game : Loads a saved game
Options : Adjust screen settings
Help : Displays a brief help regarding the game.
Quit : Exits the game

Tools & Technologies
Recommended Hardware

Pentium II 400Mhz / AMD k62 or higher
64MB RAM
Sound Card
OpenGL compliant 3D accelerator graphics card (Min. 32MB Video RAM)

Recommended Software
Windows 95/98/NT/2000/XP, OpenGL libraries (opengl32.lib, glu32.lib, glaux.lib, glut32.lib)

Development
Microsoft VC++ 6.0, OpenGL library headers

WinNT NetWorker
----------------

Features
Simultaneous multi-user chat with options for rooms, user blocking, saving chat sessions etc.
Does not require a dedicated server like other chat software.
Options to create chat rooms with users.
Support for multi-user remote file transfer operations using a explorer type of interface with additional aid to cut, copy, paste, rename options.
Offers an integrated browser for surfing.
Remote automation features such as execution of remote programs, remote locking, remote shutdown, remote restart, logoff and remote peripheral access.
Also provides an environment to perform parallel processing of a CPU intensive process by distributing the complex operation to multiple systems and finally integrating the separate results to obtain the final solution.

Tools & Technologies
Microsoft Visual Basic 6.0, Windows Sockets 2.0, SQL Server 7.0

OASIS (Online Archival Serach Information System)
--------------------------------------------------
OASIS is an online application basically serving a variety of users of the publishing industry. These include the editors, the reporters, the journalists and finally the readers.

The administrators are also a class of users who have designed to take overall in-charge of the publishing organization. He belongs to the top-level management and has access rights to all the features of the application.

The search option collects the requirements of the query from the user using well-designed interfaces for the purpose of translation into a query that can be processed by the search engine or the information retrieval system. The user can supply his requirements by means of keywords, Boolean operators or phrases as the case may be.

The key goal of OASIS is to retrieve information that might by useful and relevant to the user. Hence the main focus of our application does not merely lie on the retrieval of data but information hence help the user to decide upon his solutions in a much faster and efficient manner.

The relevance of the results separates any IR system from one another. The notion of relevance is the center of information retrieval. In order to achieve this kind of accuracy for judging the relevance of an item over, several options are provided to the user such as the number of hits for an article, the average rating of the article, the class of the article, the frequency of access, the number of occurrences of the keyword in the article etc.

It is a one-stop site for all the newspaper articles. It offers flexible and efficient querying options with custom designed searches.

Features
Allows different logins for admins, reporter and general.
Allows adding new general users using the signup page.
Allows options for retrieving forgot passwords.
FrontPage loaded with daily news briefs.
Article search options with support for Boolean expression.
Advanced article search options
Support for search within article based on number of text appearances.
Support for date period based search.
Search based on article rating.
Search based on the number of article hits.
Search based on the reporter.
Search based on the newspaper in which the article has appeared.
Also support for mixed query search.
Additional support for image searches.
Search results displayed in page wise summary format.
Feature to display the detailed view of the article containing the image, article title, summary, date of reporting, reporter name, the newspaper, the related set of articles, important sections of the article.
Option to limit the number of search results.
Reporting feature to display the user search pattern, frequently searched keywords and the number of matches found.
Crystal reports Pie, 3D Chart view of the above reports for better understanding.
Report to display the list of reporters and their respective articles along with the rating gained by each article by the general readers.
Option to isolate the maximum active category and analyze its pattern over a period of time.
Report to view the list of users and the number of searches done by each of them.
Report to view the list of all articles and the number of hits generated by each.
Option to generate identity card for reporters.
Page to display a hierarchical view of the categories of the articles on the site which offers a clear understanding of the parent and child categories with option to list all articles under any category.
Online help on every page.

Tools & Technologies
MS SQL Server 7, MS Visual Interdev 6.0, MS Visual Basic 6.0
JavaScript, VBScript, ASP (Active Server Pages), IIS
Seagate Crystal Reports 7

Sound-n-Video Gallery Application
--------------------------------------------------------------------------------
Sound-n-Video is an application to automate the operations in a musical rental library.

Features
Provides option for the user to login and depending on the type of user certain features of the application are disabled.
Provides several security features such as option to lock the system to prevent unauthorized access, determine login date and time etc.
Logs the database changes to a local file to determine the user operations.
Allows artist operations.
Allows operations on items (Musical Cassetes, CDs, Video Cassetes, VCDs)
Allows for issuing items and handles the bill generation in case of fine during return of items.
Allows the reservation of items for a particular day.
Allows previewing the items in the store by providing an onscreen display (winamp style) of the video or the musical item.
Allows customized user generated query execution with easy navigational interface.
Report to view the current quantity on hand for each item in the store.

Tools & Technologies
Oracle 8.0, MS Visual Basic 6.0, Crystal Reports 7

VisEdit (Multi-File Text Editor)
--------------------------------------------------------------------------------
DOS based file text editor developed in C++.

Features
Menu based user interface with keyboard shortcuts.
Supports all types of ASCII files.
Option to handle multiple files simultaneously
Option to scroll both horizontally and vertically to a large extent.
Option for cut, copy, paste of selected text.
Option to print the file contents.
Option to find a string and replace it.
Option to adjust the screen element colors, which include the background color, text color, selection color, menu color, tab size etc.
Designed and developed using object oriented concepts (OOPS).
Help feature to aid easy operation

Development
Turbo C++ Compiler

Gateways 2000,2001 Software
--------------------------------------------------------------------------------

Gateways is an all-India MCA festival conducted by Christ College. The events for the festival include Coding, Web Designing, Quiz, Product Marketing, Dumb Charades and a host of other IT related events.

In addition to the automation of individual events such as quiz, coding, web designing the entire process of keeping track of the college registrations, scores, event participants, event result reports were streamlined with an automation software spanning a set of computers networked.

Features
Great user appealing interfaces with easy navigational features, cool intros, animations and a host of other multimedia capabilities.
Handles individual college registrations
Handles participants of an event
Availability of updated scores immediately

Tools & Technologies
Microsoft Visual Basic 6.0, Macromedia Flash 5, Adobe Photoshop 5.5
Jasc Animation Shop, Microsoft Access 97

LDR based Burglar Alarm
--------------------------------------------------------------------------------
The burglar alarm was designed using a light dependent resistor (LDR), which triggers a typical IC555 timer chip. When the LDR is exposed to light (specifically a torch light from a burglar) the resistance of the resistor changes and pushes the circuit configuration into a state, which drives the speaker with an alarm.