Showing posts with label Visual Studio Tips. Show all posts
Showing posts with label Visual Studio Tips. Show all posts

Wednesday, August 20, 2014

PS: Remove folder recursively

Recently I have to clean up my .Net solution with a long list of projects. One of cleanup is to remove all bin and obj folders. It is very tedious doing it manually.

I turn to Powershell Script to find a quick way. Soon I got my solution, only two lines of codes and I could do in PS console interactively:

Here is the function:

$a = Get-ChildItem -Path H:MyRepository\Solution\ -Recurse | Where-Object {$_Name -Match '^obj$' }
$a | { rm -r $_.FullName }

Repeat the same steps to remove bin folders.

Read More...

Thursday, May 08, 2014

.Net var (C#) Almost Everywhere, One Exception

Starting from .Net 3.0, Microsoft introduced type var in C#, as a simply way to binding strongly type. This is a very convenient way to define variables. Basically, .Net will be smart enough to infer correctly data type. It makes code maintenance and update much easy and no need to change data type in case variable types changed. I like it very much and use var almost everywhere.

However, recently I found one case this var is not able to infer explicit data type. In the case of dynamic delegate, you have to use explicit delegate type:


var myDelegate = delegate(int valueA, int valueB) { return valueA + valueB; };

.Net cannot infer what delegate type is for myDelegate. You have to use the explicit delegate type in this case:

delegate int SumOfTwoValues(int v1, int v2);
SumOfTwoValues myDelegate = delegate(int valueA, int valueB) { return valueA + valueB; };


I found this interesting exception when I was sharing my knowledge about delegate with my co-worker.

Read More...

Sunday, December 18, 2011

Using LDAP to Authenticate Windows Users

Here are some my programming notes about using LDAP library to authenticate Windows Users.

This request came from my ASP.Net project, which is hosted on intranet IIS server. The first login page is to authenticate Windows users in the company.  I need a library to do the job.  I tried some codes created long time before, but I found that the codes is not completed.  The authentication works only in Visual Studio, but not at an IIS server after deployment. I need to fix the issue.

I found that there are many ways to do that.  One is based on our existing codes with Novel.Directory.Ldap library, another on System.DirectoryServices. I tried both in one test console application.

Here some some references and constants used in the console application:

using System;
using Novell.Directory.Ldap;
using System.Collections.Generic;
using System.DirectoryServices;
using System.DirectoryServices.Protocols;
using AD_LdapConnection = System.DirectoryServices.Protocols.LdapConnection;
using ND_LdapConnection = Novell.Directory.Ldap.LdapConnection;
using System.Net;
...
private const string LDAPHOST = "xxxx.yy.zzzz.com";
private const int LDAPPORT = 389;
private const string DOMAINNAME = "yy";
private const string CN_NAME_SUFIX = "@yy.zzzz.com";

Novel.Directory.Ldap


The first one is base on Novel.Directory.Ldap:

private static bool Authenticate(string username, string pwd)
{
  bool bRet = false;
  bool connected = false;

  // connect to LDAP server
  ND_LdapConnection ldapConnLogin = new ND_LdapConnection();
  try
  {
    Console.WriteLine("Start authenticating...\nConnecting to {0}, port: {1}",
      LDAPHOST, LDAPPORT);
    ldapConnLogin.Connect(LDAPHOST, LDAPPORT);
    connected = ldapConnLogin.Connected;
    if (connected)
    {
      Console.WriteLine("Connected: {0}", connected);

      string cn = string.Format(
        "{0}{1}", username, CN_NAME_SUFFIX);
      Console.WriteLine("Binding with {0}", cn);
      ldapConnLogin.Bind(cn, pwd);
      bRet = ldapConnLogin.Bound;
      Console.WriteLine("Bound: {1}", bRet);
    }
  }
  catch (Exception ex)
  {
    string msg = string.Format(" Error message or code: {0}", ex.Message);

    Console.WriteLine(msg);
    bRet = false;
  }
  finally
  {
    if (ldapConnLogin != null && connected)
    {
      ldapConnLogin.Disconnect();
    }
    ldapConnLogin = null;
  }

  return bRet;
}

This methods depends on ldap host name, port number, and cn name(in a format like email address in our company). One thing interesting is that the exception thrown from the binding call are error codes in Message, and no implementation of ToString() method.

System.DirectoryServices


The second method is Microsoft .Net library APIs in System.DirectoryServices. The following codes are much simpler and works in the same way to authenticate a Windows user:

private static bool Authendicate2(string domain, string userName, string password)
{
  bool validation = false;
  try
  {
    Console.WriteLine("Authenticating user by AD library...");
    var ldc = new AD_LdapConnection(
        new LdapDirectoryIdentifier(LDAPHOST, false, false));
    NetworkCredential nc = new NetworkCredential(userName, password, domain);
    Console.WriteLine("Created credencial object.");
    ldc.Credential = nc;
    ldc.AuthType = AuthType.Negotiate;
    Console.WriteLine("Binding credencial...");
    ldc.Bind(nc);
    // user has authenticated at this point, as the credentials were used to login to the dc. 
    Console.WriteLine("Binding credencial is done.");
    validation = true;
  }
  catch (Exception ex)
  {
    Console.WriteLine("Exception: {0}", ex.Message);
    validation = false;
  }
  return validation;
}

References

Read More...

Saturday, January 23, 2010

.Net Reflector

.Net Reflector is a must-have tool for .Net developers. Last year I updated my Visual Studio at work to 2008. However, I forgot to add this tool. When I started to work on a project based on MEF(Managed Extensibility Framework) as DI (dependency injection), this reminded me about the tool. I need this tool to browse the class structure of Microsoft.ComponentModel.Composition.dll.

The tool was developed by Lutz Roeder. In his blog, he said that now it is transfered to Red Gate Software. I think I used the SQL Compare application from this company. Anyway, .Net Reflector is a Windows based application, and it is very easy to install as a tool in VS 2008. From the menu Tools->External Tools..., it can be added there. Here is a snapshot of the installation:



There are also many Add-Ins for this tool.

Read More...

Sunday, September 06, 2009

CodeDom and Expression Calculator (2)

In order to compile a snip of codes dynamically, I need to define a template in the class of ExpressionEvaluation so that it can be used as a base. The template contains several parameters which will be replaced (such as a class name, a data type and an expression). I defined a string with parameters enclosed by {} so that those parameters can be easily replaced by dynamic values (string.Format(template, parameters...)).

Here is the template of snip codes in the class:


using System;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;

public class ExpressEvaluation { // class name
  private const string _InitalizeValueCode = "private {0} _value = {1};"; // valType, valExp
  private const string _ClassName = "_CalculatorWithFormula"// 0
  private const string _MethodAnswer = "Answer"// 1
  private const string _SourceCodeTemplate = @"
using System;
public class {} {{ // {{0}} Class name
  {2}
  public {} {1}()  // {{1}} method to be called to get result
  {{
    return _value;
  }}
}}";


  public int GetAnswer()         // method to get result as type
  {
    return _value;
  }
}


The key methods in the class are BuildCodes() and GetAnswerByBuildAndRunCodes():

private static string BuildCodes(
    string valueExp,
    string varType)
{
    string initializeValueCodes = string.Format(
            _InitalizeValueCode, varType, valueExp);

    string codes = string.Format(_SourceCodeTemplate,
        _ClassName, _MethodAnswer, initializeValueCodes, varType);

    return codes;
}

private static T GetAnswserByBuildAndRunCodes<T>(
    string sourceCodes) where T : struct
{
    object value = default(T);
    CompilerResults cr = GetCompiler(sourceCodes);

    var instance = cr.CompiledAssembly.CreateInstance(_ClassName);
    Type type = instance.GetType();
    MethodInfo m = type.GetMethod(_MethodAnswer);
    value = m.Invoke(instance, null);

    return (T)value;
}

Those two methods are very straightforward. In GetAnswserByBuildAndRunCodes(), a method GetCompiler() is called to get a C# CompilerResults object in the current context:

private static CompilerResults GetCompiler(string codes)
{
    CSharpCodeProvider codeProvider = new CSharpCodeProvider();

    CompilerParameters parameters = new CompilerParameters();
    parameters.GenerateExecutable = false;
    parameters.GenerateInMemory = true;
    parameters.IncludeDebugInformation = false;

    foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
    {
        parameters.ReferencedAssemblies.Add(asm.Location);
    }

    return codeProvider.CompileAssemblyFromSource(parameters, codes);
}

Here is the complete source codes for download.

Read More...

Sunday, August 23, 2009

CodeDom and Expression Calculator (1)

I have subscribed to .Net Rock podcast and I enjoy listening to this talk on weekly base. At the beginning of almost each talk Carl always gives a small section about one .Net framework library. It is a very brief information about the .Net library or namespace and some descriptions or usages about using it. Recently he mentioned something about Compiler to compile codes but he admitted that he does not know where to use it and how to use it. He just thrown it out.

This reminded me immediately about System.CodeDom namespace. I have used this to dynamically build source codes, to compile codes, to create an instance and to get result by calling a method of the instance. It is very cool stuff. I use this feature to get result of a expression such as:

    24*60*60

so that I can use expression in a configuration XML file. Since the expression is evaluated by building a snip of dynamic codes, the expression can also be a expression of C# codes like:
   Date.Parse(Date.Now.ToShrotDateString())

in the configuration file as a current date in a short date string. Eventually, the value will be a DateTime value as a property value.

I created a class called as ExpressionCalculator. Here is an examples of how to use the class to evaluate expressions:


int iVal = true;
ExpressionCalculator expCalc = new ExpressionCalculator();
expCalc.SetConfiguration("24*60*60",
    ExpressionCalculator.ECValueType.Integer).
    GetAnswer<int>(ref iVal);

Think about the snip codes to evaluate an expression. This is very simple. Here is an example:

using System;
public class ExpresssionEvaluation { // class name
  private int _value = 24*60*60; // type and expression
  public int GetAnswer()         // method to get result as type
  {
    return _value;
  }
}

What I need to evaluate an expression result is to generate a snip of codes with expression and expected type dynamically replaced. By using CodeDom classes, the snip of codes can be built and compiled. Then instance of ExpressionEvaluation can be created. Finally the result can be obtained by calling the method GetAnswer().

Interestingly, I found that the CodeDom compiler uses the exactly same compiler to compile the source codes in %tmp% directory. The assembly then is loaded by using Reflection to get all the classes, properties and methods. I found those background stuff while I had some compiler error with the snip of codes.

Read More...

Tuesday, December 04, 2007

Add Reference to Visual Studio 2005

I have installed .Net Framework 3.5 in my box (not 3.0) and WCSF for a ASP.NET project based on WCSF. When I tried to use Guidance Package Manger's Add Page Flow Project recipe I got an error and failed to add the project.

I wondered why it failed. It must use some kind template to add project. I then found the template project which has the following references but I cannot see them in my VS Add Reference Dialog window:

<Reference Include="System.Workflow.Activities" />
<Reference Include="System.Workflow.ComponentModel" />
<Reference Include="System.Workflow.Runtime" />

I think that is the reason I get the failure. My direct reaction was that I thought .Net 3.5 may not include or install 3.0 assembly files. That's wrong. From VS Add Reference list, I can see that System.WorkFlowServices.dll is located in C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\, and others which are not in VS's Add Reference window are in ...\v.30 folder.

It must be some settings such as environment or registry settings which make these assembly files visible in VS. I can find where those settings are. Anyway, cut the story in short, I found a msdn link about How to: Add ore Remove Reference in Visual Studio 2005. This web page does provide information on how to add customized assemblies in VS by setting windows registries. I followed the instruction I found that the NUnit and MbUnit assembly files I installed are set in the registry and they are in VS Add Reference window. Here are examples of NUnit 2.4.3 and MbUnit in the current user registry:
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework\AssemblyFoldersEx\NUnit 2.4.3]@="c:\Program Files\NUnit 2.4.3\bin\"
[HKEY_CURRENT_USER\SOFTWARE\Microsoft\.NETFramework\v2.0.50727\AssemblyFoldersEx\MbUnit]@="c:\Program Files\MbUnit\"

