SyntaxHighlighter

Showing posts with label c#. Show all posts
Showing posts with label c#. Show all posts

Friday, 27 October 2017

Open & Close a VPN Connection with C#

I've thrown together this simple class to check if a windows VPN connection is open and with it you can also connect and disconnect. It's not massively robust but does the trick. It's makes use of the rasdial command and is inspired by this post on SO.

Here's how to use it:
//Get a VPN connector ready
VPNConnector vpn = new VPNConnector("VPN_NAME", "USER_NAME", "USER_PASSWORD");

//Connect
Tuple<bool, IList<string>> response = vpn.Connect();

if (response.Item1)
{
    //Successfully connected
    Console.WriteLine("Connected!");
}
else
{
    //Failed to connect
    Console.WriteLine("Failed to connect :(");
    foreach (string s in response.Item2)
    {
        Console.WriteLine(s);
    }
}

//Disconnect
vpn.Disconnect();

You can optionally check if the connection is already open by using vpn.IsOpen.

The code:
/// <summary>
/// Gives access to Windows VPN connections
/// </summary>
public class VPNConnector
{

	#region Properties

	#region VPNName
	/// <summary>
	/// The name of the VPN connection
	/// </summary>
	public string VPNName { get; set; }
	#endregion

	#region Username
	/// <summary>
	/// The username to use for the connection
	/// </summary>
	public string Username { get; set; }
	#endregion

	#region Password
	/// <summary>
	/// The password to use for the connection
	/// </summary>
	public string Password { get; set; }
	#endregion

	#region IsOpen
	/// <summary>
	/// Whether the connection is currently open or not
	/// </summary>
	public bool IsOpen
	{
		get
		{
			if (String.IsNullOrWhiteSpace(this.VPNName))
				throw new ArgumentException("No VPN name (VPNName) has been set");
			
			Process p = this.getNewProcess;
			p.Start();

			bool bOpen = false;
			while (!p.StandardOutput.EndOfStream)
			{
				string sOutput = p.StandardOutput.ReadLine();
				if (sOutput.ToLower() != "no connections")
				{
					if (sOutput == this.VPNName)
					{
						bOpen = true;
						break;
					}
				}
				else
					break;
			}
			p.WaitForExit();

			return bOpen;
		}
	}
	#endregion

	#region parametersAreASet
	/// <summary>
	/// Determines if all the necessary parameters are set to make a VPN connection
	/// </summary>
	private bool parametersAreASet { get { return (!String.IsNullOrWhiteSpace(this.VPNName) && !String.IsNullOrWhiteSpace(this.Username) && !String.IsNullOrWhiteSpace(this.Password)); } }
	#endregion

	#region getNewProcess
	/// <summary>
	/// Get a new process ready to start a rasdial call
	/// </summary>
	private Process getNewProcess
	{
		get
		{
			return new Process
			{
				StartInfo = new ProcessStartInfo
				{
					FileName = "rasdial.exe",
					UseShellExecute = false,
					RedirectStandardOutput = true,
					CreateNoWindow = true
				}
			};
		}
	} 
	#endregion

	#endregion

	#region Cosntructor
	public VPNConnector() { }

	public VPNConnector(string name, string username, string password)
	{
		this.VPNName = name;
		this.Username = username;
		this.Password = password;

		if (!this.parametersAreASet)
			throw new ArgumentException("All arguments must have a value");
	}
	#endregion

	#region Public Methods

	#region Instance

	#region Connect
	/// <summary>
	/// Make a connection to the VPN. Item1 of Tuple indicates success or failure. Item2 of Tuple is the output of the dial call
	/// </summary>
	public Tuple<bool, IList<string>> Connect()
	{
		if (!this.IsOpen)
		{
			if (!this.parametersAreASet)
				throw new ArgumentException("All arguments must have a value");

			Process p = this.getNewProcess;
			p.StartInfo.Arguments = $"\"{this.VPNName}\" \"{this.Username}\" \"{ this.Password}\"";
			p.Start();

			bool bSuccess = false;
			IList<string> outputs = new List<string&gt();
			while (!p.StandardOutput.EndOfStream)
			{
				string sOutput = p.StandardOutput.ReadLine();
				outputs.Add(sOutput);

				if (sOutput.ToLower().StartsWith("success"))
					bSuccess = true;
			}
			p.WaitForExit();

			return new Tuple<bool, IList<string>>(bSuccess, outputs);
		}
		else
			return new Tuple<bool, IList<string>>(false, new List<string>() { "Connection already open" } );
	}
	#endregion

