November 29, 2006

Windows Miscellaneous

Virtual PC
Creating a Virtual PC using another machines Virtual Hard Disk
Make a copy of the other machines .vhd file.
Copy to the local machine and point the new Virtual PC to the .vhd.
SID will have to be run on the new Virtual PC in order to change the name of the machine, as it will still have the name of the original machine the vhd was taken from.

http://www.microsoft.com/technet/sysinternals/Security/NewSid.mspx

HTML DOM Inspector
http://www.sharewareconnection.com/download-ie-dom-inspector-from-sharecon.html

November 14, 2006

dotNET - VS 2005 Web Deployment Projects + Installer (MSI) creation

You've got your Web Project in Visual Studio and you want to create a way to provide it as an installation.
There are 2 ways to do this:
1. Create a Web Deployment Project from your Web Project and then use the output of this as the input to another project, a Setup Project.
After you've achieved this you'll have an MSI installer file which has configurable elements, these configurable elements will be dictated by yourself when creating the Web Deployment Project and the Setup Project.
2. Create a WebSetup project from your Web Project.
After you've achieved this you'll have an MSI installer file.

Option 2 is the simpler option.
The difference between the 2 options is that the first provides extra control using the Deployment project, such things a MSBuild and assembly type deployment.


If you choose option 1 then:
  • You can quickly create a Web Deployment Project by right-clicking the Web Project in the Visual Studio Solution Explorer. This will copy the contents of your Web Project into the new Deployment Project. See the links below on how to customise the settings.
  • The Setup Project uses the Web Deployment Project, this is achieved by adding the Web Deployment projects output as a reference, Right Click on the Setup Project...
  • Notes:
  • I noted during the Web Deployment Project creation that;
  • Changing the Project Properties does not always apply e.g. I changed the Property Pages->Deployment section to "appsettings=appsettings.config", this indicates the appsettings section of the Websites web.config should be overridden with that in the appsettings.config file in the source Web Project. But the appsettings is case-sensitive, I fixed it but it still did not apply resulting in a compilation error, I had to edit the project file itself using the VS editor. The contents of the appsettings.config file is the complete appSettings section, including the appSettings tags.
  • The appSetting file is located in the original Web Project.
  • Using appSettings=appsettings.config in the Web Deployement Project's Property Pages->Deployment section it overrides the appSettings section.
If you choose option 2 then:
  • This is a much simpler solution and really just copies the contents of your Web project into an exe or msi file for later installation.
  • Create a Web Setup project from the File->New Project dialog, under Setup and Deployment.
  • Add the Web site project's Output as a reference in the WebSetup project.

For both option 1 and 2 you'll need to create some sort of Setup project, either a Setup project (Option 1. which uses the output of the Web Deployment project) or a Web Setup project (Option 2. which uses the Web project directly).
For more on both types of Setup project and how to use the user input see the article later in this blog dotNET - Setup Programs Installer creation using VS2005

Using Web Deployment Projects with Visual Studio 2005 (msdn)
ScottGu's Blog - VS 2005 Web Deployment Projects
Modifying Web.Config during Website Installation (AspAlliance)

November 07, 2006

Cookies and FormsAuthentication

Cookies

Cookies are simply a file stored in the client machine which are sent up and down to and from the server with every Request and Response.

The Cookie is used to store some client information such as details of their past session. It allows the Client to return to a webpage and have information already available to them without having to start from scratch.
The Cookie is first sent down from the Server and is stored somewhere on the Client's hard-drive.
It's up to the Web Application developer to do the Cookie processing on the Server side. The Cookie can be accessed from the Request as the Cookie is a property of the HttpRequest, Request.Cookie["cookiename"];

