设为首页 收藏本站
查看: 800|回复: 0

[经验分享] Lexware Assembly Reference Tool for Visual Studio 2005 / 2008

[复制链接]

尚未签到

发表于 2016-5-23 00:59:17 | 显示全部楼层 |阅读模式
  http://www.codeproject.com/KB/macros/Lexware_AssemblyReference.aspx
  
  



  • Download setup - 487.69 KB

  • Download source - 74.2 KB
DSC0000.png

Introduction
  Visual Studio 2005 / 2008 both lack a good way to define assembly references per solution configuration (‘Debug’ or ‘Release’).

Background
  There are some ways to define assembly references which change if
the solution configuration changes, but they are not sufficient for
larger projects. The following features of Visual Studio 2005 / 2008
are fine for small projects:


  • Set a Project reference from one project to another. The projects
    must be all in one solution. This is not always possible in projects
    where a lot of developers are working on multiple projects lying in
    different solutions.
  • Set a reference to an assembly lying in the output path of the
    project. Visual Studio 2005 searches for assembly references first in
    the output path of the project. A way to define assembly references per
    solution configuration is to put all assemblies in a common output
    directory (MSDN Article
    ). This is inflexible.
  


The Lexware Assembly Reference Tool fills this gap, by providing a
new tool window in Visual Studio 2005 / 2008, which allows you to
change ‘hard-coded’ assembly reference paths to flexible reference
paths which change depending on the solution configuration. The tool
detects ‘Debug’ or ‘Release’ in the assembly reference path and marks
the assembly in red to show you the potential problem you have, when
you build the project in another configuration. You only need to press
a button and all these paths will be converted to paths which depend on
the configuration of the project.


DSC0001.png



Additionally the tool provides the following features:



  • Change the ‘Copy Local’ property
  • Manipulate the ‘Special Version’ property
  • Edit the assembly reference path (‘HintPath’)
  • Convert a project reference into an assembly references
  • Delete an assembly reference
  

DSC0002.png



After installing and starting the Add-In you can open the assembly reference tool via the Visual Studio 2005 / 2008 tools menu.


DSC0003.png

  

How it works

The general idea behind it
  The tool allows flexible assembly reference paths by replacing
“\Debug\” or “\Release\” in the reference path against
“\$Configuration\”, which is a placeholder for the solution
configuration in Visual Studio 2005 / 2008. Visual Basic and CSharp
projects are able to replace the placeholder back to “\Debug\” or
“\Relase\” when trying to resolve an assembly path.


Since the
Visual Studio 2005 / 2008 object model doesn’t allow any change to a
reference path, the tool changes the path in the underlying project
file. It manipulates the tag , the path to the assembly, which is referenced.
  

DSC0004.png


When the tool saves the project file, Visual Studio notices that change and asks you to reload the project.


For
some features the tool holds a reference to the internal Visual Studio
representation of an assembly reference (VSLangProj80.Reference3),
which allows a manipulation of properties like ‘CopyLocal’,
‘SpecificVersion’ or deleting a reference. Changes to these properties
are directly reflected by the original property window of the assembly
reference in Visual Studio.


The Tool solution itself
  The solution contains a CSharp and a setup project. The setup
project was created with the Setup Project template. The CSharp project
is originally created with a Visual Studio Add-In project template of
Visual Studio 2005.
  

DSC0005.png

  Visual Studio automatically creates a ‘Tool’ menu item for the
add-in, if you choose so in the project wizard. If you select ‘I would
like my Add-In to load, …’ Visual Studio loads your Add-In directly
when it starts.
  

DSC0006.png

  In the new project Visual Studio creates two files with the
extension ‘AddIn’. One is lying in the project folder (e.g.
‘Lexware.Tools.AssemblyReferences.AddIn’) and this is used when the
Add-In is deployed. The other one (e.g.
‘Lexware.Tools.AssemblyReferences - For Testing.AddIn’) is placed in
the Visual Studio Add-In folder. This is the one which is used while
debugging the Add-In. The Visual Studio Add-In folder is contained in
your documents folder. For Windows Vista it should be found here:
C:\Users\’Your User Name’\Documents\Visual Studio 2005\Addins. An
Add-In file contains a full description of the Add-In. It provides a
friendly name, the load behavior and other information, necessary for
Visual Studio to display the Add-In in the ‘Add-in Manager’.
  

DSC0007.png


DSC0008.png


The Add-In
  The Add-In project contains the file ‘connect.cs’, which contains
the code connecting to Visual Studio. The class ‘Connect’ is called,
when the Add-In starts. In fact it is defined in the ‘FullClassName’
tag of the ‘.Addin’ file described below.
  

DSC0009.png


