Posts

Showing posts with the label C#

Quick expression parsing tip

Image
In Windows, you can avoid "manual" parsing of arithmetic expressions by using the Microsoft Script Control COM object. Although it is a bit dangerous to run unsupervised scripts, it is a very handy quick way to parse any numerical expression string. It is recommended if the string is created/used in your program internally. It is NOT recommended if the "script string" is provided outside the program and you cannot control its content. All you have to do is reference the COM library Microsoft Script Control 1.0 . Then write the following under a click event -for example- to test the parsing immediately! MSScriptControl.ScriptControl c = new MSScriptControl.ScriptControl(); c.Language = "VBScript"; double v = c.Eval("5+6*8"); MessageBox.Show(v.ToString()); You can use similar code in other languages that supports COM such as Visual Basic (including VBA).

Automate Excel using C#

Image
Excel can be easily automated using C#. At first you must check that the Microsoft.Office.Interop.Excel is referenced. When the Framework 4.0 is targeted you should check that the Microsoft.CSharp.dll is referenced too. using System; using Excel = Microsoft.Office.Interop.Excel; //... Excel.Application xlApp = new Excel.Application(); //_Application xlApp = new Excel.Application(); xlApp.Visible = true; //create a workbook Workbook wb = xlApp.Workbooks.Add(XlWBATemplate.xlWBATWorksheet); //or open a workbook Workbook wb = xlApp.Workbooks.Open("c:\\book.xlsx"); //get the first worksheet Worksheet ws = (Worksheet)wb.Worksheets[1]; //Worksheets["Sheet1"] //create a worksheet Worksheet ws2 = (Worksheet)wb.Worksheets.Add(); //retrieve a range Range range = (Range)ws.Range["a1"]; Range range2 = (Range)ws.Cells[1, 1]; //the A1 cell range.Value="arkoudaki"; //alternative way to do the same thing //range2.set_Value(XlRangeValueDataType.xlRangeValueD...

Get the current path in C#

Image
The most obvious way to retrieve the current application path is by using the following statement: currentPath = Application.StartupPath; That is the obvious solution but only when the project references the System.Windows.Forms library. To avoid referencing this library (in case it is not needed), the current directory may be retrieved in many ways. See below (alternative ways are commented): // Returns the current application path without a trailing '/'. It is the same with Application.StartupPath. private string GetCurrentPath() { ////returns the path with a trailing '/' //return System.AppDomain.CurrentDomain.BaseDirectory; ////retrieve the current path (without a trailing '/') //return Environment.CurrentDirectory; //return System.IO.Directory.GetCurrentDirectory(); return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location); }

Streamreader extensions (C#)

Image
OK. These two extension functions are very practical to me: omitting lines, and copying lines from one stream to another. Although it is very simple to implement it every time in code, I suggest using those extensions to be more productive! public static class StreamReaderExtensions { /// <summary> /// Jumps the number of lines that is specified. /// </summary> /// <param name="reader">The reader object.</param> /// <param name="count">The number of lines to jump.</param> public static void OmitLines(this StreamReader reader, int count) { for (int iLine = 0; iLine < count; iLine++) reader.ReadLine(); } public static void CopyLinesTo(this StreamReader source,StreamWriter target, int count) { for (int iLine = 0; iLine < count; iLine++) target.WriteLine(source.ReadLine()); } }

Cross thread UI calls in C#

Image
If you try to call UI functions through threads other than the one the created the UI elements then an error will occur. To avoid those type of errors we need to have thread-safe calls to the corresponding Windows controls. For example, to make a thread-safe call for a textbox control, the following is valid: private void SetText(string text) { if (txtCommand.InvokeRequired) this.Invoke(new Action<string>(SetText), text); else txtCommand.Text = text; } The Invoke function will be called if the function is called from a thread other than the one that created the control. Here is a second example that will take two arguments; the first one is the control itself. private void EnableButton(Button button, bool enabled) { // InvokeRequired compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (button.InvokeRequired) button.Invoke(new Action<Button...

Associate file extensions in C#

Image
I really needed a simple class to associate a file extension to my applications. That's why I created this simple static class that can associate (programmatically) an extension to my application: public static class FileAssociator { //[System.Security.Permissions.RegistryPermission(System.Security.Permissions.SecurityAction.Assert, Unrestricted = true)] public static void AssociateExtension(string extension, string applicationPath, string identifier, string description, string icon) { RegistryKey CR = Registry.ClassesRoot; //CreateRegistryKey HKEY_CLASSES_ROOT\Extension RegistryKey extensionKey = CR.CreateSubKey(extension); //SetRegistryValue of HKEY_CLASSES_ROOT\Extension, use default value, value= Identifier extensionKey.SetValue("", identifier, RegistryValueKind.String); extensionKey.Close(); //CreateRegistryKey HKEY_CLASSES_ROOT\Identifier RegistryKey identifierKey = CR.CreateSubKey...

Dictionary class extensions (CopyTo, Sort) (C#)

Image
It seems that are not any CopyTo and Sort functions in the Dictionary class that resides in the Systems.Collection.Generic namespace. The OrderBy extension method used by Linq is not very practical to me, because it does not return a dictionary object. Here is my extension method CopyTo, applicable to generic Dictionary objects, allowing to define a part of the dictionary: public static void CopyTo<T, V>(this Dictionary<T, V> source, Dictionary<T, V> target) { if (target == null) target = new Dictionary<T, V>(); foreach (KeyValuePair<T, V> entry in source) target.Add(entry.Key, entry.Value); } public static void CopyTo<T, V>(this Dictionary<T, V> source, Dictionary<T, V> target, int start) { if (target == null) target = new Dictionary<T, V>(); int iEntry = 0; foreach (KeyValuePair<T, V> entry in source) { if (iEntry++ >= start) target.Add(entry.Key, entry.Value); } } public static void CopyTo<T, V>(this Dicti...

Array Slice in C#

Image
Unfortunately the array objects in C# do not have functions to return parts of them and I think it is not efficient to use Linq extension functions (in these cases). That is the reason why I have created a convenient Slice extension function: public static class ArrayExtensions { //returns a part of the source array public static T[] Slice<T>(this T[] source, int start, int end) { int count = end - start + 1; T[] target = null; if (count > 0) { target = new T[count]; for (int i = start; i <= end; i++) target[i - start] = source[i]; } return target; } } Here is an example, that shows to you the usage of the generic Slice function: string[] linesSrc, lineTo; ... //return a sub-array of the first three elements of the linesSrc array lineTo = linesSrc.Slice<string>(0, 2); That's the good part of the extension functions: it is general and can be used for all type of arrays.

Hook to a BackgroundWorker (C#)

Image
Using the BackgroundWorker class (that resides in the System.ComponentModel namespace) is very convenient to use for parallel processing. In the following example I add a BackgroundWorker to split the work done in several experiment objects. For that, I use an AddWorker function that creates a thread for each experiment. The line that "sticks" the application execution flow until all threads are completed, is the last one: System.Threading.AutoResetEvent waitHandle; public void Calculate() { //initialize the list of threads (BackgroundWorkers) workers = new List<BackgroundWorker>(); //initialize the object that will wait during the execution process waitHandle = new System.Threading.AutoResetEvent(false); //add a thread for each experiment object foreach (Experiment experiment in Experiments) AddWorker(experiment); //stick here until we use waitHandle.Set() waitHandle.WaitOne(); } The AddWorker() adds a thread for each experiment ...