Notice that NUnit is not related to any version while MbUnit is under .Net v2.0.50727. According to the msdn, if you add assembly location folders in HKEY_LOCAL_MACHINE in the same way, any user in the pc then can see these assemblies in VS.

Those are settings for third party to add their assemblies to VS 2005's Add Reference window. However, I still can not find any thing bout Microsoft assembly settings. I know where assembly files are, but I don't know what settings to cause them visible in the VS 2005's Add Reference window. Maybe Microsoft does not want people to mess up third party programs with Microsoft ones.

Anyway, I finally find a way to get them visible in VS 2005. I installed Visual Studio 2005 extensions for .NET Framework 3.0 (Windows Workflow Foundation). The installation did some magic settings and I can add Page Flow Project without any failure and I do see these v3.0 WowkFlow assembly files in VS 2005.

Read More...

Friday, November 30, 2007

Create Templates for Visual Studio 2005

Create customized templates for Visual Studio 2003 and VS 2005 are very different. David Hayden has one blog on this issue with VS 2005.

It is very easy to create either a template project or template item in VS 2005. VS 2005 provides a wizard to do that from File|Export Templates... By the way, if you cannot find the Export menu item, you have to add it from Customize toolbar and drag the Export item under the File menu item.

However, I don't like to use the wizard to create or modify my template if I find some minor things to change or to create another one based on an existing one. I would like to work on copy-and-past pattern. The first thing I have to find out where my templates are and how they are organized.

