Saturday, 26 September 2015

Create, Configure and Write to Event Log in C#, VB and PowerShell

Some of you might be familiar with checking out the errors and information with Event Viewer for tracing or troubleshooting purposes. Those logs' information can be written using EventLog class that are available in .NET Framework since version 1.1. Other than using code, the same thing can be achieved using PowerShell.

Here are a few things to take note when dealing with EventLog. 
  • You can't create a log that are belongs to an existing source
  • You can't create a source that is already exists on another log.
  • The first eight characters of the log name cannot be the same as the existing log name.
  • You can't delete a source's name that has the same as log name.
  • Moving a source by deleting the source from a log and then creating the same source to a different log will not work until the machine is being rebooted. Which means, if you attempt to move the source from 1 log to another log. Writing an event to this source will still appear on the previous log. To remedy this, just reboot the machine.
You might not aware of what log and source is all about. To clarify this, log is the place that holds all the written logs. By default, there are 3 logs (Application, Security, System) and they are located at the left pane of the Event Viewer window. On the other hand, the source is for you to identify which applications it belongs to. Each log can contains 1 or more sources but each source can only be tied to a single log.

This is how you can write an event to event log. Unlike code, it is mandatory to fill in the log and eventid for PowerShell. Eventid is for you to define or customize, it can be something like an error code. But in this case, we can leave the eventid as 0. If you want to change the event's default icon (Information) to something else, just change the entrytype value.