One problem I've encountered with Cookies is that all the cookies associated with your application get Posted from the Client on each Request, this adds to the amount of data sent as you can imagine. There is a solution however, in order to ensure a Cookie is only sent from Client to Server when a certain page is open you must create the Cookie with it's path set to that page;
HttpCookie rememberLogin = new HttpCookie("rememberLogin", rememberLogin.Expires = DateTime.Now.AddDays(5);
rememberLogin.Path = Request.Path;
Response.Cookies.Add(rememberLogin);

Codeproject.

Authentication

Who Are You?
There are 2 main types Windows and Forms.

Windows Authentication

This will use the clients credentials i.e. their actual windows login that they are presently using, allowing your server side app to examine who the client actually is.
Note that the client will usually have to pass their credentials onto the Server, this can be done in code adding their credentials, System.Net.CredentialCache.DefaultCredentials, to the HttpRequest with the following:
for a .NET Remoting call:
IDictionary channelProperties = ChannelServices.GetChannelSinkProperties(_remoteObject);
channelProperties["credentials"] = System.Net.CredentialCache.DefaultCredentials;

For all of this to work you muse have "Integrated Windows Authentication" (only) enabled on the Server or a subdirectory within the Server.
If you also have "Anonymous Access" enabled then Windows Authentication will not work, if you must have "Anonymous Access" enabled as well for some reason then follow these 3 steps:
1. Create a subdirectory and set it's Security settings to "Integrated Windows Authentication" e.g. "MyIntegratedDir". This subdirectory will then work as you'd expect and you can use Windows Authentication on this directory.
2. Add an entry to the Web.config to tell IIS Security to permit Anonymous users access to the particular directory.
<location path="MyIntegratedDir">
<system.web>
<authorization>
<allow users="?"/>
</authorization>
</system.web>
</location>
3. Place you Custom Authorization code within this directory i.e. probably in an aspx page

FormsAuthentication
FormsAuthentication is not directly related to Cookies but they can work together.

You can access the FormsAuthentication information from code using the FormsAuthenticationTicket.
By querying this object you can redirect etc to other pages depending on roles etc.
The FormsAuthenticationTicket object can then be passed to the Cookie constructor in order to save the information, this means the Client does not have to provide the information on each page, the Cookie is sent up and down to the Server ensuring the Client has access.
codeproject.


Authorization

In the web.config you can specify what groups or who you wish to allow or deny from your website, you can break your website down into subfolders, this is known as Authorization i.e. What you are allowed to do.

dotNET - Http traffic debugging using Fiddler

So you want to view the Http traffic between client and server. Fiddler's your man.
You can view the traffic on requests including Cookies and Cached data.
For more see msdn and fiddler.com.

November 06, 2006

Setup Programs Installer creation using VS2005

Setup Programs Installer creation using VS2005
Getting Started with Setup Projects (SimpleTalk).
Visual Studio Setup Projects and Custom Actions (Simple Talk).
Updates to Setup Projects (SimpleTalk).

To create an Installer using Visual Studio you must create a Setup Project. A setup project contents are files and outputs of other projects in the solution. The Setup Project template can be found in the Visual Studio New Project dialog under Other Projects->Setup and Deployment->Setup Project.


Tip! To debug installation or just see what's happening in the background and view system variable values use the msiexec logger, it logs everything that's happening on installation, it can also be used for uninstall
install:
msiexec /i yourinstaller.msi /l* yourinstaller.log
or verbose
msiexec /i yourinstaller.msi /l*v yourinstaller.log

uninstall:
msiexec /uninstall yourinstaller.msi /l* yourinstaller.log
or verbose
msiexec /uninstall yourinstaller.msi /l*v yourinstaller.log

Description of how to create a Setup Project
Deploying Windows Applications (Charp Onlline .NET).

You'll see that the Setup Project (note there's also a WebSetup project template) supplies the dialogs etc for user info entry, I don't think there's a way to override this. The dialogs allow limited user input. The user input from the dialogs textfields is available to you through Properties, I'll talk about how to access them now.
Setup Project Property Reference (msdn).
This is all done for you but there are a couple of things to look out for, as always if you wish to do something different it's tricky. For example if you wish to get some information on the Installation you must use a Custom Action.


Updating/Patching the installation
Updates to Setup Projects (SimpleTalk).
It doesn't appear that this is implemented all that well with Visual Studio setup projects, they don't have the power.
The SimpleTalk link gives instructions on the ways to implement update packages but it does mention that patching (just updating certain files) is not implemented, it's a full install/reinstall or nothing, even the repair does this.

Merge Modules
Installing Shared Components using Merge Modules (msdn).
The contents of the Setup Project can be broken up into Merge Modules. The Merge Modules contain Components, the components contain your installer items.
The Merge Modules are a useful tool if you wish to add contents to your installer from other resources such as projects outside of your current solution, if you wish to import outputs from a project in a location outside of your present solution then create a new Merge Module project in the other solution and then add the Merge Module to the current Setup Project.