For example, I created a template class item for NUnit test class. I want to create a similar one for MbUnit. I found out that after finished the wizard, my NUnit template is created under the following three locations (%userprofile% is "c:\Documents and Settings\[username]"):

%userprofile%\Application Data\Microsoft\VisualStudio\8.0\ItemTemplatesCache\NUnitTestClass.zip\
%userprofile%\My Documents\Visual Studio 2005\My Exported Templates\NUnitTestClass.zip
%userprofile%\My Documents\Visual Studio 2005\Templates\ItemTemplates\NUnitTestClass.zip

Actually, the template is saved at the third location. The first one is a cached template. If I want to change or create a new one, I have to go the last location to update or create one. After that, I copy and paste the new template to the second location.

It is much easier to update or create new template in this way.

By the way, I find one location in Google Code to host project files for downloading. I created my project site. I am going to put my source codes there. Here is list of my templates for NUnit and MbUnit test classes.

Read More...

Thursday, November 29, 2007

A Solution for Assembly Version Issue

Continuing with the issue I described in Rhino.Mocks and AutoMockingContainer, I found another solution to resolve the problem instead of recompiling AutoMockingContainer.

It is not always the case that you can get dependent library source codes. The alternative solution to redirect the .Net CLR to load a new version of the specified assembly. I'll take the my test project with Rhino.Mocks and AutoMockingContainer as an example. The Rhino.Mocks version I used in my project is version 3.3.0.906, while AutoMockingContainer was built with Rhino.Mocks version 2.8.1.2631 as its dependency. My test project will be compiled as TestClasses.dll. By default, all the binaries will be copied to Output directory with the latest Rhino.Mocks (3.3.0.906).