The class Connect
  The class Connect
implements the Visual Studio interface IDTExtensibility2
, which defines the Method OnConnection
.
This method is called, when Visual Studio loads the Add-In into its
memory. This is the place where you can add menu items and in this case
create a tool window.

DSC00010.gif Collapse


public
void
OnConnection(object
application, ext_ConnectMode connectMode,
object
addInInst, ref
Array custom)
{
_applicationObject = (DTE2)application;
_addInInstance = (AddIn)addInInst;
CreateToolWindow();
if
(connectMode == ext_ConnectMode.ext_cm_UISetup)
{
object
[] contextGUIDS = new
object
[] {};
Commands2 commands = (Commands2)_applicationObject.Commands;
string
toolsMenuName;
try
{
//
If you would like to move the command to a different menu, change the
//
word "Tools" to the English version of the menu. This code will take
//
the culture, append on the name of the menu then add the command to
//
that menu. You can find a list of all the top-level menus in the file
//
  CommandBar.resx.
ResourceManager resourceManager = new
ResourceManager(
"
Lexware.Tools.AssemblyReferences.CommandBar"
,
Assembly.GetExecutingAssembly());
CultureInfo cultureInfo = new
CultureInfo(_applicationObject.LocaleID);
string
resourceName = String
.Concat(cultureInfo.TwoLetterISOLanguageName,
LocalResources.ToolbarName);
toolsMenuName = resourceManager.GetString(resourceName);
}
catch
{
//
We tried to find a localized version of the word Tools, but one was
//
not found.
//
  Default to the en-US word, which may work for the current culture.
toolsMenuName = LocalResources.ToolbarName;
}
//
Place the command on the tools menu.
//
Find the MenuBar command bar, which is the top-level command bar holding
//
all the main menu items:
Microsoft.VisualStudio.CommandBars.CommandBar menuBarCommandBar = (
(CommandBars)_applicationObject.CommandBars)["
MenuBar"
];
//
Find the Tools command bar on the MenuBar command bar:
CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
//
This try/catch block can be duplicated if you wish to add multiple commands
//
to be handled by your Add-in,
//
  just make sure you also update the QueryStatus/Exec method to include
//
  the new command names.
try
{
//
Add a command to the Commands collection:
Command command = commands.AddNamedCommand2(_addInInstance,
"
AssemblyReferences"
, "
Assembly Reference Tool"
,
"
Checks and fixes assembly references. Uses placeholder for debug and release directory."
,
true
, 0
, ref
contextGUIDS,
(int
)vsCommandStatus.vsCommandStatusSupported +
(int
)vsCommandStatus.vsCommandStatusEnabled,
(int
)vsCommandStyle.vsCommandStyleText,
vsCommandControlType.vsCommandControlTypeButton);
//
Add a control for the command to the tools menu:
if
((command != null
) && (toolsPopup != null
))
{
command.AddControl(toolsPopup.CommandBar, 1
);
}
}
catch
(ArgumentException)
{
//
If we are here, then the exception is probably because a
//
command with that name
//
  already exists. If so there is no need to recreate the command and we can
//
  safely ignore the exception.
}
}
}

  When the user clicks your menu item, the method Exec
in the same class will be called. You can filter the commandName
, to know whether the called menu item was yours.

Collapse


public
void
Exec(string
commandName, vsCommandExecOption executeOption,
ref
object
varIn, ref
object
varOut, ref
bool
handled)
{
handled = false
;
if
(executeOption == vsCommandExecOption.vsCommandExecOptionDoDefault)
{
if
(commandName == "
Lexware.Tools.AssemblyReferences.Connect.AssemblyReferences"
)
{
//
Open Toolwindow
CreateToolWindow();
handled = true
;
return
;
}
}
}

  The tool window, which contains all the important code in this Add-In, is a UserControl. To create it, you can call CreateToolWindow2
. This method creates a new Visual Studio tool window and hosts a user control in it.

Collapse


private
void
CreateToolWindow()
{
if
(_toolWindow != null
)
{
_toolWindow.Activate();
}
else
{
//
This guid must be unique for each different tool window,
//
but you may use the same guid for the same tool window.
//
This guid can be used for indexing the windows collection,
//
for example: applicationObject.Windows.Item(guidstr)
Windows2 windows2 = (Windows2)_applicationObject.Windows;
Assembly asm = Assembly.GetExecutingAssembly();
object
customControl = null
;
string
className = "
Lexware.Tools.AssemblyReferences.ToolWindowControl"
;
string
caption = "
Assembly References"
;
_toolWindow = windows2.CreateToolWindow2(_addInInstance, asm.Location, className,
caption, _toolWindowGuid,
ref
customControl);
//
Set the picture displayed when the window is tab docked (this causes
//
problems in Visual Studio 2008)
try
{
_toolWindow.SetTabPicture(LocalResources.LexwareBmp.GetHbitmap());
}
catch
{
}
//
When using the hosting control, you must set visible to true before calling
//
HostUserControl, otherwise the UserControl cannot be hosted properly.
_toolWindow.Visible = true
;
if
(customControl != null
)
{
_toolWindowControl = (ToolWindowControl)customControl;
_toolWindowControl.ApplicationObject = _applicationObject;
_toolWindowControl.ParentToolWindow = _toolWindow;
}
}
}

