Thursday, 28 March 2013

Winforms Panel with Rounded Corners

Here's a small class that can create a rounded-border effect on Winforms Panels

Please note that this is not my work, and comes from this tutorial
    public class RoundedPanel : Panel
    {
        public int Radius { get; set; }
        public Color BorderColor { get; set; }
        public Color FillColor { get; set; }
        public bool Fill { get; set; }
        public bool AntiAlias { get; set; }

        public RoundedPanel()
            : base()
        {
            BackColor = Color.White;
            FillColor = Color.Transparent;
            Fill = false;
            AntiAlias = true;
            DoubleBuffered = true;
            Radius = 18;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            GraphicsPath path = RoundedRectangle.Create(0, 0, Width - 1, Height - 1, Radius);
            e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
            e.Graphics.DrawPath(new Pen(BorderColor, 1f), path);
            if (Fill)
            {
                e.Graphics.FillPath(new SolidBrush(FillColor), path);
            }
        }
    }

Friday, 10 February 2012

Creating your own certificate for a test SSL server

I've just needed to spoof an SSL server that one of my client apps connects to, in order to setup some test cases for specific responses.

The TcpListener needs an X509Certificate to use for encryption. An easy way to set this up is to use the makecert.exe utility from Mircosoft.

First, you create a trusted root certificate:
makecert -pe -n "CN=Test And Dev Root Authority" -ss my -sr LocalMachine  -sky signature 
-r "Test And Dev Root Authority.cer"
,Then you use this created cert to create a certificate for encryption:
makecert -pe -n "CN=apptest.com" -ss my -sr LocalMachine -sky exchange -eku 1.3.6.1.5.5.7.3.1 -is MY -ir LocalMachine  
-sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 apptest.com.cer

Be sure to copy the root authority certificate into you trusted root store.

An example of setting up a server is below, copied directly from here.

Thursday, 6 October 2011

Dynamic logical expressions in .NET 3.5

For a project I'm working on, I  use an external XML file to define various BL rules. One such rule involves checking if an instance of a custom record-type object contains various entries. So that our technical support guys (with only a very basic knowledge of XML) could maintain the rules, I decided on going with a format like:
field1,field2,field3,((field4,field5)|(field6))
, which means: fields1-3 MUST exist, AND EITHER (Field4 AND 5) OR Field6 must exist

In other words, what I needed to do was create a logical-expression parser. Now one way to do this would be to manually parse the string, i.e. look for the innermost brackets, convert the expression to booleans, evaluate that, then evaluate the next 'level' etc. Now not only would this get pretty complicated, but it's a little limiting.

Ideally I would have loved to create a lambda expression dynamically (i.e. convert a string to a lambda), however this functionality was not readily available. NOTE: in .NET4, it looks like this is covered with the DynamicExpression class, but I'm unfortunately limited to 3.5 atm.

What I went for in the end is probably overkill, but the concept is pretty cool. C# obviously already handles mathematical expressions parsing . So I thought: "hey, why not format the evaluation into c# code and execute it?!". Well, this is actually pretty easy. It involves leveraging the CodeDom functionality. Now you can manually construct a class, as explained here, but that involves a fair bit of work. The option I went for was to use the CSharpCodeProvider class, which enables you to specify the class as text, and create an in-memory assembly from it.

It's as easy as this:
CompilerResults cr;
    Dictionary<string, string> d = new Dictionary<string, string>();
    d.Add("CompilerVersion", "v3.5");
    CSharpCodeProvider myCodeProvider = new CSharpCodeProvider(d);
    CompilerParameters cp = new CompilerParameters(new string[] { "DevSaffa.AReferencedProject.dll" });
    cp.GenerateExecutable = false;
    cp.GenerateInMemory = true;
    cp.OutputAssembly = "OutMod"; 
    string sourceText =       "using System;" +
                              "using DevSaffa.AReferencedProject;" +
                              "namespace DevSaffa.DynamicCode{" +
                              "public class Class1{" +
                              "public static bool Evaluate(MyClass1 data){return " + logicalOperation + ";}}} ";  

    cr = myCodeProvider.CompileAssemblyFromSource(cp, sourceText);
    if (cr.Errors.Count > 0)
        throw new ArgumentException("Expression cannot be evaluated, please use a valid C# expression");
A couple of things:
  • Be sure to create the CSharpCodeProvider instance specifying the CompilerVersion, otherwise you may run into issues around referenced assemblies.
  • Also, see how you can reference one of your own projects: not only do you need to include the #using reference, but you also need to specify the referenced assembly in the compile-parameters
  • If any errors occur with the compilation, you can iterate through the cr.Errors collection, which contain the actual compile errors (as would be displayed in your build-error window in Visual studio for a normal build)
I'm passing in an instance of the custom record-type class(MyClass1) to the dynamically created method, and pre-formatting the XML-file validation-string(the logicalOperation variable above) using a simple Regex (not shown) so that:
field1,field2,field3,((field4,field5)|(field6))
becomes
data.FieldExists("field1") && data.FieldExists("field2") && data.FieldExists("field3") && 
((data.FieldExists("field4") && data.FieldExists("field5"))|(data.FieldExists("field6")))
, where my data-class has a method:
public bool FieldExists(string code)

I can then call the compiled in-memory assembly's Evaluate() method like so:
MethodInfo Methinfo = cr.CompiledAssembly.GetType("DevSaffa.DynamicCode.Class1").GetMethod("Evaluate");
    return (bool)Methinfo.Invoke(null, new object[] { data });
(where 'data' is an instance of my record-type object (MyClass1) that I want to evaluate)

Nifty!

Thursday, 8 September 2011

Retrieving available COM ports

I recently had to deal with a dodgy USB driver that didn't null-terminal it's virtual com-ports in the registry. As a result, when retrieving the ports-list via the usual SerialPort.GetPortNames(), I got values like "COM7รข".

Here's a little method to not only remove any unwanted characters from the port-names, but (using an anonymous delegate to implement an IComparer on the Sort() extension method) order the list of COM ports by port-number too (otherwise COM11 would come before COM2):

Tuesday, 30 August 2011

DateTime.ToString() custom format

I always forget which letters represent what date/time format in the ToString() method.
Commonly I use it for logging, and the format is:
DateTime.Now.ToString("yyyyMMdd HH:mm:ss:FFFFFF")
, which results in:
20110830 08:22:26:160586
The full list is available here (MSDN)

Tuesday, 23 August 2011

TCP Load-testing

Just had to whip up a load-tester for a server that communicates with clients via TCP. Can process concurrent TCP connections, and has graphical reporting, and should be easily extensible to dynamically change requests. Made use of the open-source ZedGraph graphing utility, which is pretty damn cool.

Download the source-code here
The ZedGraph binary is located here

Monday, 22 August 2011

BER-TLV Parsing

One of the EMV devices I need to connect to uses the BER-TLV (wiki) protocol for communications. Simply put, data fields are defined by a (T)ag, (L)ength and (V)alue.
  •  The tag field (T) consists of one or more consecutive bytes. It codes a class, a type, and
    a number:

  • The length field (L) consists of one or more consecutive bytes. It codes the length of
    the following field.
  • The value field (V) codes the value of the data object
Sample code removed