	#region Disconnect
	/// <summary>
	/// Disconnect from the VPN. Item1 of Tuple indicates success or failure. Item2 of Tuple is the output of the dial call
	/// </summary>
	public Tuple<bool, IList<string>> Disconnect()
	{
		if (this.IsOpen)
		{
			Process p = this.getNewProcess;
			p.StartInfo.Arguments = $"\"{this.VPNName}\" /d";
			p.Start();

			bool bSuccess = false;
			IList<string> outputs = new List<string>();
			while (!p.StandardOutput.EndOfStream)
			{
				string sOutput = p.StandardOutput.ReadLine();
				outputs.Add(sOutput);

				if (sOutput.ToLower().Contains("success"))
					bSuccess = true;
			}
			p.WaitForExit();

			return new Tuple<bool, IList<string>>(bSuccess, outputs);
		}
		else
			return new Tuple<bool, IList<string>>(false, new List<string&gt() { "Connection already closed" });
	}
	#endregion

	#endregion

	#endregion

}

Friday, 2 December 2016

Set Many Properties in One Go

If you're looking for a way to set the value of many properties who's name starts with the same string, then look no further!

Here's a useful extension you can add to an object.
public static class Extensions
{
    public static void SetPropertiesToValue(this object obj, string propertyNameStartsWith, Type propertyType, object val)
    {
        foreach (PropertyInfo prop in obj.GetType().GetProperties())
        {
            if (prop.Name.StartsWith(propertyNameStartsWith) && prop.PropertyType == propertyType && prop.CanWrite)
                prop.SetValue(obj, val);
        }
    }
}

And here's how to use it:
myObj.SetPropertiesToValue("Name", typeof(string), "Jim");
This will set any property of myObj that has a name starting with Name to Jim.

Thursday, 27 August 2015

Filter an Enum By String Value in C#

I have an enum declared and wanted to get all items in the enum that contained certain text. Well, this can be done using Linq and here's an example:

public enum Animals
{
    Dog,
    Cat,
    Mouse,
    Sheep
}

var filteredAnimals = Enum.GetValues(typeof(Animals))
    .Cast<Animals>()
    .Where(t => !t.ToString().Contains("e"))
    .ToList()

This gives a list of Mouse and Sheep.

Further to that, if wanted to get the maximum integer value of your filtered list, then you could use this:

public enum Animals
{
    Dog,
    Cat,
    Mouse,
    Sheep
}

var filteredAnimals = Enum.GetValues(typeof(Animals))
    .Cast<Animals>()
    .Where(t => !t.ToString().Contains("a"))
    .Cast<int>()
    .Max()

This gives us 1 as Cat is the highest enum that contains an "a"

Saturday, 25 July 2015

Setting a Default Value on a C# Property

Came across this little beauty for setting a default value on a C# 5.0 and below property so you can condense this:

private int myInt = 3;
public int MyInt
{
    get { return this.myInt; }
    set { this.myInt = value; }
}

Into this:

[System.ComponentModel.DefaultValue(3)]
public int MyInt { get; set; }

Obviously there's an array of variable types that can be used.

C# 6.0 is due to have a further tweak to allow us to do this:

public int MyInt { get; set; } = 3;

Sweeet :)

Thursday, 9 April 2015

Overload Resolution Failed Because No Accessible Is Most Specific For These Arguments

I have a method which has two overloads where I can pass one of two object types. In some cases, these objects may be Nothing or null. When this is the case, you will almost certainly get the Overload resolution failed because no accessible is most specific for these arguments compile error.

