I was helping to diagnose a threading error that goes like Cross-thread operation not valid... This typically happens when the UI thread is being accessed by another thread. Well, there might be solutions like to use Invoke delegation, here I would like to give a tip built on the background worker helper I wrote few weeks ago.
The tip is to use the progress handler (ProgressChangedMethod in my prior example).
For instance, when you want to refresh the UI count... instead of triggering an event (or a call) from the DoWorkMethod, fire up a ProgressChangedMethod call and from there either fire up an event or call your UI methods.
Love coding!
Wednesday, August 26, 2009
Tuesday, August 11, 2009
WSE & X.509 certificate related issues
Well, this one was rather time consuming to figure out and still getting things worked out as I write this. The seemingly straight forward but not so thing was dealing with certificates. Here is a little back ground. I got the certs from the client and supposedly seamlessly install and be up. Well not so, as with others as I found from googling.
Lesson 1 - don't install certificate by double clicking as you rather want it to be installed under Local Machine as opposed to Current User. People wrote about this all over the place.
Ok, then got the error "WSE2013: X509TokenProvider is unable to provide an X.509 token. There are no certificates in the certificate store that match the find value of...". Well searching for it resulted in many interesting and similar encounters by others. Particularly I liked Meteorist's Blog.
Again, tried all the suggestions, including using the full subject (copied from the cert) instead of just certificate name ("CN=xxxx"). Turns out to be that my solution is to CreateToken using Serial Number. The default create token uses find by name but changed it to something like:
And that got me through that part and encountered next level of problems. Will update when I find any more interesting points to blog about this experience.
Love coding!
Lesson 1 - don't install certificate by double clicking as you rather want it to be installed under Local Machine as opposed to Current User. People wrote about this all over the place.
Ok, then got the error "WSE2013: X509TokenProvider is unable to provide an X.509 token. There are no certificates in the certificate store that match the find value of...". Well searching for it resulted in many interesting and similar encounters by others. Particularly I liked Meteorist's Blog.
Again, tried all the suggestions, including using the full subject (copied from the cert) instead of just certificate name ("CN=xxxx"). Turns out to be that my solution is to CreateToken using Serial Number. The default create token uses find by name but changed it to something like:
X509SecurityToken clientX509Token = X509TokenProvider.CreateToken(
StoreLocation.LocalMachine,
StoreName.TrustedPeople,
"1234567890",
X509FindType.FindBySerialNumber);
And that got me through that part and encountered next level of problems. Will update when I find any more interesting points to blog about this experience.
Love coding!
Sunday, August 2, 2009
IIS 7 & Exceptions...
Here I would like to post the exceptions I've seen with IIS 7 setup and resolutions. I will keep the list dynamic and try to add more as they come. Comments/questions are welcome:
System.Security.SecurityException: Request for the permission of type 'System.Web.AspNetHostingPermission....
There might be other solutions to it, but common issue I noticed was when the AJAX (or other) dll's were copied from older version (may be IIS 6 version) the server 2008 default blocked them. Simply identify the dll's (or all dll's under bin) and check properties to see if the security warning says about being blocked. If so, unblock to get this issue resolved. Try restarting IIS and checking if at first it doesn't seem to work.
Love coding!
System.Security.SecurityException: Request for the permission of type 'System.Web.AspNetHostingPermission....
There might be other solutions to it, but common issue I noticed was when the AJAX (or other) dll's were copied from older version (may be IIS 6 version) the server 2008 default blocked them. Simply identify the dll's (or all dll's under bin) and check properties to see if the security warning says about being blocked. If so, unblock to get this issue resolved. Try restarting IIS and checking if at first it doesn't seem to work.
Love coding!
Thursday, June 25, 2009
Local Machine - Registry & MAC Address
Recently, had a need to come up with a utility that deals with local machine info/settings, like getting name, MAC address, add/delete/get registry info. Wrote a handler (or utility) that does few things for me and here is a snippet that does the job.
One interesting thing out of it is to get MAC address and I know there are many ways people go about doing this; I chose to look for the first active network interface that has non zero in first 3 octets of the address. Well, the code isn't that complex and easy to look at - take a look:
Love coding!
One interesting thing out of it is to get MAC address and I know there are many ways people go about doing this; I chose to look for the first active network interface that has non zero in first 3 octets of the address. Well, the code isn't that complex and easy to look at - take a look:
using System;
using System.Net.NetworkInformation;
using Microsoft.Win32;
namespace MyCompany.MyProject
{
/// <summary>
/// Local Machine Handler
/// </summary>
public class LocalMachineHandler
{
public enum RegistryType
{
LocalMachine,
CurrentUser,
Users,
ClassesRoot,
CurrentConfig,
}
#region Private Properties
private static LocalMachineHandler _localMachineHandler = null;
#endregion Private Properties
#region Public Properties
/// <summary>
/// Singleton instance of LocalMachineHandler
/// </summary>
public static LocalMachineHandler Instance
{
get
{
if (_localMachineHandler == null)
_localMachineHandler = new LocalMachineHandler();
return _localMachineHandler;
}
}
/// <summary>
/// Gets currently loggedin User
/// </summary>
public string UserName
{
get
{
try { return System.Windows.Forms.SystemInformation.UserName; }
catch { return "All Users"; }
}
}
/// <summary>
/// Gets Computer Name
/// </summary>
public string ComputerName
{
get
{
try { return System.Windows.Forms.SystemInformation.ComputerName; }
catch { return ""; }
}
}
/// <summary>
/// Gets MAC Address of the computer
/// </summary>
public string MacAddress
{
get
{
string macAddress = "";
#region Logic to get MacAddress
try
{
IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
if (nics != null && nics.Length > 0)
{
// All network interfaces
string firstFewOctets = "";
int octetCount = 0;
foreach (NetworkInterface adapter in nics)
{
macAddress = "";
firstFewOctets = "";
octetCount = 0;
IPInterfaceProperties properties = adapter.GetIPProperties();
// Look for the first interface that is up
if (adapter.OperationalStatus == OperationalStatus.Up)
{
// Get the physical address and format
PhysicalAddress address = adapter.GetPhysicalAddress();
byte[] bytes = address.GetAddressBytes();
for (int i = 0; i < bytes.Length; i++)
{
octetCount += 1;
// Get the first 3 octets and make sure they all are not 0
if (octetCount < 4)
firstFewOctets += string.Format("{0}", bytes[i].ToString("X2"));
// Get the physical address in hexadecimal.
macAddress += string.Format("{0}", bytes[i].ToString("X2"));
// Insert a hyphen after each byte, unless we are at the end of the address.
if (i != bytes.Length - 1)
{
macAddress += "-";
}
}
// make sure it's not all 0
if (firstFewOctets != null &&
firstFewOctets.Trim() != null &&
firstFewOctets.Trim().Length > 0 &&
firstFewOctets.Replace("0", "").Length > 0)
break;
}
}
}
}
catch { } // Nothing to catch, it's ok not to get a MAC address
#endregion Logic to get MacAddress
return macAddress;
}
}
#endregion Public Properties
#region Constructors
/// <summary>
/// Singleton - therefore prvate constructor
/// </summary>
private LocalMachineHandler() { }
#endregion Constructors
#region Public Methods
#region Registry methods
/// <summary>
/// Gets Registry value for the type
/// </summary>
/// <param name="registryType"></param>
/// <param name="keyPath"></param>
/// <param name="valueName"></param>
/// <returns></returns>
public string GetRegistryValue(RegistryType registryType, string keyPath, string valueName)
{
try
{
// Based on the type of registry, Open
RegistryKey registryKey = null;
switch (registryType)
{
case RegistryType.ClassesRoot:
registryKey = Registry.ClassesRoot.OpenSubKey(keyPath);
break;
case RegistryType.CurrentConfig:
registryKey = Registry.CurrentConfig.OpenSubKey(keyPath);
break;
case RegistryType.CurrentUser:
registryKey = Registry.CurrentUser.OpenSubKey(keyPath);
break;
case RegistryType.LocalMachine:
registryKey = Registry.LocalMachine.OpenSubKey(keyPath);
break;
case RegistryType.Users:
registryKey = Registry.Users.OpenSubKey(keyPath);
break;
default:
registryKey = Registry.LocalMachine.OpenSubKey(keyPath);
break;
}
return registryKey.GetValue(valueName).ToString();
}
catch { return ""; }
}
/// <summary>
/// Adds Registry value for the type
/// </summary>
/// <param name="registryType"></param>
/// <param name="keyPath"></param>
/// <param name="valueName"></param>
/// <param name="valueData"></param>
/// <returns></returns>
public bool AddRegistry(RegistryType registryType, string keyPath, string valueName, string valueData)
{
try
{
// Based on the type of registry, create
RegistryKey registryKey = null;
switch (registryType)
{
case RegistryType.ClassesRoot:
registryKey = Registry.ClassesRoot.CreateSubKey(keyPath);
break;
case RegistryType.CurrentConfig:
registryKey = Registry.CurrentConfig.CreateSubKey(keyPath);
break;
case RegistryType.CurrentUser:
registryKey = Registry.CurrentUser.CreateSubKey(keyPath);
break;
case RegistryType.LocalMachine:
registryKey = Registry.LocalMachine.CreateSubKey(keyPath);
break;
case RegistryType.Users:
registryKey = Registry.Users.CreateSubKey(keyPath);
break;
default:
registryKey = Registry.LocalMachine.CreateSubKey(keyPath);
break;
}
registryKey.SetValue(valueName, valueData);
return true;
}
catch { return false; }
}
/// <summary>
/// Deletes a registry path
/// </summary>
/// <param name="registryType"></param>
/// <param name="keyPath"></param>
/// <returns></returns>
public bool DeleteRegistry(RegistryType registryType, string keyPath)
{
try
{
// Based on the type of registry, Delete
switch (registryType)
{
case RegistryType.ClassesRoot:
Registry.ClassesRoot.DeleteSubKey(keyPath);
break;
case RegistryType.CurrentConfig:
Registry.CurrentConfig.DeleteSubKey(keyPath);
break;
case RegistryType.CurrentUser:
Registry.CurrentUser.DeleteSubKey(keyPath);
break;
case RegistryType.LocalMachine:
Registry.LocalMachine.DeleteSubKey(keyPath);
break;
case RegistryType.Users:
Registry.Users.DeleteSubKey(keyPath);
break;
default:
Registry.LocalMachine.DeleteSubKey(keyPath);
break;
}
return true;
}
catch { return false; }
}
#endregion Registry methods
#endregion Public Methods
}
}
Love coding!
Tuesday, June 16, 2009
One Way Hash - Credit Card storage?
In ecommerce it is very common for us to come across situations to deal with credit cards and when it must be stored, then the security of it. Recently, was dealing with design of a visa service (confidential) and had to address the storage of CC numbers under PCI guidelines. I would recommend to take a look at this interesting blog - PCI Integrity Corp. There's a lot of documentation, suggestions, issues, complaints, models... e.t.c one can go through. I would like to give my version here and why I chose to do so.
My model:
1. Use one way hash
2. Use salt (even if it's hard coded)
3. Do a minimum of 100 iterations
4. Use 512 encryption (on XP developer machine use SHA512Managed but on servers 2003 and above SHA512CryptoServiceProvider could be used as well)
Let me explain why I chose to use salt that is hard coded in the code. Yes, developers can see it and what's the point in not addressing the separation of responsibilities here... well, the rational is to prevent the external threats. Hashing without salt itself is acceptable under PCI and adding an internally known salt won't make it any worse but rather make it more secured for external threats. Enough said, take a look at a prototype code that can work for this model:
Love coding!
My model:
1. Use one way hash
2. Use salt (even if it's hard coded)
3. Do a minimum of 100 iterations
4. Use 512 encryption (on XP developer machine use SHA512Managed but on servers 2003 and above SHA512CryptoServiceProvider could be used as well)
Let me explain why I chose to use salt that is hard coded in the code. Yes, developers can see it and what's the point in not addressing the separation of responsibilities here... well, the rational is to prevent the external threats. Hashing without salt itself is acceptable under PCI and adding an internally known salt won't make it any worse but rather make it more secured for external threats. Enough said, take a look at a prototype code that can work for this model:
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
/// <summary>
/// HashManager
/// </summary>
public sealed class HashManager
{
private static readonly string _salt = "BD4332CF-EE54-4BB1-BCCF-BD7A0F0C7F1F";
private static readonly int _hashIterationsMax = 100;
private HashManager() { }
#region Public Methods
/// <summary>
/// Gets the salted hash value with predetermined iterations.
/// </summary>
/// <param name="unhashedData"></param>
/// <returns></returns>
public static string GetSaltedHash(string unhashedData)
{
string hashData = unhashedData;
for (int hashLimit = 0; hashLimit < _hashIterationsMax; hashLimit++)
hashData = GetHash(_salt + hashData);
return hashData;
}
/// <summary>
/// Verifies the hash
/// </summary>
/// <param name="unhashedData"></param>
/// <param name="hashedData"></param>
/// <returns></returns>
public static bool VerifyHash(string unhashedData, string hashedData)
{
string hashData = GetSaltedHash(unhashedData);
return hashedData.Equals(hashData);
}
#endregion Public Methods
#region Private Methods
/// <summary>
/// Gets the hash value of the data using SHA512Managed
/// </summary>
/// <param name="unhashedData"></param>
/// <returns></returns>
private static string GetHash(string unhashedData)
{
byte[] hashData = Encoding.UTF8.GetBytes(unhashedData);
// on server 2003 or higher, can use SHA512CryptoServiceProvider
SHA512Managed sha512Managed = new SHA512Managed();
hashData = sha512Managed.ComputeHash(hashData);
sha512Managed.Clear();
return Convert.ToBase64String(hashData);
}
#endregion Private Methods
}
Love coding!
Monday, March 23, 2009
BackgroundWorker Wrapper/Helper
Recently came across a need to use BackgroundWorker at multiple places in one of the projects and I went digging in my old code to find a wrapper/helper class. Refactored the old code and started using it, again.
A quick googling for this term gets to few nice examples and some are pretty good. However, thought to post my version of it too, though in some terms it's not as robust as others like thread safety e.t.c. You may use it if you want a basic helper/wrapper and find this version sufficient.
And here's how it may be consumed/implemented...
To use it with method based calls...
Love coding!
A quick googling for this term gets to few nice examples and some are pretty good. However, thought to post my version of it too, though in some terms it's not as robust as others like thread safety e.t.c. You may use it if you want a basic helper/wrapper and find this version sufficient.
using System;
using System.ComponentModel;
using System.Threading;
namespace myProject.ClientFacade
{
public class BackgroundWorkerHelper : IDisposable
{
#region Private Properties
private bool disposed = false;
private BackgroundWorker _backgroundWorker;
private bool _supportsCancellation = false;
private bool _reportsProgress = false;
private bool _cancelPending = false;
#endregion Private Properties
#region Constructor
public BackgroundWorkerHelper() { }
#endregion Constructor
#region Public Properties
/// <summary>
/// Gets/Sets whether worker supports cancellation
/// </summary>
public bool WorkerSupportsCancellation
{
get { lock (this) { return _supportsCancellation; } }
set { lock (this) { _supportsCancellation = value; } }
}
/// <summary>
/// Gets/Sets whether worker supports progress reporting
/// </summary>
public bool WorkerReportsProgress
{
get { lock (this) { return _reportsProgress; } }
set { lock (this) { _reportsProgress = value; } }
}
/// <summary>
/// Gets whether there is a pending cancellation
/// </summary>
public bool CancellationPending
{
get { lock (this) { return _cancelPending; } }
}
/// <summary>
/// Sets the progress value as integer percentage
/// </summary>
public int SetProgressPercent
{
set { _backgroundWorker.ReportProgress(value); }
}
#endregion Public Properties
#region Event Handlers
public delegate void BackgroundDoWorkEventHandler();
public event BackgroundDoWorkEventHandler BackgroundDoWorkEvent;
public delegate void BackgroundCompletedEventHandler();
public event BackgroundCompletedEventHandler BackgroundCompletedEvent;
public delegate void BackgroundProgressChangedEventHandler(int percentComplete);
public event BackgroundProgressChangedEventHandler BackgroundProgressChangedEvent;
#endregion Event Handlers
#region Method Handlers
public delegate void BackgroundMethodHandler();
public BackgroundMethodHandler DoWorkMethod;
public BackgroundMethodHandler RunWorkerCompletedMethod;
public delegate void BackgroundProgressMethodHandler(int percentComplete);
public BackgroundProgressMethodHandler ProgressChangedMethod;
#endregion Method Handlers
#region Public Methods
/// <summary>
/// Runs the events created in the background thread
/// </summary>
public void RunBackgroundWorker()
{
RunBackgroundWorker(null, null, null);
}
/// <summary>
/// Runs the methods in the background thread
/// </summary>
/// <param name="doWorkMethod"></param>
/// <param name="progressChangedMethod"></param>
/// <param name="runWorkerCompletedMethod"></param>
public void RunBackgroundWorker(BackgroundMethodHandler doWorkMethod,
BackgroundProgressMethodHandler progressChangedMethod,
BackgroundMethodHandler runWorkerCompletedMethod)
{
// Set methods:
if (doWorkMethod != null)
{
DoWorkMethod = doWorkMethod;
ProgressChangedMethod = progressChangedMethod;
RunWorkerCompletedMethod = runWorkerCompletedMethod;
// Set events to null
BackgroundDoWorkEvent = null;
BackgroundCompletedEvent = null;
BackgroundProgressChangedEvent = null;
}
// BackgroundWorker
_backgroundWorker = new BackgroundWorker();
// DoWork
_backgroundWorker.DoWork +=
new DoWorkEventHandler(BackgroundWorker_DoWork);
// RunWorkerCompleted
_backgroundWorker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(BackgroundWorker_RunWorkerCompleted);
// ProgressChanged
_backgroundWorker.ProgressChanged +=
new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);
_backgroundWorker.WorkerReportsProgress = _reportsProgress;
_backgroundWorker.WorkerSupportsCancellation = _supportsCancellation;
_backgroundWorker.RunWorkerAsync();
}
/// <summary>
/// CancelBackgroundWorker
/// </summary>
public void CancelBackgroundWorker()
{
if (_supportsCancellation)
{
lock (this)
{
_cancelPending = true;
_backgroundWorker.CancelAsync();
}
}
}
#endregion Public Methods
#region Private Methods
/// <summary>
/// Event for DoWork
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
if (DoWorkMethod != null)
{
_cancelPending = false;
DoWorkMethod();
}
else if (BackgroundDoWorkEvent != null)
{
_cancelPending = false;
BackgroundDoWorkEvent();
}
}
/// <summary>
/// Event for Run Worker Completed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (RunWorkerCompletedMethod != null)
{
_cancelPending = false;
RunWorkerCompletedMethod();
}
else if (BackgroundCompletedEvent != null)
BackgroundCompletedEvent();
}
/// <summary>
/// Event for Progress Changed
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
if (ProgressChangedMethod != null)
{
_cancelPending = false;
ProgressChangedMethod(e.ProgressPercentage);
}
else if (BackgroundProgressChangedEvent != null && _reportsProgress)
BackgroundProgressChangedEvent(e.ProgressPercentage);
}
#endregion Private Methods
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
}
}
~BackgroundWorkerHelper()
{
Dispose(false);
}
#endregion IDisposable Members
}
}
And here's how it may be consumed/implemented...
private ClientFacade.BackgroundWorkerHelper backgroundWorkerHelper =
new ClientFacade.BackgroundWorkerHelper();
public void CallingMethod()
{
txtStart.Text = DateTime.Now.ToLongTimeString();
// Set properties
backgroundWorkerHelper.WorkerReportsProgress = true;
backgroundWorkerHelper.WorkerSupportsCancellation = true;
// ********* EVENT BASED ******************
backgroundWorkerHelper.BackgroundDoWorkEvent +=
new ClientFacade.BackgroundWorkerHelper.BackgroundDoWorkEventHandler(DoWork);
backgroundWorkerHelper.BackgroundProgressChangedEvent +=
new ClientFacade.BackgroundWorkerHelper.BackgroundProgressChangedEventHandler(ProgressChanged);
backgroundWorkerHelper.BackgroundCompletedEvent +=
new ClientFacade.BackgroundWorkerHelper.BackgroundCompletedEventHandler(Completed);
// Run Background
backgroundWorkerHelper.RunBackgroundWorker();
}
private void DoWork()
{
for (int i = 0; i < 30; i++)
{
backgroundWorkerHelper.SetProgressPercent = (int)((float)i / (float)30 * 100);
System.Threading.Thread.Sleep(1000);
if (i > 10)
backgroundWorkerHelper.CancelBackgroundWorker();
if (backgroundWorkerHelper.CancellationPending)
return;
}
}
private void Completed()
{
txtCompleted.Text = DateTime.Now.ToLongTimeString();
}
private void ProgressChanged(int percentComplete)
{
txtProgress.Text = percentComplete.ToString();
}
To use it with method based calls...
// ********* METHOD BASED ******************
backgroundWorkerHelper.DoWorkMethod +=
new ClientFacade.BackgroundWorkerHelper.BackgroundMethodHandler(DoWork);
backgroundWorkerHelper.ProgressChangedMethod +=
new ClientFacade.BackgroundWorkerHelper.BackgroundProgressMethodHandler(ProgressChanged);
backgroundWorkerHelper.RunWorkerCompletedMethod +=
new ClientFacade.BackgroundWorkerHelper.BackgroundMethodHandler(Completed);
// Run Background
backgroundWorkerHelper.RunBackgroundWorker(DoWork, ProgressChanged, Completed);
Love coding!
Thursday, February 19, 2009
Mutex - A manager class to support both local and global scope
I think Mutex is one such object that I've seen few of us having difficulty or second opinions in usage. After all it does what it's supposed to do and as always I recommend everybody to read documentation to get a good understanding.
There are quite few interesting blogs that go on this topic and here I would like to show a manager class I use (even on terminal services) in my code. Notice that I'm prefixing Global in cases where I want it to be visible for all terminal server sessions; otherwise it's per user session (common usage). Take a look:
When to consume, I then use it like:
Love coding!
There are quite few interesting blogs that go on this topic and here I would like to show a manager class I use (even on terminal services) in my code. Notice that I'm prefixing Global in cases where I want it to be visible for all terminal server sessions; otherwise it's per user session (common usage). Take a look:
using System;
using System.Threading;
namespace myNameSpace
{
/// <summary>
/// MutexManager to support safe Mutex implementation
/// Be sure to check for IsMutexCreated
/// </summary>
public class MutexManager : IDisposable
{
#region Private Properties
private bool disposed = false;
private Mutex _Mutex;
#endregion Private Properties
#region Public Properties
public bool IsMutexCreated { get; private set; }
public bool HasException
{
get { return (ExceptionText != null && ExceptionText.Length > 0); }
}
public string ExceptionText { get; private set; }
#endregion Public Properties
/// <summary>
/// Instantiates the MutexManager with the WaitOne.
/// Check for IsMutexCreated to make sure whether to continue
/// </summary>
/// <param name="handleName">Unique name for each handler</param>
/// <param name="isGlobal">Set to true when using this for Terminal Services</param>
/// <param name="synchronizeRequest">Set to true when the request needs to be synchronized.</param>
public MutexManager(string handleName, bool isGlobal, bool synchronizeRequest)
{
try
{
IsMutexCreated = true;
bool isNewMutexCreated = false;
// Look for global
if (isGlobal)
handleName = @"Global\" + handleName;
//
_Mutex = new Mutex(false, handleName, out isNewMutexCreated);
//
IsMutexCreated = (isNewMutexCreated || synchronizeRequest);
if (IsMutexCreated)
isNewMutexCreated = _Mutex.WaitOne();
}
catch (UnauthorizedAccessException accessException)
{
IsMutexCreated = false;
ExceptionText = accessException.Message;
}
catch (AbandonedMutexException abandonedMutex)
{
IsMutexCreated = false;
ExceptionText = abandonedMutex.Message;
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this.disposed)
{
try { _Mutex.ReleaseMutex(); }
catch { }
disposed = true;
}
}
~MutexManager()
{
Dispose(false);
}
#endregion IDisposable Members
}
}
When to consume, I then use it like:
using (MutexManager mutexManager =
new MutexManager("my unique handler name", true, false))
{
// Mutex has exception?
if (mutexManager.HasException)
log(mutexManager.ExceptionText);
// Not synchronizing the Mutex ==> check for whether to continue
if (!mutexManager.IsMutexCreated)
return;
// do work
}
Love coding!
Wednesday, February 18, 2009
Wizard Control in WinForms? A Trick by hiding Tabs.
Recently I stumbled upon a nifty trick to build a wizard control simulator (like Asp.Net wizard). Check this forum post to see how simple it is; thanks to the poster there. Taking the idea, I created a control class like this:
And I start using this in place of tab control and used SelectedIndex property to show each step (or tab) in the wizard simulator.
Love coding!
using System;
using System.Windows.Forms;
namespace MyProejctNameSpace
{
public class WizardControl : TabControl
{
protected override void WndProc(ref Message m)
{
// Hide tabs by trapping the TCM_ADJUSTRECT message
if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1;
else base.WndProc(ref m);
}
}
}
And I start using this in place of tab control and used SelectedIndex property to show each step (or tab) in the wizard simulator.
Love coding!
Tuesday, February 10, 2009
Oracle 10g client upgrade error - Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Last year when we were looking to upgrade Oracle client to 10.2 version (our databases were already 10g from a year before), ran into errors with XMLType columns. Anytime we read XMLType column, we get an exception "Attempted to read or write protected memory. This is often an indication that other memory is corrupt".
Strangely, this was not a problem on local machines but only on servers. Tried many simulations and trials, but with no success. This might be a valid error in cases like when the connection was closed/disposed before reading the XMLType data but in my test scenarios I made sure it was clean code and handles objects properly. Actually went too deep trying to diagnose the problem, even digging GAC.
Turns out in the end all we had to do is to apply 10g Release 2 (10.2.0.4) Patch Set 3 for Microsoft Windows (32-Bit). And things have been stable since that patch.
Love coding!
Strangely, this was not a problem on local machines but only on servers. Tried many simulations and trials, but with no success. This might be a valid error in cases like when the connection was closed/disposed before reading the XMLType data but in my test scenarios I made sure it was clean code and handles objects properly. Actually went too deep trying to diagnose the problem, even digging GAC.
Turns out in the end all we had to do is to apply 10g Release 2 (10.2.0.4) Patch Set 3 for Microsoft Windows (32-Bit). And things have been stable since that patch.
Love coding!
Cryptography - AesManaged
I wrote a cryptography class for one my projects in the past and it was built using RijndaelManaged Class. Few months back, revisited to upgrade it to a simpler yet better code block and that's when I looked into AesManaged Class. Just as I was getting ready to post my sample to this blog, I searched and found that Steve Sheldon had a wonderful blog about a simple example to implement AesManaged class in a blog titled Simple Cryptography Block. Thanks Steve!
Love coding!
Love coding!
Tuesday, January 20, 2009
WCF Client without app.config/web.config
We might be so used to having the config file options for the WCF client applications and it makes life so easy to handle. However, should we ever need to work with no config file scenario, like if we were to build an api kind of interface and expose properties instead of a config file, then we still could do it using code. It can get a little complex but to start let me give you a simple example.
Look at this code snippet that helps to get this idea:
Love coding!
Look at this code snippet that helps to get this idea:
EndpointAddress endpointAddress = new EndpointAddress("http://myServiceURL.com");
WSHttpBinding serviceBinding = new WSHttpBinding();
serviceBinding.ReceiveTimeout = new TimeSpan(0, 0, 120);
MyServiceClient myClient = new MyServiceClient(serviceBinding, endpointAddress);
Love coding!
Serialize using DataContractSerializer
In the past I had couple of posts about serialization - this and this. Recently, came across a need that required to serialize an object that is not public - wanted to serialize an internal class. This could be done using good old reflection techniques but thanks to 3.0/3.5 framework, the solution lies in using DataContractSerializer.
Let's get to the code - quite simple:
Love coding!
Let's get to the code - quite simple:
using System.Runtime.Serialization;
/// <summary>
/// Serialize using DataContractSerializer
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
internal string Serialize(Object obj)
{
StringBuilder serialXML = new StringBuilder();
DataContractSerializer dcSerializer = new DataContractSerializer(obj.GetType());
using (XmlWriter xWriter = XmlWriter.Create(serialXML))
{
dcSerializer.WriteObject(xWriter, obj);
xWriter.Flush();
return serialXML.ToString();
}
}
Love coding!
Monday, January 19, 2009
WCF Streaming - Couple of blogs to read
Recently I was building a WCF streaming service and came across couple of blogs that are very neat in explaining the basics. Take a look at those...
WCF Streaming: Upload files over HTTP
Transferring large files using WCF
Love coding!
WCF Streaming: Upload files over HTTP
Transferring large files using WCF
Love coding!
Subscribe to:
Posts (Atom)