[C#]
EventLog.WriteEntry("SourceName", "Message"EventLogEntryType.Information);

[C# Alternative]
using (EventLog eventLog = new EventLog())
{
    eventLog.Source = "SourceName";
    eventLog.WriteEntry("Message", EventLogEntryType.Information)
}

[VB]
EventLog.WriteEntry("SourceName", "Message"EventLogEntryType.Information)

[VB Alternative]
Using eventLog As EventLog = New EventLog()
    eventLog.Source = "SourceName"
    eventLog.WriteEntry("Message", EventLogEntryType.Information)
End Using

[PowerShell]
write-eventlog -logname LogName -source SourceName -message "Message" -eventid 0 -entrytype Information


The following is for you to create a new log and the log's source. When creating a new log with the source's name and the log's name is different, a source with the same name as the log's name will be created automatically.

[C#]
EventLog.CreateEventSource("SourceName", "LogName");

[VB]
EventLog.CreateEventSource("SourceName", "LogName")

[PowerShell]
new-eventlog -logname LogName -source SourceName


If you want to change the log's maximum size and the action to take if reached the maximum size, you can do so with the following code. What the following does is to set the maximum size to 2048 KB and delete the oldest event if exceeded the maximum size.

[C#]
using (EventLog eventLog = new EventLog(LOG_NAME))
{
    eventLog.MaximumKilobytes = 2048;
    eventLog.ModifyOverflowPolicy(OverflowAction.OverwriteAsNeeded, 0);
}

[VB]
Using eventLog As EventLog = New EventLog(LOG_NAME)
    eventLog.MaximumKilobytes = 2048
    eventLog.ModifyOverflowPolicy(OverflowAction.OverwriteAsNeeded, 0)
End Using

[PowerShell]
limit-eventlog -logname LogName -maximumsize 2048KB -overflowaction overwriteasneeded

Other than configuring them in code or with PowerShell, you can do so through the Event Viewer window by navigating to the log's properties.





Monday, 31 August 2015

Encryption with Angularjs-Crypto

Recently, I have the need to look into encrypting / decrypting content in javascript when sending / receiving from the server through Web API. My mentor, Serena Yeoh suggest me to check out the AngularJS-Crypto, so today I will share this with you guys. Before reading further, it is advisable to have a basic knowledge on AngularJS and ngResource. Otherwise you will have hard time understanding how the code is being written.

AngularJS-Crypto integrates the functionalities from CryptoJS and is required to use it together with ngResource. It allows encrypting the properties of the object based on a keyword or encrypt the whole object before sending over to the server. For more details about AngularJS-Crypto and how to integrate it to your project, you can refer from this link https://github.com/pussinboots/angularjs-crypto

Ensure that you have all the necessary scripts. The following are the list of required scripts.
  • angular.js
  • angular-resource.js 
  • angularjs-crypto.js 
  • CryptoJSCipher.js
And the following 2 scripts for using AES encryption with ECB mode. 
  • aes.js
  • mode-ecb.js
In your angular module, add the dependency angularjs-crypto.

[Javascript]
angular.module('sampleModule', ['ngResource''angularjs-crypto'])

Here are a few things you can do in the run blocks for initializing the crypto.
  • Set the encryption key to base64Key or use the function base64KeyFunc for dynamically change the key. The key needs to be in base64 format.
  • Define the type of encryption algorithm.
  • Define the pattern and only encrypt the object's property that contains or match the pattern.
So in this case, the algorithm used is AES and encrypt / decrypt the object's property that contains the name "content".

[Javscript]
.run(['$rootScope''cfCryptoHttpInterceptor'function ($rootScope, cfCryptoHttpInterceptor) {
    cfCryptoHttpInterceptor.base64KeyFunc = function () {
        return $rootScope.base64Key;
    }
    cfCryptoHttpInterceptor.plugin = new CryptoJSCipher(CryptoJS.mode.ECB, CryptoJS.pad.Pkcs7, CryptoJS.AES)
    cfCryptoHttpInterceptor.pattern = "content";
}])

Next, create a factory to implement $resource to invoke the services that are created with Web API. The following is for encrypting / decrypting object's property only. Encryption / decryption will only be enabled when crypt is set to true.

[Javascript]
$resource('sample'null, {
    post: {
        method: 'POST',
        crypt: true
    }
});

The following is for encrypting / decrypting whole object. Encryption will only be enabled when fullcryptbody is set to true and decryption will be enabled when decryptbody is set to true.

transformRequest is used to intercept the content before sending it to the server. In this case, for the Web API to understand the string value from the body, the content will be supplied with the double quote added at the beginning and at the end before sending to server.

transformResponse is used to intercept the result received from the server. In this case, the value returned through Web API contains double quote. Before decrypting the content, the double quote located at the beginning and at the end of the content needs to be removed.

[Javascript]
$resource('sample'null, {
    post: {
        method: 'POST',
        fullcryptbody: true,
        decryptbody: true,
        transformRequest: function (data, headers) {
            return '"' + data + '"';
        },
        transformResponse: function (data, headers) {
            return data.slice(1, -1);
        }
    }
});

For changing the encryption key, just assign the value to the base64Key. The function base64KeyFunc will be called whenever $resource is invoked.

[Javascript]
$scope.$root.base64Key = '16rdKQfqN3L4TY7YktgxBw==';

That's all for setting up the encryption in javascript. Just invoke your service from javascript and the server will receive your encrypted data.

If you want to know how the server decrypt the content sent from client and encrypt it back to client. You can check out from the sample code here https://onedrive.live.com/?id=E6612168B803803D%21337&cid=E6612168B803803D&group=0&parId=E6612168B803803D%21165&authkey=%21AFMOI7ZQ%2DtGFxKM&action=locate

Sunday, 30 August 2015

Thread Synchronization with Mutex and How to Implement it in C# & VB

Previously, I have posted about acquiring exclusive lock with SpinLock http://jaryl-lan.blogspot.com/2015/08/thread-synchronization-with-spinlock.html. Today, we will look into how to implement and use the Mutex. [I would like to give credits to Serena Yeoh for introduce this to me.]

The purpose for SpinLock and Mutex are quite similar, which is for applications that deal with multiple threads and every threads requires to have exclusive right to perform a task. But unlike SpinLock, Mutex are not limited to current process and can share across different processes. In Mutex, threads that are waiting for acquiring the lock are waiting for signal from the thread that is holding the lock.

To use the Mutex, An instance of a Mutex is required.

[C#]
Mutex mutex = new Mutex();

[VB]
Dim mutex As Mutex = New Mutex()

The code above can only be used in the current process. To share the Mutex across other processes, you need to give the Mutex a name. Here are a few things to take note when instantiating an instance of Named Mutex. For more details, https://msdn.microsoft.com/en-us/library/system.threading.mutex.aspx & https://msdn.microsoft.com/en-us/library/windows/desktop/ms682411(v=vs.85).aspx.
  • The name given to the Mutex are case sensitive, so make sure to take note of the name's casing when you want to share the same Named Mutex across your applications.
  • There are two types of prefix, which is "Global\" and "Local\". By default, if you do not specify any prefix for the Named Mutex, it will be "Local\".
  • If you need to share your Mutex across different Environment (For Example: Web Application, Windows Application), you need to include the prefix "Global\" in the name of the Mutex.
  • Other than prefix, the remaining character for the Named Mutex cannot contain backslash (\).
Other than that, you need to define the security access for the Mutex. This is to allow other processes that are launched by different user to share the same Mutex.

What the following code does is to try and get the existing Named Mutex. If is doesn't exist, a new Named Mutex will be created. Regarding the parameter MutexRights, specifying synchronize is to allow the thread to wait for the Named Mutex's lock. As for Modify, it is to allow the thread to release the lock of the Named Mutex.

The SecurityIdentifier is to define what kind of users can use the Named Mutex, in this case, specifying WorldSid is to allow all users (also known as Everyone) to use the Named Mutex.

[C#]
if (!Mutex.TryOpenExisting(MUTEX_NAME, MutexRights.Synchronize | MutexRights.Modify, out mutex))
{
    bool createdNew;
    MutexAccessRule mutexAccessRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.Synchronize | MutexRights.Modify, AccessControlType.Allow);

    MutexSecurity mutexSecurity = new MutexSecurity();
    mutexSecurity.AddAccessRule(mutexAccessRule);

    mutex = new Mutex(false, MUTEX_NAME, out createdNew, mutexSecurity);
}

[VB]
If mutex.TryOpenExisting(MUTEX_NAMEMutexRights.Synchronize Or MutexRights.Modify, mutex) Then
    Dim createdNew As Boolean
    Dim mutexAccessRule As MutexAccessRule = New MutexAccessRule(New SecurityIdentifier(WellKnownSidType.WorldSid, Nothing), MutexRights.Synchronize Or MutexRights.Modify, AccessControlType.Allow)

    Dim mutexSecurity As MutexSecurity = New MutexSecurity()
    mutexSecurity.AddAccessRule(mutexAccessRule)

    mutex = New Mutex(False, MUTEX_NAME, createdNew, mutexSecurity)
End If

mutex.WaitOne is to acquire the lock and wait for the lock to be released if is owned by other thread.

[C#]
mutex.WaitOne();

[VB]
_mutex.WaitOne()

mutex.ReleaseMutex is to release the lock and to enable other threads to acquire the lock.

[C#]
mutex.ReleaseMutex();

[VB]
_mutex.ReleaseMutex()

By using the same scenario as specified in my previous blog post about SpinLock. Race Condition will not happen if used together with Mutex. By running the sample code for SpinLock and Mutex, you will notice that SpinLock are much faster compared to Mutex.

The test is run with the following specification:
Operating System: Windows Server 2012 R2 64 Bit
Processor: Intel Core i7-4800MQ Processor
RAM: 16GB, Dual Channel, DDR3

Parallel Loop for 1,000,000 times.
Elapsed time for SpinLock: 126.08 ms ~ 129.57 ms
Elapsed time for Mutex: 2774.81 ms ~ 2868.85 ms

Hold it. Don't jump to a conclusion that SpinLock is better than Mutex. In this test, what i'm doing is just changing a single variable value. This means that each threads acquire the lock and release it in a very short duration, in which it can be ideal for SpinLock. But if the thread takes a very long time to complete a task, you will see the performance of the application starts to degrade. SpinLock will also affect other processes' performance while waiting for the lock to be release from the thread, since it uses CPU cycle while spinning in the loop.

You can get the sample code about Mutex from the following link. https://onedrive.live.com/redir?resid=E6612168B803803D!334&authkey=!ACaO5bWfJ1DdEJs&ithint=file%2czip

Wednesday, 26 August 2015

Programmatically Change Values in Configuration File During Runtime in C# & VB

In this post, I will show you guys on how to programmatically change the values defined in configuration file. [Thanks to Serena Yeoh for introduce this to me.]

"Be aware that it is not recommended to change the value in web application's configuration file, this is due to changing of the configuration file will cause the application pool to restart. What this means is that the value kept in session or in static will be lost."

Well, don't be scared off by the statement. It doesn't mean that you can't use it in different environment. There might be a situation that requires you to change the value in configuration file, such as the value defined in configuration file changes the way how your application behaves and you want to test these behaviors in your Unit Test. Changing the configuration value manually and re-run the test can be very tedious and other developers that are sharing/developing the same project might not be aware about this.

To deal with this kind of situation, you will need to change them in code. So let's get started.

You need to have an instance of Configuration. By calling the following code, it will retrieve the current project's configuration file (app.config).

[C#]
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

[VB]
Dim config As Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None)

If your application is using a custom configuration and wants to change the value in the custom configuration, you will need to get the instance of the section. Assuming my section's name is "sampleSectionGroup/changeConfiguration".

[C#]
var configSection = (ChangeConfigurationSection)config.GetSection("sampleSectionGroup/changeConfiguration");

[VB]
Dim configSection = CType(config.GetSection("sampleSectionGroup/changeConfiguration"), ChangeConfigurationSection)

With the configuration retrieved, you can then change the configuration value. The following code is used to change the value in appSettings. Assuming my appSettings contain keys with the name "sampleAppKeyOne" and "sampleAppKeyTwo".

[C#]
config.AppSettings.Settings["sampleAppKeyOne"].Value = "NewSampleAppKeyOne";
config.AppSettings.Settings["sampleAppKeyTwo"].Value = "NewSampleAppKeyTwo";

[VB]
config.AppSettings.Settings("sampleAppKeyOne").Value = "NewSampleAppKeyOne"
config.AppSettings.Settings("sampleAppKeyTwo").Value = "NewSampleAppKeyTwo"

The following code is used to change the value in a custom made configuration. Assuming my element name is "sampleConfig" that contain 2 string attribute "samplePropertyOne" and "samplePropertyTwo".

[C#]
configSection.SampleConfig.SamplePropertyOne = "NewSamplePropertyOne";
configSection.SampleConfig.SamplePropertyTwo = "NewSamplePropertyTwo";

[VB]
configSection.SampleConfig.SamplePropertyOne = "NewSamplePropertyOne"
configSection.SampleConfig.SamplePropertyTwo = "NewSamplePropertyTwo"

Once you have done changing the value. You need to save them back to the configuration file.

[C#]
config.Save(ConfigurationSaveMode.Modified);

[VB]
config.Save(ConfigurationSaveMode.Modified)

If you have the need to access the updated value from the configuration file immediately after the changes is saved to the configuration file. you need to refresh the section that you have changed. So if let's say the appSettings and the custom configuration's value is changed and need to get the updated value from the configuration file. those section needs to be refreshed by calling the following code.

[C#]
ConfigurationManager.RefreshSection("appSettings");
ConfigurationManager.RefreshSection("sampleSectionGroup/changeConfiguration");

[VB]
ConfigurationManager.RefreshSection("appSettings")
ConfigurationManager.RefreshSection("sampleSectionGroup/changeConfiguration")

The sample code can be obtained here https://onedrive.live.com/redir?resid=E6612168B803803D!331&authkey=!AGahxzzrDJsW3MM&ithint=file%2czip