`
gstarwd
  • 浏览: 1525043 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Lexware Assembly Reference Tool for Visual Studio 2005 / 2008

    博客分类:
  • .NET
阅读更多

http://www.codeproject.com/KB/macros/Lexware_AssemblyReference.aspx

 

 

Sample Image - maximum width is 600 pixels

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.


ToolWindow


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


Context menue


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


VisualStudioMenue

 

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.


Hnit path

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.


New project

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.


Projectwizard

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’.


Addin Manager Menue


Addin Manager

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.


Connect

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.

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.


Convert to configuration based assembly paths

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.


Reload the project

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.


Setupproject

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: Germany Germany

 

Other popular Macros and Add-ins articles:

分享到:
评论

相关推荐

    Lexware:Lexware的数据库访问

    这些类的特殊之处在于您具有对Lexware数据库的完全访问权限(包括写入),并且-与已知的ODBC解决方案相反-不必打开Lexware! 执照 该库受。 NuGet软件包 描述 徽章 基础库 Lexware基本组件 NHibernate组件 全球...

    lexweb:网络上的 Lexware 信息和工具

    网络上的 Lexware 信息和工具 有关 Web 文档和在线工具,请参阅 。 在这个存储库中: ├── lw2xml : Validator and dictionary formatter ├── analysis : Xquery extraction from xhtml ├── pages_md : ...

    cteward-sa-meckerfritze:Mtefritze(Lexware)cteward的脚本操作

    "cteward-sa-meckerfritze"项目似乎是一个针对"Mtefritze"(可能是 Lexware 公司的一个产品)的自动化脚本集,由用户"cteward"创建。"Lexware"是一家知名的德国软件公司,其产品主要面向小型和中型企业,提供财务、...

    elkatoAbrechnung:汽车共享会计程序-开源

    这是在簿记框架内完成的,为此还需要一个簿记程序——一个接口被内置到簿记程序中(例如“Lexware Buchhalter”)。 捐款可以通过会计部门作为俱乐部捐款(非物质领域)或作为参与者费用(需缴纳销售税!)在发票上...

    【优化流量】基于matlab遗传算法GA求解OD流量优化问题【含Matlab源码 9159期】.mp4

    Matlab领域上传的视频均有对应的完整代码,皆可运行,亲测可用,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作

    基于深度学习YOLOv9实现道路红绿灯行人车辆(8类)识别检测系统python源码+详细教程+模型+数据集+评估指标曲线.zip

    【使用教程】 一、环境配置 1、建议下载anaconda和pycharm 在anaconda中配置好环境,然后直接导入到pycharm中,在pycharm中运行项目 anaconda和pycharm安装及环境配置参考网上博客,有很多博主介绍 2、在anacodna中安装requirements.txt中的软件包 命令为:pip install -r requirements.txt 或者改成清华源后再执行以上命令,这样安装要快一些 软件包都安装成功后才算成功 3、安装好软件包后,把anaconda中对应的python导入到pycharm中即可(不难,参考网上博客) 二、环境配置好后,开始训练(也可以训练自己数据集) 1、数据集准备 需要准备yolo格式的目标检测数据集,如果不清楚yolo数据集格式,或者有其他数据训练需求,请看博主yolo格式各种数据集集合链接:https://blog.csdn.net/DeepLearning_/article/details/127276492 更多详情介绍,见资源内的项目说明

    (源码)基于SpringBoot和Vue的学生作业互评系统.zip

    # 基于Spring Boot和Vue的学生作业互评系统 ## 项目简介 本项目是一个基于Spring Boot和Vue框架开发的学生作业互评系统。系统主要功能包括学生作业的提交、教师作业的布置、作业的批改与评分、以及学生之间的作业互评。通过该系统,教师可以方便地管理课程和作业,学生可以在线提交作业并参与互评,从而提高作业质量和学习效果。 ## 项目的主要特性和功能 1. 用户管理 支持学生、教师和管理员三种角色的用户管理。 提供用户注册、登录、密码修改等功能。 2. 课程管理 教师可以创建和管理课程,学生可以选课。 支持课程信息的查看和编辑。 3. 作业管理 教师可以布置作业,设置作业的截止日期和评分标准。 学生可以在线提交作业,查看作业提交状态。 4. 作业批改与评分 教师可以对学生提交的作业进行批改和评分。 学生可以查看自己的作业评分和教师的评语。

    PHP学生成绩查询(源代码+论文).rar

    PHP学生成绩查询(源代码+论文)

    c语言学生信息系统.rar

    c语言学生信息系统

    Android的多媒体框架OpenCore介绍.zip

    Android的多媒体框架OpenCore介绍

    AutocompleteTest.zip

    AutocompleteTest

    2023-04-06-项目笔记 - 第三百一十八阶段 - 4.4.2.316全局变量的作用域-316 -2025.11.15

    2023-04-06-项目笔记-第三百一十八阶段-课前小分享_小分享1.坚持提交gitee 小分享2.作业中提交代码 小分享3.写代码注意代码风格 4.3.1变量的使用 4.4变量的作用域与生命周期 4.4.1局部变量的作用域 4.4.2全局变量的作用域 4.4.2.1全局变量的作用域_1 4.4.2.316局变量的作用域_316- 2024-11-15

    可以识别视频语音自动生成字幕SRT文件的开源 Windows-GUI 软件工具.zip

    可以识别视频语音自动生成字幕SRT文件的开源 Windows-GUI 软件工具

    c语言情人节的红玫瑰.rar

    c语言情人节的红玫瑰

    c语言24点游戏源码.rar

    c语言24点游戏源码

    c语言实现的汉诺塔演示程序.rar

    c语言实现的汉诺塔演示程序

    android_jni操作指南.zip

    android_jni操作指南

    网上绝无仅有的Log分析教程及例子.zip

    网上绝无仅有的Log分析教程及例子

    python编写开源的跳板机(堡垒机)系统Jumpserver-v3.10.7.zip

    Jumpserver 是一款由python编写开源的跳板机(堡垒机)系统,实现了跳板机应有的功能。基于ssh协议来管理,客户端无需安装agent。 Jumpserver 3.0 架构上和 2.0 变化较大,建议全新安装一套环境来体验。如需升级,请务必升级前进行备份。 支持常见系统: 1、redhat centos 2、debian 3、suse ubuntu 4、freebsd 5、其他ssh协议硬件设备 特点: 完全开源,GPL授权 Python编写,容易再次开发 实现了跳板机基本功能,认证、授权、审计 集成了Ansible,批量命令等 支持WebTerminal Bootstrap编写,界面美观 自动收集硬件信息 录像回放 命令搜索 实时监控 批量上传下载

Global site tag (gtag.js) - Google Analytics