Using C# to running command-line utility
(Another snippet I originally posted to CodeKeep.)
I needed to do a secure file copy to a remote server for an activity report. I chose to use pscp from PuTTY.
(Another snippet I originally posted to CodeKeep.)
I needed to do a secure file copy to a remote server for an activity report. I chose to use pscp from PuTTY.
(Another snippet I originally posted to CodeKeep.)
Using ‘this’ can make your code simpler and easier to read.
Here is a hard way to create a pair of constructors:
(Another snippet I originally posted to CodeKeep.)
Need the path to the local temp folder or a temp file name to store some runtime junk?
Look no further…
var tempPath = System.IO.Path.GetTempPath();
var tempFile = System.IO.Path.GetTempFileName();
(Another snippet I originally posted to CodeKeep.)
I’d recommend looking at EntLib 5.0 if you are serious about your event logging. This is but a simple hack…
(Another snippet I originally posted to CodeKeep.)
Code:
interface IPlural
{
void Load();
void Load(ELoadOptions option, int id);
}
interface IMembership
{
void Save();
void Delete();
void Load(int id);
}
Usage:
public class CAddresses : List<CAddress> , IPlural
{
public void Load()
{
// do something
}
public void Load(ELoadOptions option, int id)
{
// do something
}
}
(Another snippet I originally posted to CodeKeep.)
In perl, I could write "=" x80 to create a visual separator in my debug statements or report headers. Here is an equally crisp syntax to do the same in C#.
Code:
Environment.NewLine + String.Empty.PadRight(80,’=') + Environment.NewLine;
Notes:
This idea also works for strings that need to be trimmed to a specific length (think fixed width output files). Take the existing string, pad it to the desired length, then chop off the rest via a substring.
myString.PadRight(80 ,’ ‘).Substring(0, 80).TrimEnd(new char[] {‘ ‘});
(Another snippet I originally posted to CodeKeep on 23-Feb-2009.)
This one seems rather obvious, but if you don’t know…
Code:
for (int i = 0, j = 1; i < max; i++, j++)
{
// do something
}
Notes:
You can have any many initializers in the for loop definition as you like. Just make sure you index all of the values to avoid any infinite loops that might occur.
(Another snippet I originally posted to CodeKeep.)
Code:
// Required libs
using Microsoft.Office.Interop.Excel;
using Microsoft.Office.Tools.Excel.Extensions;
using Tools = Microsoft.Office.Tools;Range range = <get the target range to apply the label over>
string controlName = <unique name for the control to avoid collisions on other worksheets>// Add a control
Tools.Excel.Controls.Label lbl = worksheet.Controls.AddLabel(targetRange, controlName);// Add meaning to the label
lbl.Text = Title;
lbl.TextAlign = ContentAlignment.MiddleCenter;
lbl.BorderStyle = BorderStyle.FixedSingle;
lbl.ForeColor = Color.Black;
lbl.BackColor = Color.Green;// Delete a control
worksheet.Controls.Remove(controlName);
Usage:
//Add
lbl = worksheet.Controls.AddLabel(targetRange, controlName);// Delete
worksheet.Controls.Remove(controlName);
Notes:
If your range extends beyond a single cell, clear it before merging and applying the control. EG: range.Value2 = String.Empty; range.MergeCells = true; range.Value2 = Title;
Setting the cell background color and border, works around the label border artifacting. I was getting a strange green 1px line when I tried to define the borders in the label. I dropped the explicit settings and applied the border settings to the underlying cell and the green lines disappeared. It is probably something related to the Interop / Tool interaction.
If you are hitting a large number of cells, toggle Application.ScreenUpdating (false/true) to speed up the update and eliminate the screen flutter.
(Another snippet I originally posted to CodeKeep.)
Code:
Range rng = <your range>;
if (rng.get_End(XlDirection.xlToLeft) != rng.get_End(XlDirection.xlToLRight)
{
rng.Value2 = string.Empty;
rng.MergeCells = true;
}
rng.Value2 = Title;
rng.HorizontalAlignment = XlHAlign.xlHAlignCenter;
rng.VerticalAlignment = XlVAlign.xlVAlignCenter;rng.Font.Size = 10;
rng.Font.Bold = true;
rng.Borders.Weight = XlBorderWeight.xlMedium
Notes:
The range must be large than a single cell for the ‘MergeCells = true’ to work.
I’ve had problems with get_End. In some cases, I parsed the address range manually as when I needed the address range for the first column in a listObject.DataBodyRange. In other cases, using get_End worked just fine.
(Another snippet I originally posted to CodeKeep.)I’m realizing most of the code I kept on CodeKeep is fairly old, circa .Net 3.0.
Code:
IPlugin Interface:
public interface IPlugin { void Run(); }
IPluginAttribute:
[AttributeUsage(AttributeTargets.Class)] public class PluginAttribute : Attribute { private readonly Guid guid; private readonly string requiredRight; private readonly string menu; /// <summary> /// Gets a GUID that identifies the plugin. This identifier should /// remain constant between plugin versions. /// </summary> public Guid Guid { get { return guid; } } /// <summary> /// Gets the Active Directory right that users must have in order /// to use the plugin. The plugin itself is not expected to verify /// user rights. /// </summary> public string RequiredRight { get { return requiredRight; } } /// <summary> /// Gets a tab-delimited string that represents the desired menu /// hierarchy into which the plugin should be placed. /// </summary> /// <remarks> /// After separation into <c>n</c> strings, the first <c>n - 1</c> /// strings represent menu sub-levels, and the last string represents /// the menu entry that should launch the plugin. If this property /// is null or the empty string, the plugin should not be placed in /// any menu structure. /// </remarks> public string Menu { get { return menu; } } /// <summary> /// Initializes a new instance of the <c>PluginAttribute</c> /// class with the specified values for the <see cref="Guid" />, /// <see cref="RequiredRight" />, and <see cref="Menu" />properties. /// </summary> /// <param name="guid" />A <see cref="System.Guid" />that uniquely /// identifies the plugin. /// <param name="requiredRight" />A string that names a required Active /// Directory right /// <param name="menu" />A string representing the desired menu /// hierarchy. public PluginAttribute(Guid guid, string requiredRight, string menu) { this.guid = guid; this.requiredRight = requiredRight; this.menu = menu; } public PluginAttribute(string guidText, string requiredRight, string menu) : this(new Guid(guidText), requiredRight, menu) { } /// <summary> /// Initializes a new instance of the <c>PluginAttribute</c> /// class with the specified values for the <see cref="Guid" />and /// <see cref="RequiredRight" />properties. The <see cref="Menu" /> /// property is set to the empty string. /// </summary> /// <param name="guid" />A <see cref="System.Guid" />that uniquely /// identifies the plugin. /// <param name="requiredRight" />A string that names a required Active /// Directory right public PluginAttribute(Guid guid, string requiredRight) : this(guid, requiredRight, "") { } public PluginAttribute(string guidText, string requiredRight) : this(guidText, requiredRight, "") { } }
Attribute Tag in the assembly:
[Plugin("GUID","AccessRights","Topic\tSubtopic\tName")]
Lookup:
IEnumerabletypes = thisAssembly.GetTypes(); foreach (Type type in types) { if ((typeof(IPlugin).IsAssignableFrom(type) &&(type.GetCustomAttributes(true).Count() > 0)){var objs = .GetCustomAttributes(true);foreach (object obj in type.GetCustomAttributes(true)){var pa = obj as PluginAttribute;if (pa != null){str.Append("\t" + obj.GetType() + ": \t" + obj + Environment.NewLine);str.Append("\tGuid: " + pa.Guid + Environment.NewLine);str.Append("\tMenu: " + pa.Menu + Environment.NewLine);str.Append("\tRequiredRight: " + pa.RequiredRight + Environment.NewLine);str.Append("\tTypeId: " + pa.TypeId + Environment.NewLine);str.Append(Environment.NewLine);}}}}}
(Another snippet I originally posted to CodeKeep.)
Change ‘IPlugin’ to suit your needs.
Code:
Assembly thisAssembly = AssemblyBuilder.LoadFrom(pathToAssembly);
IEnumerable<Type> types = thisAssembly.GetTypes();
types = from t in types
orderby t.Name
select t;foreach (Type type in types)
{
if (typeof(IPlugin).IsAssignableFrom(type))
{
// Implements the IPlugin interface
// Do something interesting
}
}
(Another snippet I originally posted to CodeKeep.)
Code:
public static class FileManagement
{public static List<FileInfo> GetFiles(string rootDirectory)
{Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.ToString() + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "() called.");
DirectoryInfo di = new DirectoryInfo(rootDirectory);
List<FileInfo> files = new List<FileInfo>();GetFileList(di, ref files);
foreach (FileInfo file in files)
Debug.WriteLine(file.FullName);return files;
}private static void GetFileList(DirectoryInfo di, ref List<FileInfo> files)
{Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.ToString() + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "() called.");
foreach (FileInfo file in di.GetFiles())
files.Add(file);foreach (DirectoryInfo innerDir in di.GetDirectories())
GetFileList(innerDir, ref files);}
}
Usage:
List<FileInfo> files = GetFiles(rootDirectory);
(Another snippet I originally posted to CodeKeep.)
Using reflection inside a method to determine where you are in the control flow via the output window.
This is another snippet I used to have on CodeKeep.net.
I like to put a lot of debugging statements in my code and tracking the code exec is much easier if I know which methods are being called. I don’t do this so much anymore as VS2010 has greatly improved debugging over VS2008 and VS2005.
Code:
string callingAssemblyName = System.Reflection.Assembly.GetCallingAssembly().FullName;
string methodName = System.Reflection.MethodBase.GetCurrentMethod().Name;
string className = System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.ToString();
Usage:
using System.Diagnostics;
Debug.WriteLine(System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.ToString() + "." + System.Reflection.MethodBase.GetCurrentMethod().Name + "() called.");
or
string methodName = System.Reflection.MethodBase.GetCurrentMethod().ReflectedType.ToString() + "." + System.Reflection.MethodBase.GetCurrentMethod().Name;
Debug.WriteLine(methodName + "(" + <method args> + ") called.");
…
Debug.WriteLine(methodName + "() ending.");