It's quite simple to sort as you you literally just cast the Nothing or null to the type you want it to be processed as. For example:

In C#
public void MyMethod(object1 o)
{
    //Some code...
}

public void MyMethod(object2 o)
{
    //Some code...
}

...

MyMethod((object1)null);

In VB.Net
Public Sub MyMethod(o As object1)
    'Some code...
End Sub

Public Sub MyMethod(o As object2)
    'Some code...
End Sub

...

MyMethod(Cast(Nothing, object1))

Saturday, 22 March 2014

C# & VB.NET Trim String To a Specific Length

I needed to trim some strings that if over a certain length would trim nicely and add "..." to the end. I particularly like to use extension methods in .NET where possible so I created this little TrimTo extension. There are some optionals that can be sent through including the characters whack on the end and whether to swap out the HTML br tag (I needed this - you may not ;) )

C#
public static class Extensions
{
 /// <summary>
 /// <summary>
 /// Trim a string to a specific length
 /// </summary>
 /// <param name="size">The finishing size of the string</param>
 public static string TrimTo(this string s, int size)
 {
  return TrimTo(s, size, "...");
 }

 /// <summary>
 /// Trim a string to a specific length
 /// </summary>
 /// <param name="size">The finishing size of the string</param>
 /// <param name="chars">The characters to put at the end of the string. Defaults to "..."</param>
 public static string TrimTo(this string s, int size, string chars)
 {
  return TrimTo(s, size, chars, false);
 }

 /// <summary>
 /// Trim a string to a specific length
 /// </summary>
 /// <param name="size">The finishing size of the string</param>
 /// <param name="chars">The characters to put at the end of the string. Defaults to "..."</param>
 /// <param name="doBRs">Where to replace new lines with &lt;br /&gt;. Defaults to false</param>
 public static string TrimTo(this string s, int size, string chars, bool doBRs)
 {
  if (s.Length > size)
   s = String.Format("{0}{1}", s.Substring(0, size), chars);
  if (doBRs)
   s = s.Replace("\n", "<br />");
  return s;
 }
}

VB.NET
Public Shared Class Extensions
 ''' <summary>
 ''' <summary>
 ''' Trim a string to a specific length
 ''' </summary>
 ''' <param name="size">The finishing size of the string</param>
 Public Shared Function TrimTo(this string s, int size) As String
  Return TrimTo(s, size, "...")
 End Function

 ''' <summary>
 ''' Trim a string to a specific length
 ''' </summary>
 ''' <param name="size">The finishing size of the string</param>
 ''' <param name="chars">The characters to put at the end of the string. Defaults to "..."</param>
 Public Shared Function TrimTo(this string s, int size, string chars) As String
  Return TrimTo(s, size, chars, false)
 End Function

 ''' <summary>
 ''' Trim a string to a specific length
 ''' </summary>
 ''' <param name="size">The finishing size of the string</param>
 ''' <param name="chars">The characters to put at the end of the string. Defaults to "..."</param>
 ''' <param name="doBRs">Where to replace new lines with &lt;br /&gt;. Defaults to false</param>
 Public Shared Function TrimTo(this string s, int size, string chars, bool doBRs) As String
  If s.Length > size Then s = String.Format("{0}{1}", s.Substring(0, size), chars)
  If doBRs Then s = s.Replace("\n", "<br />")
  Return s
 End Function
End Class

C# Hex Colour to RGB

I have to do a lot of interop work with Word & Excel and generally struggle matching up colour pallets across the two applications and the only way I've found to consistently do this is by using RGB colours and the RGB function provided in VB(A).

Having recently started a new C# project that I am using hex colour codes with (e.g. #000000), I thought I would write a simple RGB colour handling class that converts the hex colour code into RGB codes for me. And here it is...

