This is how it goes, a stable website using ASP.net 1.1 needed some new modules.
We decided to go with 2.0 for the new modules as a first step towards upgrading ( 1.1 is almost legacy now )
The mosule was written , and was ready to be deployed , when boom the domain went down..
1) You cannot run both 1.1 and 2.0 on the same worker process.
2) Each Application pool gets a separate process
3) You can set an application ( virtual directory ) to use a particular application
pool and ASP.net version..
From the above ,
1) Create a new application pool.
2) Create a new virtual directory to hold the 2.0 sources
3) Set the application pool property to the newly created app pool
4) Set the asp.net version to 2.0
Bingo..
Wednesday, April 23, 2008
VS extensibility and CodeDom
Do you want to create your own VS tool that shows up in the tools list??
VS add-in is the answer.
Create a new Add-in project.
VS does the base work for the add-in.
You have to concentrate on the execute method that is called when the tool is executed.
My goal was to create a tool that when selected will list all the controls on a form,
when a control is selected it lists all the events , when an event is selected
it automatically generates event handling code.
DOnt ask me why , its a long story.
When the tool executes , i show a new form.
I also pass in the applicationObject inorder to access the codedom.
The code generation is handled by my new form.
using System;
using Microsoft.Office.Core;
using Extensibility;
using System.Runtime.InteropServices;
using EnvDTE;
using System.Windows.Forms;
using System.Reflection;
public void Exec(string commandName, EnvDTE.vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if(executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if(commandName == "YourTool.Connect.YourTool")
{
//write code to display the modeless dialog
YourForm _yform = new YourForm(applicationObject);
_yform.Show();
handled = true;
return;
}
}
}
private _DTE applicationObject;
..........
Portions of code from the new form.
Shows how to generate code
The fundamental building blocks of the codedom is codeelemets.
Inorder to get codeelemts , you need to access the codemodel , that can be retreived from the applicationobject ( that we passed to this form )
Once you get a codeelement , you can get get a codeclass out of it for a class.
You can then use addfunction method of the codeclass to add methods to the class.
/********************************************************************
*
* Gets the codeclass corresponding to className
*
* *******************************************************************/
private CodeClass getCodeClass(string className)
{
CodeClass ClassCodeElem = null;
CodeModel myFCM = null;
myFCM = DTE.ActiveDocument.ProjectItem.ContainingProject.CodeModel;//DTE.Solution.Projects.Item(1).CodeModel;
//DTE.ActiveDocument.ProjectItem.ContainingProject.CodeModel;
if ( null == myFCM )
{
Log.LogError("FileCodeModel is Null");
return null;
}
// get the class element.
// This is the preffered way as sugested in MSDN
// Using name might not give the desired result
CodeElements nameSpaceElems = myFCM.CodeElements;
// this gives the namespace element.
// get the class element from that
foreach ( CodeElement nameSpace in nameSpaceElems )
{
// look for the class we need
if ( nameSpace.Kind == vsCMElement.vsCMElementNamespace )
{
listBox1.Items.Add(nameSpace.Name);
CodeElements classE = ((CodeNamespace)nameSpace).Members;
foreach( CodeElement classElem in classE )
{
if ( classElem.Kind == vsCMElement.vsCMElementClass)
{
// determine if this is the class we are looking for
CodeClass classType = (CodeClass)classElem;
if ( classType.Name == className )
{
ClassCodeElem = classType;
break;
}
}
}
}
}
return ClassCodeElem;
}
Example of adding a function
brClass is a codeclass.
fnCons = brClass.AddFunction("YourFunction",vsCMFunction.vsCMFunctionFunction,vsCMTypeRef.vsCMTypeRefVoid, -1,
vsCMAccess.vsCMAccessPrivate, null);
Adding code into the function
EditPoint consRef = fnCons.EndPoint.CreateEditPoint();
// skip two lines
consRef.LineUp(1);
consRef.Insert("\n//Call Generated by tool\n;\n");
VS add-in is the answer.
Create a new Add-in project.
VS does the base work for the add-in.
You have to concentrate on the execute method that is called when the tool is executed.
My goal was to create a tool that when selected will list all the controls on a form,
when a control is selected it lists all the events , when an event is selected
it automatically generates event handling code.
DOnt ask me why , its a long story.
When the tool executes , i show a new form.
I also pass in the applicationObject inorder to access the codedom.
The code generation is handled by my new form.
using System;
using Microsoft.Office.Core;
using Extensibility;
using System.Runtime.InteropServices;
using EnvDTE;
using System.Windows.Forms;
using System.Reflection;
public void Exec(string commandName, EnvDTE.vsCommandExecOption executeOption, ref object varIn, ref object varOut, ref bool handled)
{
handled = false;
if(executeOption == EnvDTE.vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if(commandName == "YourTool.Connect.YourTool")
{
//write code to display the modeless dialog
YourForm _yform = new YourForm(applicationObject);
_yform.Show();
handled = true;
return;
}
}
}
private _DTE applicationObject;
..........
Portions of code from the new form.
Shows how to generate code
The fundamental building blocks of the codedom is codeelemets.
Inorder to get codeelemts , you need to access the codemodel , that can be retreived from the applicationobject ( that we passed to this form )
Once you get a codeelement , you can get get a codeclass out of it for a class.
You can then use addfunction method of the codeclass to add methods to the class.
/********************************************************************
*
* Gets the codeclass corresponding to className
*
* *******************************************************************/
private CodeClass getCodeClass(string className)
{
CodeClass ClassCodeElem = null;
CodeModel myFCM = null;
myFCM = DTE.ActiveDocument.ProjectItem.ContainingProject.CodeModel;//DTE.Solution.Projects.Item(1).CodeModel;
//DTE.ActiveDocument.ProjectItem.ContainingProject.CodeModel;
if ( null == myFCM )
{
Log.LogError("FileCodeModel is Null");
return null;
}
// get the class element.
// This is the preffered way as sugested in MSDN
// Using name might not give the desired result
CodeElements nameSpaceElems = myFCM.CodeElements;
// this gives the namespace element.
// get the class element from that
foreach ( CodeElement nameSpace in nameSpaceElems )
{
// look for the class we need
if ( nameSpace.Kind == vsCMElement.vsCMElementNamespace )
{
listBox1.Items.Add(nameSpace.Name);
CodeElements classE = ((CodeNamespace)nameSpace).Members;
foreach( CodeElement classElem in classE )
{
if ( classElem.Kind == vsCMElement.vsCMElementClass)
{
// determine if this is the class we are looking for
CodeClass classType = (CodeClass)classElem;
if ( classType.Name == className )
{
ClassCodeElem = classType;
break;
}
}
}
}
}
return ClassCodeElem;
}
Example of adding a function
brClass is a codeclass.
fnCons = brClass.AddFunction("YourFunction",vsCMFunction.vsCMFunctionFunction,vsCMTypeRef.vsCMTypeRefVoid, -1,
vsCMAccess.vsCMAccessPrivate, null);
Adding code into the function
EditPoint consRef = fnCons.EndPoint.CreateEditPoint();
// skip two lines
consRef.LineUp(1);
consRef.Insert("\n//Call Generated by tool\n;\n");
Events tab in property grid
have you ever looked at the property grid in VS IDE and wondered how to get the
events tab on?
Well , the good news is that the framework provides an EventTab that can be added to the propertytabs collection of the propertygrid..
Wait... thats not it ...
To be able to see thevents tab , you need to assign the propertygrid's site to your custom site.
Why??
Because propertygrid internally uses the site's getservice to retrieve the eventsbindingservice.
So you need to create your own custom site.
I can hear you say , Alright , but it looks like something more is required...
Yes, you need to provide the EventsBindingService by implementing IEventsBindingService.
Now, how do you connect the eventsbindingservice class to your site?
You have to add the service to the service container.
Below is the code to implement the propertygrid
For further study , u might be interested in propertygridinternal.viewevent code
( i use reflector ).
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Xml;
using System.IO;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
namespace NewPanel {
public partial class PropertyForm : Form
{
MyDesignSurface designSurface;
public PropertyForm()
{
InitializeComponent();
designSurface = new MyDesignSurface();
IServiceContainer serviceContainer = (IServiceContainer)designSurface.GetService(typeof(IServiceContainer));
serviceContainer.AddService(typeof(IEventBindingService), new MyEventBindingService(designSurface));
}
// a new object has been selected
public void SetNewObject(Object obj)
{
IDesignerHost designerHost = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
this.extPropertyGrid.SelectedObject = obj;
if (designerHost != null)
{
extPropertyGrid.Site = (new IDEContainer(designerHost)).CreateSite(extPropertyGrid);
extPropertyGrid.PropertyTabs.AddTabType(typeof(System.Windows.Forms.Design.EventsTab), PropertyTabScope.Document); extPropertyGrid.ShowEvents(true);
}
else
{
extPropertyGrid.Site = null;
}
}
}
#region MyDesignerSurface
class MyDesignSurface : DesignSurface, IServiceProvider
{
#region IServiceProvider Members
object IServiceProvider.GetService(Type serviceType)
{ return this.GetService(serviceType); }
#endregion
}
#endregion
#region Site
class IDEContainer : Container
{
class IDESite : ISite
{
private string name = "";
private IComponent component;
private IDEContainer container;
public IDESite(IComponent sitedComponent, IDEContainer site, string aName) { component = sitedComponent;
container = site;
name = aName;
}
public IComponent Component { get { return component; } }
public IContainer Container { get { return container; } }
public bool DesignMode { get { return false; } }
public string Name { get { return name; } set { name = value; } } public object GetService(Type serviceType) { return container.GetService(serviceType); }
}
public IDEContainer(IServiceProvider sp) { serviceProvider = sp; }
protected override object GetService(Type serviceType)
{
object service = base.GetService(serviceType);
if (service == null)
{
service = serviceProvider.GetService(serviceType);
}
return service;
}
public ISite CreateSite(IComponent component)
{
return CreateSite(component, "UNKNOWN_SITE");
}
protected override ISite CreateSite(IComponent component, string name)
{
return new IDESite(component, this, name);
}
private IServiceProvider serviceProvider;
}
#endregion
#region EventBindingService public class MyEventBindingService : System.ComponentModel.Design.EventBindingService
{
public MyEventBindingService(IServiceProvider myhost) : base(myhost) { }
#region IEventBindingService Members
protected override string CreateUniqueMethodName(IComponent component, EventDescriptor e)
{
throw new Exception("The method or operation is not implemented.");
}
protected override System.Collections.ICollection GetCompatibleMethods(System.ComponentModel.EventDescriptor e)
{
throw new Exception("The method or operation is not implemented.");
}
protected override bool ShowCode(System.ComponentModel.IComponent component, System.ComponentModel.EventDescriptor e, string methodName)
{
throw new Exception("The method or operation is not implemented.");
}
protected override bool ShowCode(int lineNumber)
{
throw new Exception("The method or operation is not implemented.");
}
protected override bool ShowCode()
{
throw new Exception("The method or operation is not implemented.");
}
#endregion
} #endregion
}
events tab on?
Well , the good news is that the framework provides an EventTab that can be added to the propertytabs collection of the propertygrid..
Wait... thats not it ...
To be able to see thevents tab , you need to assign the propertygrid's site to your custom site.
Why??
Because propertygrid internally uses the site's getservice to retrieve the eventsbindingservice.
So you need to create your own custom site.
I can hear you say , Alright , but it looks like something more is required...
Yes, you need to provide the EventsBindingService by implementing IEventsBindingService.
Now, how do you connect the eventsbindingservice class to your site?
You have to add the service to the service container.
Below is the code to implement the propertygrid
For further study , u might be interested in propertygridinternal.viewevent code
( i use reflector ).
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Xml;
using System.IO;
using System.Drawing;
using System.Reflection;
using System.Runtime.InteropServices;
namespace NewPanel {
public partial class PropertyForm : Form
{
MyDesignSurface designSurface;
public PropertyForm()
{
InitializeComponent();
designSurface = new MyDesignSurface();
IServiceContainer serviceContainer = (IServiceContainer)designSurface.GetService(typeof(IServiceContainer));
serviceContainer.AddService(typeof(IEventBindingService), new MyEventBindingService(designSurface));
}
// a new object has been selected
public void SetNewObject(Object obj)
{
IDesignerHost designerHost = (IDesignerHost)designSurface.GetService(typeof(IDesignerHost));
this.extPropertyGrid.SelectedObject = obj;
if (designerHost != null)
{
extPropertyGrid.Site = (new IDEContainer(designerHost)).CreateSite(extPropertyGrid);
extPropertyGrid.PropertyTabs.AddTabType(typeof(System.Windows.Forms.Design.EventsTab), PropertyTabScope.Document); extPropertyGrid.ShowEvents(true);
}
else
{
extPropertyGrid.Site = null;
}
}
}
#region MyDesignerSurface
class MyDesignSurface : DesignSurface, IServiceProvider
{
#region IServiceProvider Members
object IServiceProvider.GetService(Type serviceType)
{ return this.GetService(serviceType); }
#endregion
}
#endregion
#region Site
class IDEContainer : Container
{
class IDESite : ISite
{
private string name = "";
private IComponent component;
private IDEContainer container;
public IDESite(IComponent sitedComponent, IDEContainer site, string aName) { component = sitedComponent;
container = site;
name = aName;
}
public IComponent Component { get { return component; } }
public IContainer Container { get { return container; } }
public bool DesignMode { get { return false; } }
public string Name { get { return name; } set { name = value; } } public object GetService(Type serviceType) { return container.GetService(serviceType); }
}
public IDEContainer(IServiceProvider sp) { serviceProvider = sp; }
protected override object GetService(Type serviceType)
{
object service = base.GetService(serviceType);
if (service == null)
{
service = serviceProvider.GetService(serviceType);
}
return service;
}
public ISite CreateSite(IComponent component)
{
return CreateSite(component, "UNKNOWN_SITE");
}
protected override ISite CreateSite(IComponent component, string name)
{
return new IDESite(component, this, name);
}
private IServiceProvider serviceProvider;
}
#endregion
#region EventBindingService public class MyEventBindingService : System.ComponentModel.Design.EventBindingService
{
public MyEventBindingService(IServiceProvider myhost) : base(myhost) { }
#region IEventBindingService Members
protected override string CreateUniqueMethodName(IComponent component, EventDescriptor e)
{
throw new Exception("The method or operation is not implemented.");
}
protected override System.Collections.ICollection GetCompatibleMethods(System.ComponentModel.EventDescriptor e)
{
throw new Exception("The method or operation is not implemented.");
}
protected override bool ShowCode(System.ComponentModel.IComponent component, System.ComponentModel.EventDescriptor e, string methodName)
{
throw new Exception("The method or operation is not implemented.");
}
protected override bool ShowCode(int lineNumber)
{
throw new Exception("The method or operation is not implemented.");
}
protected override bool ShowCode()
{
throw new Exception("The method or operation is not implemented.");
}
#endregion
} #endregion
}
Subscribe to:
Posts (Atom)