The ToolWindow
  The tool window registers some events of the Visual Studio solution,
document and the command object, so that changes in the solution will
be noticed by the Add-In.

Collapse


private
void
RegisterEvents()
{
if
(_solutionEvents != null
)
{
UnregisterEvents();
}
_solutionEvents = _applicationObject.Events.SolutionEvents;
//
register new events
_solutionEvents.Opened += new
_dispSolutionEvents_OpenedEventHandler(
_solutionEvents_Opened);
_solutionEvents.ProjectAdded += new
_dispSolutionEvents_ProjectAddedEventHandler(
_solutionEvents_ProjectAdded);
_solutionEvents.ProjectRemoved += new
_dispSolutionEvents_ProjectRemovedEventHandler(
_solutionEvents_ProjectRemoved);
_solutionEvents.ProjectRenamed += new
_dispSolutionEvents_ProjectRenamedEventHandler(
_solutionEvents_ProjectRenamed);
_solutionEvents.AfterClosing += new
_dispSolutionEvents_AfterClosingEventHandler(
_solutionEvents_AfterClosing);
_documentEvents.DocumentSaved += new
_dispDocumentEvents_DocumentSavedEventHandler(
_documentEvents_DocumentSaved);
_commandEvents.AfterExecute += new
_dispCommandEvents_AfterExecuteEventHandler(
_commandEvents_AfterExecute);
}

private
void
_commandEvents_AfterExecute(string
Guid, int
ID, object
CustomIn,
object
CustomOut)
{
//
Command name: File.SaveSelectedItems
//
Command GUID/ID: {5EFC7975-14BC-11CF-9B2B-00AA00573819}, 331

//
Command name: File.SaveAll
//
Command GUID/ID: {5EFC7975-14BC-11CF-9B2B-00AA00573819}, 224

//
Command name: File.SaveSelectedItemsAs
//
Command GUID/ID: {5EFC7975-14BC-11CF-9B2B-00AA00573819}, 226

//
Command name: Build.SolutionConfigurations
//
Command GUID/ID: {5EFC7975-14BC-11CF-9B2B-00AA00573819}, 684

//
Command name: Project.Addreference
//
Command GUID/ID: {1496A755-94DE-11D0-8C3F-00C04FC2AAE2}, 1113
if
(((Guid == "
{5EFC7975-14BC-11CF-9B2B-00AA00573819}"
) && (ID == 331
)) ||
((Guid == "
{5EFC7975-14BC-11CF-9B2B-00AA00573819}"
) && (ID == 224
)) ||
((Guid == "
{5EFC7975-14BC-11CF-9B2B-00AA00573819}"
) && (ID == 226
)))
{
ReadAllReferences();
}
else
if
((Guid == "
{1496A755-94DE-11D0-8C3F-00C04FC2AAE2}"
) && (ID == 1113
))
{
ParentToolWindow.Activate();
}
}

  When the solution changes, the Add-In iterates the projects
contained in the solution and reads in the references of each project.
It adds each reference to the list view and puts an instance of the
class AssemblyReferenceInformation
at the tag of the ListViewItem
. This instance contains information about the project file (.csproj or .vbproj) and the assembly reference (VSLangProj80.Reference3
), which will be used when manipulating the reference.

Collapse