/// A helper class used to hold the RGB values of a hex colour e.g. #000000
/// </summary>
public class RGBColour
{
 private string _HexRef = String.Empty;
 public string HexRef
 {
  get { return this._HexRef; }
  set
  {
   if (!value.StartsWith("#"))
    throw new Exception("The hex colour reference must start with a #. e.g. #000000");
   if (value.Length < 7)
    throw new Exception("The hex colour reference must be 7 characters. e.g. #000000");
   this._HexRef = value;
   Color c = ColorTranslator.FromHtml(value);
   this._R = Convert.ToInt32(c.R);
   this._G = Convert.ToInt32(c.G);
   this._B = Convert.ToInt32(c.B);
  }
 }

 private int _R = 0;
 public int R { get { return this._R; } }

 private int _G = 0;
 public int G { get { return this._G; } }

 private int _B = 0;
 public int B { get { return this._B; } }

 public RGBColour()
 {
 }
 public RGBColour(string hexRef)
 {
  this.HexRef = hexRef;
 }
} 

It quite simply uses the System.Drawing.ColorTranslator.FromHtml method to convert the hex value into a System.Drawing.Color object. The Color RGB properties are then converted to an int32.

This can then be used like this...

RGBColour rgb = new RGBColour("#000000");
xl.ActiveCell.Interior.Color = xl.RGB(rgb.R, rgb.G, rgb.B);

Return Dynamic Generic IList in C#

I had a situation where I had a SQL statement stored against a row in a database. Depending on the row would depend on what data was output. For example, row 1 would return all the industries and row 2 would  return all the age groups and so on. Each of my tables has it's own C# class/object associated to it. So I have an Industry class and an AgeGroup class and so on.

The data that has the SQL logged against it was a table and object called PersonalDetail and the SQL was stored in a column/property called LookUpStatement. I wanted to get an Ilist<> of the data results that LookUpStatement returns when executed. The key thing I wanted to achieve was that the new method would return the IList<> strongly typed. So in the case of the industry data I would have IList<Industry> returned by it or for AgeGroup an IList<AgeGroup>.

The whole passing and returning of dynamic types has been something I have wanted to master for some time. After some extensive searching and no single article telling me exactly what I needed I managed to pile it all together and ended with this...

Calling and using it:

//Get the personal detail row that is required
// The Load method loads a specifc row from the database
// In this instance, row 1 LookUpStatement will select all industires (e.g. SELECT * FROM [Industry]) 
PersonalDetail personalDetail = PersonalDetail.Load(1);

//Get the industries as an IList from the personal detail object
IList<Industry> industries = personalDetail.LookUpData<List<Indstry>>();

Note that the LookUpData call is made using a List<> and not an IList<>.The code itself:

public class PersonalDetail
{

 public LookUpStatement
 {
  get; set;
 }
 
 //Other properties, constructor, etc...
 
 public T LookUpData<T>()
 {
  if (!typeof(T).Name.StartsWith("List"))
   throw new ArgumentException("The generic pass type must be a List<>"); 
  
  //Create a typed instance of the required List
  T os = (T)Activator.CreateInstance(typeof(T));
  
  //Get the base object propertype. e.g. Industry
        Type propType = typeof(T).GetProperty("Item").PropertyType;
  
  //Get the data as a DataSet
  DataSet ds = _DB.GetDataSet(this.LookUpStatement);
  
  //Iterate the data
  for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
  {
   //Get the data row
   DataRow dr = ds.Tables[0].Rows[i];

   //Use relfection to execute the Add method of the dynmaic List
   //Then use relfection to execute the LogItem method of the base object
   // Logitem converts the data row into the base object. e.g. Industry
   os.GetType().GetMethod("Add").Invoke(
    os,
    new object[] {
     propType.GetMethod("LogItem").Invoke(null, new object[] { dr })
    }
   );
  }
 }

}

The comments in the code should hopefully give an indication of how it works. Working out the T os = (T)Activator.CreateInstance(typeof(T)); took a while as defining the os object as IList<object> just wasn't working. Got there in the end though :)

Friday, 12 April 2013

How To Change the Value in the app.config File

If you need to be able to change values in your application's app.config file, then it is surprisingly easy :)

In VB

Dim config As Configuration = ConfigurationManager.OpenExeConfiguration( _
    ConfigurationUserLevel.None)