MSBuild and Setup Projects

Word of warning on Setup Project (.vdproj). MSBuild will not build these type of projects. The result is a warning in MSBuild ... and the contents (the Outputs of other Projects which the Setup uses) are not updated, it could install older versions of files than you had hoped.

One solution would be to Build the Setup project manually after running MSBuild.

Another solution is to tell devenv to explicitly build the Setup project
There are 2 ways to do this:
  1. On the command line, e.g in your build script with
  2. In another project file tell devenv to build the project using devenv


To Force an uninstall try this
MsiExec.exe /I installer.msi REINSTALLMODE=voums REINSTALL=ALL
installer.msi is the name of your installer. The Repair/Remove dialog will appear and you can then Remove.

November 01, 2006

Miscellaneous

New Assignment instead of Virtual/Override
The "new" keyword can be used with methods, it provides a type of inheritance similar to polymorphism.
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
ChildClass cc = new ChildClass();
bc.Foo();
bc.Bar();
Console.WriteLine("=======================");
((BaseClass)cc).Foo();
((BaseClass)cc).Bar();
Console.WriteLine("=======================");
cc.Foo();
cc.Bar();
Console.WriteLine("=======================");
Console.ReadLine();
}
}

class BaseClass
{
public void Foo() { Console.WriteLine("BaseClass.Foo"); }
public virtual void Bar() { Console.WriteLine("BaseClass.Bar"); }
}

class ChildClass : BaseClass
{
new public void Foo()
{
Console.WriteLine("ChildClass.Foo");
base.Foo();
}
public override void Bar()
{
Console.WriteLine("ChildClass.Bar");
base.Bar();
}
}
Output:
BaseClass.Foo
BaseClass.Bar
=======================
BaseClass.Foo
ChildClass.Bar
BaseClass.Bar
=======================
ChildClass.Foo
BaseClass.Foo
ChildClass.Bar
BaseClass.Bar
=======================
In the above the use of new in the method signature indicates that we the ClildClass wishes to override the BaseClass method Foo().
As we can see from the output the call to
((BaseClass)cc).Foo();
results in
BaseClass.Foo
as we would expect. You could use Virual/Override to do the same thing. But note in the above case we use DownCasting, and in this case the Virtual/Override still calls the ChildClass.Foo and the new assignment version does not, this is suprising to me at least as I would have thought the opposite were true.



Calling one Constructor from another with CSharp

This allows us to create an instance with either of these 2 overloads.
Note that if we use the first overload then the second parameter is null, usually a check would be done in the second overload for null and some default applied
public MyClass(string param1) : this(param1, null)
{
}
public MyClass(string param1, string param2)
{
if(param2==null)
param2 = "default";
}
These could also be called vice versa of course
public MyClass(string param1)
{
_param2 = "default";
}
public MyClass(string param1, string param2) : this(param1)
{
_param2 = param2;
}


Request a Web Page from outside a Web Application

using System.Net;
using System.Xml;
using System.IO;

namespace UrlCall
{
class Program
{
static void Main(string[] args)
{

string url = "http://localhost:3703/ServerProject/Cookie/GetCookie.aspx";

HttpWebRequest myWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
myWebRequest.Method = "GET";
// make request for web page
HttpWebResponse myWebResponse = (HttpWebResponse)myWebRequest.GetResponse();
StreamReader myWebSource = new StreamReader(myWebResponse.GetResponseStream());
string myPageSource = myWebSource.ReadToEnd();
myWebResponse.Close();

}
}
}

Reflection, how the metadata works
CodeProject has an explanation of the internals of a .NET assembly.

Training/Certification
dotNetSlackers has a good description of the .NET Certification available.

Tools

.NET Framework Tools (msdn).
CFF Explorer (Tool to investigate the internals of a .NET assembly).

Fix ASP.NET

If you've installed a new version of .NET you'll have to register it, it's required for ASP.NET to use the correct version
aspnet_regiis.exe -i
Depending on where you call this from will determine which .NET gets used with ASP.NET
e.g.
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis -i
Errors that this may fix are
"Some of all identity References could not be translated"
"iis metadata access rights.

