Editing a .NET project file from within the WSDL tool
For one of my projects I had the need to customize the proxy classes created by the WSDL tool when performing "Add Web Reference..." within Visual Studio .NET 2005. When the WSDL tool detects a class that it doesn't recognize, it creates a new class definition within the proxy class. In case of having this new class definition, I wanted to use my own class definition.
After googling a while, I bounced on an article from Jelle Druyts who explained exactly what I needed (Article).
The only difference for my particular scenario was the need for a file with the mappings in the project folder. The problem is that when implementing a custom class that extends the SchemaImporterExtension, you don't have immediate access to the calling project.
With a little help from a colleague, Gabriel Lozano-Morán, I succeeded to get a reference to the calling project.
This is the code to retrieve the calling project from within the custom SchemaImporterExtension:
using EnvDTE;
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
public class CallingClass
{
public static void ChangeProjectName(string newName)
{
_DTE ide = DTEHelper.GetCurrentIDE();
Array projs = (Array)ide.ActiveSolutionProjects;
// The proj object allows you to edit the project.
Project proj = (Project)projs.GetValue(0);
proj.Name = newName;
}
}
public static class DTEHelper
{
[DllImport("ole32.dll")]
public static extern uint GetRunningObjectTable(
uint reserved, out IRunningObjectTable ROT);
[DllImport("ole32.dll")]
public static extern uint CreateBindCtx(
uint reserved, out IBindCtx ctx);
public static _DTE GetCurrentIDE()
{
IRunningObjectTable runningObjectTable;
IEnumMoniker iterator;
IMoniker[] monikers = new IMoniker[1];
int currProcId =
System.Diagnostics.Process.GetCurrentProcess().Id;
// Get a pointer to the running object table.
GetRunningObjectTable(0, out runningObjectTable);
// Enumerator to loop through the running objects.
runningObjectTable.EnumRunning(out iterator);
// Reset the enumeration sequence to the beginning.
iterator.Reset();
IntPtr numberFetched = IntPtr.Zero;
while (iterator.Next(1,
monikers,
numberFetched) == 0)
{
IBindCtx ctx;
CreateBindCtx(0, out ctx);
string runningObjectName;
monikers[0].GetDisplayName(
ctx, null, out runningObjectName);
Marshal.ReleaseComObject(ctx);
object runningObjectValue;
runningObjectTable.GetObject(
monikers[0], out runningObjectValue);
// Reference to the IDE if the object is the
// current Visual Studio environment.
if (runningObjectName ==
String.Format("!VisualStudio.DTE.8.0:{0}",
currProcId.ToString()))
return (_DTE)runningObjectValue;
}
return null;
}
}
1 comments:
A couple of days ago I found a better solution playing around with the Marshal type:
http://support.microsoft.com/kb/316126
Dude you use Windows Live Messenger? How come I can't see you?
Post a Comment