config.ConnectionStrings.ConnectionStrings("MyDB") _
    .ConnectionString = "A_DB_CONNECTION_STRING"
config.AppSettings.Settings("MySetting").Value = "A_SETTING_VALUE"
config.Save(ConfigurationSaveMode.Modified)
ConfigurationManager.RefreshSection("connectionStrings")
ConfigurationManager.RefreshSection("appStrings")

In C#

Configuration config = ConfigurationManager.OpenExeConfiguration(
     ConfigurationUserLevel.None);
config.ConnectionStrings.ConnectionStrings["MyDB"]
    .ConnectionString = "A_DB_CONNECTION_STRING";
config.AppSettings.Settings["MySetting"].Value = "A_SETTING_VALUE";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("connectionStrings");
ConfigurationManager.RefreshSection("appStrings");

In these examples, I am changing a connection string value and an app setting value. Once the config has been saved the modified section(s) need to be refreshed to ensure the new mods are loaded back into memory.

Remember that if your app is re-installed, then the modified app.config will be overwritten.

Thursday, 25 October 2012

HttpContext.Current.Session is null

Had a funny one with an ASP.NET 4.0 C# project I am working on. I moved my session handling into a class to keep things tidy. I started getting the old reference to a null object error when trying to access a session variable.

This initially confused me a little as I was already doing an if (context.Session["myvar"] == null) on it. I then realised that it was the Session object itself that was null. I did a lot of hunting around on Google - and there are hundreds of responses (HttpContext.Current.Session is null). None of them were working for me.

I had checked that sessions were enabled and that the Session_Start event was firing in Global.asax.cs. The most useful article I came across was this one on stackoverflow.

My session handling class was using private static HttpContext context = HttpContext.Current; so that I had a shorthand to the Session object (context.Session). I swapped out the shorthand to use the full path to it (HttpContext.Current.Session) and we were off - all working!

Tuesday, 17 April 2012

.NET Round Date to Nearest Hour

A quick little snippet here for those needing to round a DateTime in VB.NET or C# to the nearest hour

VB.NET
Public Shared Function RoundedHour(ByVal dt As DateTime) As DateTime
 Return DateTime.Parse( _
   String.Format("{0:yyyy-MM-dd HH:00:00}", _
     IIf(dt.Minute > 30, dt.AddHours(1), dt) _
 )
End Function

C#
public static DateTime RoundedHour(ByVal dt As DateTime) {
 Return DateTime.Parse(
   String.Format("{0:yyyy-MM-dd HH:00:00}",
     (dt.Minute > 30 ? dt.AddHours(1) : dt)
 )
}

It's pretty straight forward. If the minutes of the time are over 30 then add an hour. If not, keep using the given date. Format the date to have the minutes and seconds set to 0 and parse it back as a date.

Tuesday, 8 November 2011

Add a Border to a Panel Using .NET Compact Framework

After spending quite some time working out how to add a border round a panel control in the .NET compact framework, I finally got it working. It's pretty easy to be honest.

VB.NET
Using g As Graphics = e.Graphics
    Using p As New Pen(Color.Black, 1)
        g.DrawRectangle(p, 0, 0, MyPanel.Width - 1, MyPanel.Height)
    End Using
End Using

C#
Using (Graphics g = e.Graphics) {
    Using (Pen p = New Pen(Color.Black, 1)) {
        g.DrawRectangle(p, 0, 0, MyPanel.Width - 1, MyPanel.Height);
    }
}

You need to make sure that this code is put in the Paint event of your panel.

Friday, 24 June 2011

How To Enumerate / Iterate an Enum

I often find myself needing to iterate/enumerate an enum. It's dead easy, but seem to always forget! What a fool ;)

Anyway, here ya go...

Public Enum MyEnum
    Jim = 0
    Bob = 1
End Enum

For Each e As MyEnum in [Enum].GetValues(GetType(MyEnum))
    Console.Write(String.Concat(e.ToString(), "=", Int32.Parse(e)))
Next

The GetValues method is quite useful as you can also get stuff like the length from it:
[Enum].GetValues(GetType(MyEnum)).Length.

The C# is pretty much the same just that [Enum] has no square brackets around it.

Thursday, 7 April 2011

Could not establish trust relationship for the SSL/TLS secure channel with authority

I recently had this error (Could not establish trust relationship for the SSL/TLS secure channel with authority) when trying to make a remote call from a C# web app. I hunted around and came across this article on thejoyofcode.com.

ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(
    delegate
    {
        return true;
    }
);

So I used the suggested code to bypass the certificate verification, but got a trust level permission error. In order to get round that I modified the Web.Config file to have the trust level set to Full.

Just for the record, this is a quick and dirty hack while I sort out what the actual problem is ;)

Thursday, 11 November 2010

Dynamically Determine the Current Method / Function in C# and VB.NET

Needed to do some basic reflection the other day to easily determine the current method that was being executed in a VB ASP.NET application.

So here's the C# for it:

//Current method name
System.Reflection.MethodBase.GetCurrentMethod()
    .Name;

//Fully qualified name of the method's class
System.Reflection.MethodBase.GetCurrentMethod()
    .ReflectedType.FullName;

//Method's class name without Namespace
System.Reflection.MethodBase.GetCurrentMethod()
    .ReflectedType.Name;

//Namespace
System.Reflection.MethodBase.GetCurrentMethod()
    .ReflectedType.Namespace;

And the VB.NET:

'Current method name
System.Reflection.MethodBase.GetCurrentMethod(). _
    Name

'Fully qualified name of the method's class
System.Reflection.MethodBase.GetCurrentMethod(). _
    ReflectedType.FullName

'Method's class name without Namespace
System.Reflection.MethodBase.GetCurrentMethod(). _
    ReflectedType.Name

'Namespace
System.Reflection.MethodBase.GetCurrentMethod(). _
    ReflectedType.Namespace

Tuesday, 19 October 2010

Sending Email using ASP.NET via Google Apps Mail / GMail

I have recently moved all my hosting to go through Google Apps and it is sweet :)

