Sunday, January 29, 2012

看電影

透過電影來提醒自己過得幸福?或是活得不夠努力!

Friday, March 25, 2011

IIS Application Pool Identity

I did some research for IIS application pools because I encountered some issues when I deployed my OPC client web application into IIS7. I had to change the identity of the application pool to LocalSystem to make it run properly.
Basically, an application pool is just like a container to contain the managed application. It isolates the managed application so the managed application won't affect the other applications in other application pool and vice versa.
Therefore, if I change the identity of the application pool, I change the privilege of the managed application. In my OPC client case, I changed the identity to LocalSytem, so I gave the application very high power privileges. Of course, this increases the security concerns, but if one day when my client complaints :), I think I can create a custom account, define some proper privileges and assign the account to the application pool identity.

References:
http://technet.microsoft.com/en-us/library/cc753449%28v=ws.10%29.aspx
http://technet.microsoft.com/en-us/library/cc771170%28v=ws.10%29.aspx

Thursday, March 24, 2011

OPC client in Asp .NET C#

The goal is to create an OPC client in Asp .Net website to read and write against Kepware KepServerEX and then deploy the website to IIS7.

I got a dll, OPCDAAuto.dll, from a client and I need to utilize this dll to access the KepServerEX 5.2 in order to read and write some values into the PLC module.
For practice purpose, I created a regular website in Visual Studio 2008 and added the reference of the dll, then I used using OPCAutomation; in my project to start coding the OPC client. Here are my testing codes.

// set up some variables
OPCServer ConnectedOpc = new OPCServer();
Array OPCItemIDs = Array.CreateInstance(typeof(string), 10);
Array ItemServerHandles = Array.CreateInstance(typeof(Int32), 10);
Array ItemServerErrors = Array.CreateInstance(typeof(Int32), 10);
Array ClientHandles = Array.CreateInstance(typeof(Int32), 10);
Array RequestedDataTypes = Array.CreateInstance(typeof(Int16), 10);
Array AccessPaths = Array.CreateInstance(typeof(string), 10);
OPCGroup OpcGroupNames;

// connect to KepServerEX
ConnectedOpc.Connect("Kepware.KEPServerEX.V5", "");

Add tags and OPC group.

// set up the tags
OPCItemIDs.SetValue("Counting.PLC.Station1.LoggedON", 1);
OPCItemIDs.SetValue("Counting.PLC.Station2.LoggedON", 2);
OPCItemIDs.SetValue("Counting.PLC.Station3.LoggedON", 3);
OPCItemIDs.SetValue("Counting.PLC.Station1.Operator", 4);
OPCItemIDs.SetValue("Counting.PLC.Station2.Operator", 5);
OPCItemIDs.SetValue("Counting.PLC.Station3.Operator", 6);

// set up the opc group
OpcGroupNames = ConnectedOpc.OPCGroups.Add("Group01");
OpcGroupNames.DeadBand = 0;
OpcGroupNames.UpdateRate = 100;
OpcGroupNames.IsSubscribed = true;
OpcGroupNames.IsActive = true;
OpcGroupNames.OPCItems.AddItems(6, ref OPCItemIDs, ref ClientHandles, out
ItemServerHandles, out ItemServerErrors, RequestedDataTypes, AccessPaths);

Read the values from the server for those tags.

// read
Array ItemServerValues = Array.CreateInstance(typeof(string), 10);
object a;
object b;
OpcGroupNames.SyncRead((short)OPCAutomation.OPCDataSource.OPCDevice, 6, ref
ItemServerHandles, out ItemServerValues, out ItemServerErrors, out a, out b);
Label2.Text = (string)ItemServerValues.GetValue(4);
Label3.Text = (string)ItemServerValues.GetValue(5);
Label4.Text = (string)ItemServerValues.GetValue(6);

Write some values into the server for those tags.

// write
Array ItemServerValues = Array.CreateInstance(typeof(object), 7);
ItemServerValues.SetValue(1, 1);
ItemServerValues.SetValue(1, 2);
ItemServerValues.SetValue(1, 3);
ItemServerValues.SetValue("Test Op 1", 4);
ItemServerValues.SetValue("Test Op 2", 5);
ItemServerValues.SetValue("Test Op 3", 6);
OpcGroupNames.SyncWrite(6, ref ItemServerHandles, ref ItemServerValues, out
ItemServerErrors);

The above codes were running fine in the VS2008, but when I deployed to IIS7, I encountered some errors.
The first error looks like this:

Retrieving the COM class factory for component with CLSID {28E68F9A-8D75-11D1-8DC3-3C302A000000} failed due to the following error: 80040154.

And here is the second error:

Error HRESULT E_FAIL has been returned from a call to a COM component.

I believed these errors coming from the dll. I spent two days to search online and did some try and error. Finally, I figured out I need to twist two settings in the IIS7 to make it run properly.

1. Right click on the application pool to select Advanced Settings. Set "Enable 32-Bit Applications" to True. (This will resolve the first error and let the second error show up.)
2. Also in the Advanced Settings of the application pool, set Process Model -> Identity to LocalSystem. (This will resolve the second error and no more errors.)

I am not sure these changes will affect the security of the web application or not, but since the application is in a closed network environment, I think I don't have to worry about it at this moment.