GAC (installing assemblies in the GAC)
The GAC is a location on Windows where Assemblies can be stored, the idea is that all applications can access this one assembly. It's also versioned. The GAC contents can be viewed at C:\Windows\Assembly.
To install your assembly in the GAC you can use to methods
The exe from the .NET SDK
C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\gacutil.exe /i
or the Visual Studio SDK
C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\gacutil.exe /i
or programmically using the GacInstall class
try
{
System.EnterpriseServices.Internal.Publish gac = new System.EnterpriseServices.Internal.Publish();
gac.GacInstall(assemblyName);
}
catch (System.Security.SecurityException se)
{

}

Assembly Code Analysis Tool (FxCop)
FXCop is a MS Tool which analyzes you Managed Code by loading your assembly, reading the manifest and analysing the MSIL in the CLR.
FxCop bried description (TechRepublic)
FxCop (msdn)


Download from gotdotnet.com



Http debugging tool

So you want to view the Http traffic between client and server. Fiddler's your man.
You can view the traffic on requests including Cookies and Cached data.
For more see msdn and fiddler.com.

Some useful dotNET methods etc

  • Ref and Out
  • Use these keywords to pass a reference to another method so that it the reference itself can be changed. All objects are passed by reference in C#, meaning if you wish another object to change values in another object you simply pass the objects reference (the variable name) to the method as normal.
  • Class Passer
    {
    List messages = new List();
    Receiver r = new Receiver();
    r.Method(messages);
    }
  • Class Reveiver
    {
    void Method(List messages)
    {
    message.add("I'm adding a new item to the Passers member messages, this affects the original");
    }
  • However if you want another method or object to change the instance itself, I mean new-up a new memory location with your original reference then you use Ref.
  • The difference between Ref and Out is that Ref is initialized by the passing object and Out is initialized by the receiving object e.g.
  • Class Passer
    {
    List refMessages = new List();
    Receiver r = new Receiver();
    r.RefMethod(ref refMessages);

List outMessages; //not initialized here in the passing object
r.OutMethod(ref refMessages);
}


    Class Reveiver
    {
    void RefMethod(ref List refmessages)
    {
    refmessage.add("I'm adding a new item to the Passers member messages");
    }
void OutMethod(out List outmessages)
{
List outmessages = new List();
outmessage.add("I'm adding a new item to the Passers member messages");
}

}



  • To determine if it's a web app or a windows app use
    • System.Web.HttpContext.Current;
    • If null it's a windows app.
  • TryParse can now be used to determine if 2 values are equal.
    • It can presently be used for int, double, DateTime ....
    • There are 2 params, the value your comparing to and the out which is the result boolean value which is set.
  • Using statement
    • If you are using an Object which implements the Dispose/Inherits from IDisoposing then you can use Using to ensure the object is GC'd after use.
e.g. instead of StopWatch sw = new StopWatch try
using(StopWatch sw = new StopWatch try)
{....
}//sw is deleted here.


  • Get the name of the current method at runtime, useful for printing:
System.Reflection.MethodBase mb = System.Reflection.MethodBase.GetCurrentMethod();
Get the name of the Current Method
string currentMethod = mn.Name;
Get the Current Class name
string currentClassName = mb.DeclaringType.Name;
Or Get a Method at a particular location in the stack: System.Diagnostics.StackFrame sf = new System.Diagnostics.StackFrame(0, true); //To get the calling method name, use 1 instead of 0.
string currentMethodName = System.Reflection.MethodBase mb = sf.GetMethod();
string methodName = mb != null ? mb.Name : "nothing found";
  • Creating Disposable Objects
  • Visual Studio Project Macros/Variable/Properties
  • Here's a useful static method for dumping messages (debugging) to a file:

  • public class DebugWriter
    {
    public static void WriteDebugToFile(string message)
    {
    string path = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, "DebugFile.txt"));
    StreamWriter sw = null;
    if (!File.Exists(path))
    {
    using (sw = File.CreateText(Path.GetFullPath(Path.Combine (Environment.CurrentDirectory, "DebugFile.txt"))))
    {
    }
    }
    using (sw = File.AppendText(path))
    {
    sw.WriteLine(message);
    sw.Close();
    }
    }
    }