This meant that I needed to modify my emailing routine in various .NET apps. A lot of this can be done via the Web.Config, but due to various reasons, I need to control it in code.

So configure your MailMessage object as per usual. I have added msg.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure; to mine, which could prove to be useful. Then configure your SmtpClient a follows:

SmtpClient smtp = new SmtpClient("smtp.gmail.com");
smtp.EnableSsl = true;
smtp.Timeout = 10000;
smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
smtp.UseDefaultCredentials = false;
smtp.Credentials = new System.Net.NetworkCredential("email@mydomain.com", "my-password");
smtp.Send(msg);

Now a lot of articles I read suggested that you need to use port number 587 for the SmtpClient. When I did, I got the following error:

Request for the permission of type 'System.Net.Mail.SmtpPermission' failed

So I tried without declaring it and it worked just fine :)

A point worth noting: Make sure the account you are sending the email through is the same account that you are sending from.

Labels

.net (7) ajax (1) android (7) apache (1) asp.net (3) asus (2) blogger (2) blogspot (3) c# (16) compact framework (2) cron (1) css (1) data (1) data recovery (2) dns (1) eclipse (1) encryption (1) excel (1) font (1) ftp (1) gmail (5) google (4) gopro (1) html (1) iis (3) internet explorer IE (1) iphone (1) javascript (3) kinect (1) linux (1) macro (1) mail (9) mercurial (1) microsoft (3) microsoft office (3) monitoring (1) mootools (1) ms access (1) mssql (13) mysql (2) open source (1) openvpn (1) pear (2) permissions (1) php (12) plesk (4) proxy (1) qr codes (1) rant (4) reflection (3) regex (1) replication (1) reporting services (5) security (2) signalr (1) sql (11) sqlce (1) sqlexpress (1) ssis (1) ssl (1) stuff (1) svn (2) syntax (1) tablet (2) telnet (3) tools (1) twitter (1) unix (3) vb script (3) vb.net (9) vba (1) visual studio (2) vpc (2) vpn (1) windows (4) woff (1) xbox 360 (1)