When my test class tries to call any AutoMockingContainer class which depends on Rhino.Mocks (2.8.1.2631), the .Net CLR cannot find the specified strong named assembly dll, and then exception was thrown.

I remembered that when .Net was released, it claimed to resolve COM-hell issue with versions and it allows two or more different versions of assembly running within a process. One way to resolve the version issue is to promote the version by using assembly's configuration file. For more information about .Net configuration, see Configuration File Schema for the .NET Framework.

That link provides a way to redirect old version to new version by using configuration's bindingRedirect element. Here is what I did in my test project:

  1. Add a configuration file to the project where AutoMockingContainer is referenced. The file name should be as same as the project name with congif extension. For example, I used "TestClasses.dll.config".

  2. Right click on this file and set Copy to Output Directory to Copy Always.

  3. Add the following line to the configuration file (make changes depending on your case):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Rhino.Mocks"
publicKeyToken="0b3305902db7183f"
culture="neutral" />
<bindingRedirect oldVersion="2.8.1.2631"
newVersion="3.3.0.906"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

  1. Finally compile the project. The project should run (with NUnit test program) without exception.


I used the tool of Lutz' .Net Reflector to find assembly's version. It's a great tool for developers.

Read More...

Wednesday, November 28, 2007

Update Assembly Version

Continuing from the previous blog, I found two places talking the related issue: how to manage assembly version:



The utility program's author, Matt, also posted two interesting tools: one for system tray icon with tooltips, and another PrefTimer timer class based on API.

Read More...

Sunday, June 17, 2007

Signing a Solution for publishing

For publishing application by click-once to deploy, I found that I have to set all the assemblies or projects to sign with a key file (pfx). In the project which is the start one, you have to make sure the Certificate option is checked in project's property Signing tab and make sure this certificate was generated by the same key file. Otherwise, you will get an error message saying failure to run tool SignTool.

After every thing are built correctly, you may use internet explorer to link to the URL which was set in the solution's property (Publication Location). Click on Install to deploy the application. You may have download the setup.exe installation file first. You will get an application file such as Bankshell.application. Still you cannot run the application in your downloaded folder. You have find the file in your URL location, where you can click on Bankshell.application to install the application.

This is just a note for me as a reference. I got this problem while I was doing exercises of Lab 5: Building the End-to-End Global Bank Application, Patterns & Practices (CAB).

Read More...

Friday, April 27, 2007

DataSet 2.0 Issues

When I tried to use Visual Web Developer 2005 Express to compile a project with TypedDataSet, I got some warning message for compling. Basically, these warning messages are about some XML attributes for DataSet not being declared. For example:

Warning 2 The 'ParameterPrefix' attribute is not declared. G:\Datadc\Programming\ASP.Net\Data Tutorials\DT01\App_Code\Northwind.xsd 8 231 G:\...\DT01\

I googled solution to find out why and to remove these warning. Here is a link about this issue. In short, these attibutes are not defined in VS IDE's xsd file. I could to add these attributes there but it is not recommended. Steve Cheng from Microsoft Online Help said that you can ignore these messages and the build should be fine.

That's a good explaination for this issue.

Read More...