Saturday, December 31, 2011

ASM Abnormal Situation Management SCADA Standard

Designing HMI graphics for Abnormal Situation Management (ASM)

The Abnormal Situation Management (ASM) was created by a Honeywell management consortium in 1994. Its purpose was to find better solutions to certain emergency situations at the manufacturing plant.

The Role of the HMI Designer

As a designer for the HMI software on the production equipment software you need to integrate ASM SCADA/HMI graphics into your programing. These graphics will not only monitor and record the data of the production equipment such as the pumps, switches, tank levels, temperatures, etc, but you also need them to identify any abnormality if ASM occurs. These are any disturbances that occur in a process that can cause the normal plant operations to deviate from their normal operational process. When the operations team notes the HMI warning, they can then identify the cause and correct the issue in a timely manner.

As a Human Machine Interface (HMI) designer you must make design modifications to account for ASM. So you must know what the ASM Honeywell standards are. By reading the ASM standard requirements you can better design the HMI software for this purpose.

We have published an Article on Synergist SCADA Inc:

http://synergistscada.com/asm-4-best-practices-for-operator-display-design/

New Synergist SCADA Inc website launched

We are pleased to announce the launch of the new Synergist SCADA Inc website at:
http://www.synergistscada.com

Please take a look and let us know what you think!

Tuesday, July 13, 2010

Encrypt / Decrypt Strings using Visual Basic and C# .Net

I have created a few handy methods for encrypting and decrypting a string using the .net frameworks Tripple DES Crypto Service Provider.

I have posted the Encryption / Decryption code below in both VB and C# .Net.


Visual Basic Version:

Imports System
Imports System.IO
Imports System.Security.Cryptography

' Triple DES String Encryptor / Decryptor
' Austin Scott
' June 17, 2010
Public Class FormTestEncryptDecrypt

' Key For Triple DES
Private key() As Byte = {34, 12, 93, 23, 7, 53, 2, 99, 19, 25, 27, 200, 192, 32, 60, 57, 87, 102, 183, 123, 34, 22, 65, 42}
' IV for Triple DES
Private iv() As Byte = {69, 110, 68, 26, 69, 178, 200, 219}

Private Sub ButtonEncrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonEncrypt.Click
TextBoxEncrypt.Text = Encrypt(TextBoxEncrypt.Text)
End Sub


Private Sub ButtonDecrypt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonDecrypt.Click
TextBoxDecrypt.Text = Decrypt(TextBoxDecrypt.Text)
End Sub

' =-=-=-=-=-=-=-=-=-=-=---=-=-
' Encrypt a string value (to a Comma Separated byte array) using triple DES
' =-=-=-=-=-=-=-=-=-=-=---=-=-
Public Function Encrypt(ByVal plainText As String) As String

Dim utf8encoder As Text.UTF8Encoding = New Text.UTF8Encoding()
Dim inputInBytes() As Byte = utf8encoder.GetBytes(plainText)

Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateEncryptor(Me.key, Me.iv)

Dim encryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write)

cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
encryptedStream.Position = 0

Dim result(encryptedStream.Length - 1) As Byte
encryptedStream.Read(result, 0, encryptedStream.Length)
cryptStream.Close()

Dim sbResult As Text.StringBuilder = New Text.StringBuilder()

For iPos As Int16 = 0 To result.Length - 1
If (iPos = result.Length - 1) Then
sbResult.Append(result(iPos))
Else
sbResult.Append(result(iPos))
sbResult.Append(",")
End If
Next iPos

Return sbResult.ToString

End Function


' =-=-=-=-=-=-=-=-=-=-=---=-=-
'Decrypt a string value (Comma Separated byte array) using triple DES
' =-=-=-=-=-=-=-=-=-=-=---=-=-
Public Function Decrypt(ByVal stringToDecrypt As String) As String


Dim byteArrayString() As String = stringToDecrypt.Split(",")
Dim inputInBytes(byteArrayString.Length - 1) As Byte
For iPos As Int16 = 0 To byteArrayString.Length - 1
inputInBytes(iPos) = Convert.ToByte(byteArrayString(iPos))
Next iPos

Dim tdesProvider As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider()
Dim cryptoTransform As ICryptoTransform = tdesProvider.CreateDecryptor(Me.key, Me.iv)

Dim decryptedStream As MemoryStream = New MemoryStream()
Dim cryptStream As CryptoStream = New CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write)
cryptStream.Write(inputInBytes, 0, inputInBytes.Length)
cryptStream.FlushFinalBlock()
decryptedStream.Position = 0

Dim result(decryptedStream.Length - 1) As Byte
decryptedStream.Read(result, 0, decryptedStream.Length)
cryptStream.Close()
Dim myutf As Text.UTF8Encoding = New Text.UTF8Encoding()
Return myutf.GetString(result)
End Function


C# Version:


// Key For Triple DES - Modify these
private byte[] key = { 34, 12, 93, 23, 7, 53, 2, 99, 19, 25, 27, 200, 192, 32, 60, 57, 87, 102, 183, 123, 34, 22, 65, 42 };
// IV for Triple DES - Modify these
private byte[] iv = { 69, 110, 68, 26, 69, 178, 200, 219 };

public Form1()
{
InitializeComponent();
}

private void ButtonEncrypt_Click(object sender, EventArgs e)
{
TextBoxEncrypt.Text = Encrypt(TextBoxEncrypt.Text);
}


private void ButtonDecrypt_Click(object sender, EventArgs e)
{
TextBoxDecrypt.Text = Decrypt(TextBoxDecrypt.Text);
}


// =-=-=-=-=-=-=-=-=-=-=---=-=-
// Encrypt a string value (to a Comma Separated byte array) using triple DES
// =-=-=-=-=-=-=-=-=-=-=---=-=-
private String Encrypt(string plainText)
{

UTF8Encoding utf8encoder = new UTF8Encoding();
byte[] inputInBytes = utf8encoder.GetBytes(plainText);
TripleDESCryptoServiceProvider tdesProvider = new TripleDESCryptoServiceProvider();
ICryptoTransform cryptoTransform = tdesProvider.CreateEncryptor(key, iv);

MemoryStream encryptedStream = new MemoryStream();
CryptoStream cryptStream = new CryptoStream(encryptedStream, cryptoTransform, CryptoStreamMode.Write);

cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
cryptStream.FlushFinalBlock();
encryptedStream.Position = 0;

byte[] result = new byte[encryptedStream.Length];
encryptedStream.Read(result, 0, Convert.ToInt32(encryptedStream.Length));
cryptStream.Close();

// Create a comma separated string of the encrypted bytes values
StringBuilder sbResult = new StringBuilder();

for (Int16 iPos = 0; iPos <= result.Length - 1; iPos++)
{
if (iPos == result.Length - 1)
{
sbResult.Append(result[iPos]);
}
else
{
sbResult.Append(result[iPos]);
sbResult.Append(",");
}

}

return sbResult.ToString();
}


// =-=-=-=-=-=-=-=-=-=-=---=-=-
// Decrypt a string value (Comma Separated byte array) using triple DES
// =-=-=-=-=-=-=-=-=-=-=---=-=-
private String Decrypt(string stringToDecrypt)
{
string[] byteArrayString = stringToDecrypt.Split(',');
byte[] inputInBytes = new byte[byteArrayString.Length];
for (Int16 iPos = 0; iPos <= byteArrayString.Length - 1; iPos++)
{
inputInBytes[iPos] = Convert.ToByte(byteArrayString[iPos]);
}

TripleDESCryptoServiceProvider tdesProvider = new TripleDESCryptoServiceProvider();
ICryptoTransform cryptoTransform = tdesProvider.CreateDecryptor(key, iv);

MemoryStream decryptedStream = new MemoryStream();
CryptoStream cryptStream = new CryptoStream(decryptedStream, cryptoTransform, CryptoStreamMode.Write);

cryptStream.Write(inputInBytes, 0, inputInBytes.Length);
cryptStream.FlushFinalBlock();
decryptedStream.Position = 0;

byte[] result = new byte[decryptedStream.Length];
decryptedStream.Read(result, 0, Convert.ToInt32(decryptedStream.Length));
cryptStream.Close();
UTF8Encoding myutf = new UTF8Encoding();
return myutf.GetString(result);
}

Tuesday, June 8, 2010

Java WebStart - "Unable to completely uninstall application" Problem

Today I ran into an annoying problem when I needed to re-install a Java WebStart application.
When I opened up the Control Panel and Selected Add Remove Programs on my Windows XP computer, and selected the Java WebStart application I wanted to uninstall, the following message appeared:

"Unable to completely uninstall application"


After trying a few different tricks, I was able to uninstall the application using the Java Control Panel by:

  1. Opening the Control Panel and Selecting the Java option
  2. From the Java Control Panel under the General Tab in the Temporary Internet Files group box I clicked the View... button.
  3. The Java Cache Viewer appears.
    I found the application I wanted to uninstall on the list.
  4. Finally I right clicked the application and selected Delete

After I deleted the application from the Java Control Panel I was able to re-install the Java WebStart application and continue with my work.

Monday, May 17, 2010

Force IIS7 to run applications in x86 (32 bit)

The other day I ran into a problem where my WCF C# .net application was being run in x64 bit mode. Normally this would not be an issue but my C# application was linking to some old unmanaged dlls that were compiled to only run in x86 mode.

The error message I was seeing is IIS7 was:
Could not load file or assembly 'MyDllFile' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Could not load file or assembly 'MyDllFile' or one of its dependencies. An attempt was made to load a program with an incorrect format.Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.BadImageFormatException: Could not load file or assembly 'MyDllFile' or one of its dependencies. An attempt was made to load a program with an incorrect format.

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