private
void
ReadAllReferences()
{
ClearHintLists();
if
((_applicationObject != null
) && (_applicationObject.Solution != null
))
{
//
Walk through the projects of the solution and search for assembly references
foreach
(Project currentProject in
_applicationObject.Solution.Projects)
{
ReadProjectReferences(currentProject);
}
}
}
private
void
ReadProjectReferences(Project currentProject)
{
try
{
if
(currentProject != null
)
{
VSProject2 visualStudioProject = currentProject.Object
as
VSProject2;
//
The current project can be a 'real' project, but it can also be a
//
folder (see else if)
if
(visualStudioProject != null
)
{
string
projectFullName = currentProject.FullName;
if
(!string.IsNullOrEmpty(projectFullName))
{
FileInfo projectFileInfo = new
FileInfo(projectFullName);
//
If it is a csproj or a vbproj, add it the the list view
if
(projectFileInfo.Exists &&
((projectFileInfo.Extension == _csProjectFileExtension) ||
(projectFileInfo.Extension == _vbProjectFileExtension)))
{
//
Add a group for this project
ListViewGroup projectGroup = GetProjectGroup(currentProject);
AddAssemblyHintsToListView(currentProject, projectFullName,
projectGroup, visualStudioProject);
}
}
}
else
if
((currentProject.ProjectItems != null
) && (
currentProject.ProjectItems.Count > 0
))
{
//
Project Item Type       GUID
//
Physical File         {6BB5F8EE-4483-11D3-8BCF-00C04F8EC28C}
//
Physical Folder       {6BB5F8EF-4483-11D3-8BCF-00C04F8EC28C}
//
Virtual Folder        {6BB5F8F0-4483-11D3-8BCF-00C04F8EC28C}
//
Subproject            {EA6618E8-6E24-4528-94BE-6889FE16485C}

//
The projects contains a sub folder -> search for projects in
//
these folders
foreach
(ProjectItem currentProjectItem in
currentProject.ProjectItems)
{
if
(currentProjectItem.SubProject != null
)
{
ReadProjectReferences(currentProjectItem.SubProject);
}
}
}
}
//
Enable fixit button, if there is something to fix
toolStripButtonFixIt.Enabled = (_needsToBeSaved.Count > 0
);
}
catch
(Exception ex)
{
ShowMessage(ex);
}
}

  When the user hits the 'FixIt' button, the tool changes the
underlying project file. It save all projects which needs to be saved,
due to an incorrect assembly path.
  

DSC00011.png


Collapse


private
void
SaveDirtyProjects()
{
try
{
foreach
(KeyValuePair project in
_needsToBeSaved)
{
XmlDocumentHolder documentHolder = project.Value;
SaveProject(documentHolder);
}
}
catch
(Exception ex)
{
ShowMessage(ex);
}
}
private
void
SaveProject(XmlDocumentHolder documentHolder)
{
string
projectName = documentHolder.Project.FullName;
if
(!documentHolder.Project.Saved)
{
MessageBox.Show("
Please save all projects before you fix the problems."
);
return
;
}
//
Check out the project
if
((_sourceControl != null
) && (_sourceControl.IsItemUnderSCC(projectName)) &&
(!_sourceControl.IsItemCheckedOut(projectName)))
{
_sourceControl.CheckOutItem(projectName);
}
using
(XmlTextWriter writer = new
XmlTextWriter(documentHolder.ProjectFileName,
Encoding.UTF8))
{
writer.Formatting = Formatting.Indented;
documentHolder.XmlDocument.Save(writer);
}
}

  Visual Studio notices that the tool changed the project file and asks you to reload the project.
  

DSC00012.png


The setup project
  The setup project deploys the Add-In to the AddIns folders of Visual Studio 2005 and Visual Studio 2008.

It
automatically detects newer and older version, older versions will be
removed before installing a new version. To create a new setup version
for the Add-In, only change the version of the setup. Visual Studio
will generate a new ProductCode for you, but it will not touch the
UpgradeCode. With the combination of codes, Windows Installer is able
to detect and update older or newer versions of the Add-In.
  

DSC00013.png


Requirements to build the solution
  To build the solution, you need Visual Studio 2008. The Add-In is
tested on Visual Studio 2005 and 2008 Team Developer and Team Suite.

History
  no changes

<!--  Main Page Contents End -->


License
  This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




About the Author


Thomas Dörr




Member
Thomas has been programming in C, C++, VB and C# since many years.
He works as a Senior Software Architect for Lexware GmbH & Co.KG in
Freiburg, Germany.
Occupation:
Software Developer (Senior)
Company:
Lexware GmbH & Co.KG
Location:
DSC00014.gif
Germany

  

Other popular Macros and Add-ins articles:



  • Undocumented Visual C++
    Spelunking in the Badlands of MSDEV

  • CodePlotter 1.6 - Add and edit diagrams in your code with this 'Visio-like' tool
    A Visual Studio addin for creating and editing ASCII diagrams in source files

  • Versioning Controlled Build
    A Visual Studio add-in and command-line utility that automates versioning of .NET and VC++ projects

  • Useful enhancements for Visual Studio .NET
    Several tools packed into one addin for Visual Studio .NET

  • WTL Helper
    Add-in for Microsoft VC++.NET 2003 that helps to insert message handlers for WTL.

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-220387-1-1.html 上篇帖子: Visual Basic 2008 中 Linklabel 的使用 下篇帖子: 从2008高考人数想到的软件人才
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表