Here is how I was able to force IIS7 to use x86 mode on a 64 bit version of Windows Server 2008:
  1. First I needed to change my C# applications to compile in x86 mode rather than "Mixed Platforms".
    I did this by right clicking my solution and opening the Properties and then selecting the Configuration Properties tree branch in Visual Studio 2008.

  2. Next I opened IIS7 Manager (Internet Information Services Manager):
    Control Panel -> Administrative Options -> Internet Information Services Manager

  3. In the IIS7 Manager I selected the Application Pools leaf for my server.





  4. I right clicked on the Classic .Net AppPool.

    (you may want to use the Default AppPool depending on if you application was originally designed for IIS7 )

    And selected Advanced Settings...





  5. Under Advanced Sttings there is an option called
    "Enable 32-Bit Applications"

    Switch that option to True





  6. Open your website and find your Application.
    Change your application to use the Classic .Net AppPool
    (or Default AppPool depending on your application )

  7. Restart IIS7

Tuesday, May 11, 2010

Windows Vista \ Windows 7 \ Windows Server 2008 folder permissions

My C# Log File or Configuration File throws a System.UnauthorizedAccessException in Vista / Windows 7 / Windows Server 2008!

I am sure most people have encountered an Access Exception in C# .Net after installing an application that was:

  • Written to run on Windows XP

  • Written to run Windows Server 2003

  • Written to run on an even earlier version of Windows...

after installing it on a :

  • Windows Vista computer

  • Windows 7 computer

  • Windows Server 2008 server

System.UnauthorizedAccessException

at LogOMatic.Logger.Append(String message, Priority level, Priority logPriorityLevel)

at SyncInvokeMemConnect(Object , Object[] , Object[] )

at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)

at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)

at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)


Back in the good old days of windows application development files could be written willy-nilly across the hard drive! They were glorious days, but all good things must come to an end.

Modern windows applications (Windows Vista, Windows 7, Windows Server 2008) are expected to only read and write files to certain predefined folder paths.

http://msdn.microsoft.com/en-us/library/system.environment.specialfolder%28VS.100%29.aspx

In the good old days we used to use the default execution path or the assembly path to reference our configuration or log files like so:

// THE OLD XP WAY
String assmLoc = Assembly.GetExecutingAssembly().Location;

Now we need to use the Environment.SpecialFolder class.

If you are running a client side application you can use the ApplicationData special folder like the following example:

// New UAC Way
String APPLICATION_NAME = "TEST";

String assmLoc = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)+"\\"+APPLICATION_NAME;


This will put your configuration or log file in the hidden folder:

Windows Vista / Windows 7 / Windows Server 2008:

C:\ProgramData\\Application Data\TEST

Windows XP / Windows Server 2003:

C:\Documents and Settings\\Application Data\TEST

If you are running a windows service or WCF (Windows Communication Foundation) applciation (like a SOAP web service) you will need to use the CommonApplicationData special folder entry.

//New UAC way for WCF or Services
String APPLICATION_NAME = "TEST";

Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)+"\\"+APPLICATION_NAME

This will put your configuration or log files into the Hidden folder C:\ProgramData\ (could be on a different partition depending on your server configuration):

Windows Vista / Windows 7 / Windows Server 2008:

C:\ProgramData\TEST

Windows XP / Windows Server 2003:

C:\Documents and Settings\TEST




About Synergist Software
Synergist Software is a Calgary, Alberta (Canada) based software company focused on Rich Internet Application (RIA) development.
Please visit us at:
http://www.synergist.ca

How to Debug WCF

In this short tutorial I will show you how to “Attach to process...” a WCF web service using Visual Studio and IIS6 or IIS7

There are a few minimum requirements that must be met in order to attach to a WCF ( Windows Communication Foundation ) service process:

  1. You must add the following entry to your:
    Web.config
    or

    app.config
    file to enable debugging:

  1. You must be running at least Visual Studio Pro, Premium, and Ultimate editions
    Sorry, no debugging in Express ( at least not for C# )

  2. These instructions only work with IIS6 or IIS7

There are also some limitations of debugging WCF that should be considered.

Once you have everything setup correctly ( you may need to restart IIS ) you can open visual studio and select:

Tools -> Attach to Process...

(Ctrl + Alt + P )

Check off both the Show processes... check boxes at the bottom of the dialog:

  • Show processes from all users

  • Show processes in all sessions


And find the process named:

w3wp.exe

NOTE:
If the process w3wp.exe does not appear in the list. Try running the web service using the WCF Test Client. After the service is run the w3wp.exe process should appear.

Attach the debugger to that process and you should be able to step through your code.




References:

http://msdn.microsoft.com/en-us/library/bb157687.aspx

About Synergist Software
Synergist Software is a Calgary, Alberta (Canada) based software company focused on Rich Internet Application (RIA) development.
Please visit us at:
http://www.synergist.ca