65.9K
CodeProject 正在变化。 阅读更多。
Home

Code Store - VS.NET 插件

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.33/5 (21投票s)

2003年6月25日

CPOL

14分钟阅读

viewsIcon

208906

downloadIcon

2645

一个Visual Studio .NET插件,用于提供对.NET组件在线存储库的即时集成访问。

Code Store Screenshot

引言

在我开发应用程序时,我总是觉得使用别人已经编写好的控件或库比自己动手更容易。这就是为什么我和你们中的许多人一样,来到Code Project——因为它是一个现成组件的绝佳资源。然而,当您来到这里时,您必须仔细查找,下载源代码和演示项目,构建它们以确保它们正常工作,然后将它们复制到有用之处,然后将它们添加到您的项目中,然后您才能开始使用它。

这就是Code Store的用武之地。Code Store是一个插件,为您提供对.NET组件在线存储库的即时集成访问。所有组件都已构建好并可供使用;Code Store所做的就是下载您请求的组件,然后自动将其添加到工具箱中,供您在项目中使用。

历史

  • 版本 1.0 (2003年6月25日): 初始发布。
  • 版本 1.1 (2003年6月25日): 修复了一些关于启动的错误。
  • 更新 (2003年6月27日): .NET Framework 1.0 版本。完整的安装程序可在此 获取。
  • 更新 (2003年6月27日): 文章更新了更多关于VS.NET集成和XML文件的信息。
  • 版本 1.2 (2003年6月30日): 添加了 代理服务器支持 (非常感谢Alex Kucherenko的帮助)。
  • 版本 2.0 (2003年7月9日): 对所有内容进行了彻底的重构 (见下文)。
  • 版本 2.0 SP1 (2003年7月11日): 修复了下载路径错误 (感谢Matt Dixon)。
  • 版本 2.0 SP2 (2003年7月11日): 修复了启动异常错误 (感谢Marc Merritt)。完整版本号为 2.0.1287.27032。
  • 版本 2.1 (2003年7月15日): 添加了对非UI组件和自定义卸载操作的支持。
  • 版本 2.1.1298 (2003年7月22日): 添加了对压缩文件和依赖于其他库的组件的支持。还包括对多项目解决方案的支持。完整版本号为 2.1.1298.15694。

公告

2003年9月16日

在重新考虑了我早先的陈述 (见下文) 以及我目前的情况后,我决定我没有足够的财力来支持这样的事业。因此,我将CodeStore作为一项免费且独有的服务提供给CodeProject的所有成员。我目前正在等待Chris Maunder的消息,这导致了开发延迟。开发现已重启,因为我渴望尽快能为#Develop团队提供一些东西。

网站设计已经重构,由Movable Type (后端) 和 Paul Watson (新布局) 提供。RSS Feed已更改为

2003年7月16日

我目前正在考虑辞职并专注于Code Store的开发。我相信它有真正的潜力,特别是当我们达到支持UI和非UI组件以及ASP.NET Web控件的阶段时。为了实现这一点,我需要收取一定的费用。我认为出售软件本身不是好方法,我认为基于订阅的服务允许用户下载组件是更好的方法。我目前考虑的入门级订阅费约为每年10英镑,以允许访问免费组件 (如Code Project上可用的组件)。之后,可以引入更高级别的订阅,提供对Dundas等公司生产的专业组件的访问。

为了保护Code Store,源代码的更新将不再提供下载。版本 2.0 的源代码是 (并将保持) 可下载的。软件的更新和新版本将继续在此处提供。

入门

要开始使用,只需下载其中一个安装程序 (请参阅文章顶部的链接),然后安装Code Store。安装完成后,转到“工具”菜单并选择“Code Store”。这将下载一个列出可用组件的XML文件,然后对其进行解析以显示列表。选择您想要的组件并单击下载。在每个组件下载完成后,它将被添加到工具箱中名为“Code Store”的选项卡中。

如何实现

与我这类规模的大多数作品一样,我从设计开始。我总是从用例图开始,因为它是我从用户角度表示需求的一种清晰有效的方式,而且我总能参考它来检查我是否走在正确的道路上。

图 1 - 显示插件使用的用例图

在将Code Store开发到初始版本并进一步到版本 1.2 以满足竞争截止日期后,是时候从我所做和设计的经验中学习,然后重写所有内容了。这催生了版本 2.0,它分为三个区域:与Visual Studio的交互、文件下载和用户界面。这个结构如图所示的以下包图

图 2 - 显示总体结构的包图

以下一组图展示了插件的每个包

图 3 - Salamander.Addins.CodeStore 命名空间的类图

图 4 - Salamander.Addins.CodeStore.Engine 命名空间的类图

图 5 - Salamander.Addins.CodeStore.UserInterface 命名空间的类图

该插件包含一个命令,执行时首先从服务器下载组件列表XML文件。该XML文件被解析,然后详细信息被添加到ListView控件并显示给用户,并带有复选框。用户勾选要下载的每个组件的复选框,然后依次下载每个组件。进度事件用于显示当前下载进度。

下载完成事件随后用于将控件添加到工具箱中的“Code Store”选项卡 (参见下文“要点”。)

该插件本质上分为两部分:第一部分是与Visual Studio的交互,第二部分执行文件下载。

Visual Studio 交互

插件在OnConnection事件期间进行设置和配置。命令仅在UI设置期间 (connectMode == Extensibility.ext_ConnectMode.ext_cm_UISetup) 添加到菜单,这发生在插件安装后第一次加载时,以便用户可以自定义他们的用户界面,而无需每次加载插件时都重置。此UI设置阶段是根据HKCU\Software\Microsoft\VisualStudio\7.1\PreloadAddinState\键中每个插件的值确定的。如果该值 (例如Salamander.Addins.CodeStore.Connect) 为“1”,则用户界面尚未初始化;如果为“0”,则用户界面已完成初始化。

在将命令添加到“工具”菜单后,插件会检查工具箱中是否存在“Code Store”选项卡;如果不存在,则会创建一个。Code Store下载的所有用户界面组件都将添加到工具箱的“Code Store”选项卡中。即使没有加载解决方案,也会发生这种情况。

ToolBoxTab toolBoxTab = null;
try
{
    Window win = 
     applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindToolbox);
    ToolBox toolBox = (ToolBox)win.Object;
    ToolBoxTabs toolBoxTabs = toolBox.ToolBoxTabs;
    // Look to see if it's already been added.
    for (int i = 1; i < toolBoxTabs.Count; i++)
    {
        if ("Code Store" == toolBoxTabs.Item(i).Name)
        {
            toolBoxTab = toolBoxTabs.Item(i);
            break;
        }
    }
    if (null == toolBoxTab)
    {
        toolBoxTab = toolBoxTabs.Add("Code Store");
    }

与Visual Studio的其余交互在组件下载后发生。文件下载完成后,该组件将被添加到工具箱的“CodeStore”选项卡中。这是通过以下方式完成的:

    this.toolBoxTab.ToolBoxItems.Add(comp.Name, strPath, 
        EnvDTE.vsToolBoxItemFormat.vsToolBoxItemFormatDotNETComponent);
  • comp.Name是组件的名称,由XML文件中的Name项定义,这是在工具箱中显示的标签;
  • strPath是下载文件的路径,使用XML文件中的FileName项;
  • 最后一个参数决定了要添加到工具箱的内容,在这种情况下,是一个.NET组件。根据文档,这将“将库中的所有类”添加到工具箱。

对于非用户界面组件 (自 2.1 版本起支持),如果当前已加载解决方案,则会将程序集引用添加到解决方案的第一个项目中。

文件下载

下载文件的过程非常简单,在单独的线程中逐一下载,以保持用户界面的响应性。下载类最初是 Ray Hayes 的 WebDownload 类。尽管这些类已从头开始重写,但它们仍然相当相似。Ray 的文章描述了下载过程,所以我在这里没有重复。包含WebDownload类的Salamander.Net命名空间的类图如下所示:

图 6 - Salamander.Net 命名空间的类图

XML文件

一个非常简单的XML文件用于传输组件信息。它只是存储在CodeStore服务器上,并且在每次显示组件列表时由插件下载。我最初的希望是MySQL (当前的组件数据库) 能够以格式良好的XML导出表内容。不幸的是,它错误地关闭了每个标签 (不包含“/”),并且没有为每一行提供容器,所以需要一些手动编辑。我希望将来后端能够被移植为某种运行在SQL Server上的Web服务,这样XML导出问题就能得到解决。

文件本身只包含一个“codestore”元素,然后为每个组件包含一个“component”元素。Component元素包含以下项:

  • ID - 数据库文件标识符。将来可能会在内部用于引用组件;
  • Name - 组件的“友好”名称;
  • FileName - 组件的实际文件名。用于实际将组件加载到工具箱中。
  • Version - 组件的版本号。后端未来的版本可以在上传过程中自动确定此值。此字段也可以在未来版本中用于为用户提供“新版本通知”服务,以便在现有组件的新版本可用时通知他们。
  • Description - 组件及其用途的描述;
  • Author - 组件作者;
  • Email - 组件作者的电子邮件地址。未来的版本将在组件列表中显示为可点击链接,以便用户可以就问题联系作者;
  • DateSubmitted - 组件提交到存储库的日期。网页会自动添加此字段。未来的版本将使用此字段告知用户何时向存储库添加了新组件;
  • MoreInfo - 此字段目前旨在链接到有关组件的文档或更多信息。通常,这将是CodeProject相关页面的链接。

XML文件的一个示例如下:

<?xml version="1.0"?>
  <codestore>
    <component>
      <ID>1</ID>
      <Name>Browse For Folder</Name>
      <FileName>Salamander.Windows.Forms.BrowseForFolder.dll</FileName>
      <Version>1.0.1221.24682</Version>
      <Description>Managed wrapper around the 
           BrowseForFolder function.</Description>
      <Author>Derek Lakin</Author>
      <Email>derek.lakin@salamandersoftware.biz</Email>
      <DateSubmitted>2003-06-24 10:28:50</DateSubmitted>
      <MoreInfo>NULL</MoreInfo>
    </component>
    <component>
      <ID>2</ID>
      <Name>Collapsible Panel Bar</Name>
      <FileName>CollapsiblePanelBar.dll</FileName>
      <Version>1.4.1059.25679</Version>
      <Description>Panel and panel bar class that 
         imitate Windows XP collapsible panels.</Description>
      <Author>Derek Lakin</Author>
      <Email>derek.lakin@salamandersoftware.biz</Email>
      <DateSubmitted>2003-06-24 10:28:50</DateSubmitted>
      <MoreInfo>http://www.salamandersoftware.biz/
            products/collapsiblepanelbar.htm</MoreInfo>
    </component>
  </codestore>

代理服务器支持

自版本 1.2 起,已添加了代理服务器支持 (得益于Alex Kucherenko的帮助和支持)。自版本 2.0 起,可以在“选项”部分编辑代理服务器设置。

代理设置在Engine类中的ApplySettings方法中应用。

/// <SUMMARY>
/// Apply the current add-in options.
/// </SUMMARY>
internal void ApplyOptions()
{
    WebProxy proxy = GlobalProxySelection.GetEmptyWebProxy() as WebProxy; 

    try { proxy = WebProxy.GetDefaultProxy(); } // only IE 5.5 and higher
    catch (System.Exception exc)
    {
      System.Diagnostics.Trace.WriteLine(exc.Message, "Engine.ApplyOptions");
    }

    try 
    {
        if (true == this.options.UseProxy) 
        {

            proxy = new WebProxy(this.options.ProxyAddress 
                                + ":" + this.options.ProxyPort,
                this.options.BypassProxyOnLocal); 
            if (true == this.options.ProxyAuthorisation) 
            {
                if (this.options.ProxyUser != null && 
                            this.options.ProxyUser.Length > 0)
                    proxy.Credentials = new NetworkCredential(
                        this.options.ProxyUser, this.options.ProxyPassword);
            }
            else
            {
              proxy.Credentials = 
                System.Net.CredentialCache.DefaultCredentials;
            }
        }
    }
    finally 
    {
        this.webProxy = proxy; 
    }

    this.formCodeStore.userControlOptions.ApplyOptions(ref this.options);
}

网站

除了插件本身,还有一个网站 (http://codestore.salamandersoftware.biz/),它还允许您浏览可用组件,并允许组件开发者将有关其组件的信息添加到数据库中。出于几个原因,没有实时组件上传功能。主要原因是时间和我无法使其正常工作 :/. 但另一个原因是安全。我想在组件可供使用之前进行检查,以防止恶意代码进入他人的系统。

该网站托管了一个MySQL数据库,用于显示网站上的组件列表,并生成插件下载的XML文件。但主要是该网站的目的是托管实际的组件本身。

限制

版本 1.2 可用于 .NET 1.1 和 1.0,但新的版本 2.0 (及更高版本) 目前仅适用于 .NET 1.1。如果有人能提供关于从 VS.NET 7.1 转换为 7.0 的有用见解,特别是关于部署项目和 resx 文件,我希望能听到您的意见。

目前,仅支持独立的UI和非UI组件,即不依赖于附加库 (除了标准的.NET Framework库) 的组件。将来,将添加对压缩存档和依赖文件以及对ASP.NET Web控件的支持。

其他即将推出的功能将在下面的“未来功能”部分详细介绍。

关注点

有两个已知的与此插件相关的错误,都与将内容添加到工具箱有关。第一个要求在成功将控件添加到工具箱之前打开属性窗口,第二个要求选项卡具有焦点。

尽管在不同的新闻组的多个线程中都有传言和尝试,但这些错误的最佳解决方案如下。首先,您需要调用

applicationObject.ExecuteCommand("View.PropertiesWindow");

然后,在调用ToolBoxItems.Add()之前,您需要调用

myTab.Activate();

号召

此插件有潜力变得非常有用,并为像您和我一样的开发者节省时间。然而,如果只有少数组件可供下载,它就什么也不是。所以,如果您是.NET开发者,并且拥有UI控件、库或其他代码库,那么请 点击此处 注册详细信息,然后将发布版本 DLL 发送至 codestore@salamandersoftware.biz

如果有人认为他们可以为Code Store开发做出贡献,或者可以实现下面列出的任何“未来功能”,那么您可以在 GotDotNet Code Store Workspace 注册并加入。

致谢

非常感谢Paul Watson和Alex Kucherenko在发布前的测试工作,以及Matt Dixon和Marc Merritt在版本 2.0 发布后 bug 修复方面的协助。

也感谢Furty的 Collapsible Splitter 控件。

非常感谢所有为初始组件库贡献作品的作者。

未来功能

当前的开发计划如下。时间表是估计的,如果现实生活™介入,很容易出现延迟。计划包括已确定会加入的功能;也可能添加其他功能,特别是如果足够多的人要求的话。

  • 第一阶段 (完成)

    基本功能初始发布。

    • 版本 1.0 (2003/06/25)

      代理服务器支持和次要 bug 修复。

    • 版本 1.2 (2003/06/20)
  • 第二阶段 (完成)

    重构内部架构以分离功能。新的用户界面 - 在不编辑注册表的情况下编辑选项。

    • 版本 2.0 (2003/07/09)
  • 第三阶段
    • 添加对非UI组件的支持。添加对压缩组件的支持。
    • 添加对多文件组件 (即有依赖项的组件) 的支持。
    • 版本 2.1 (预计 2003/08/01)
    • 添加对 ASP.NET Web 控件的支持。
    • 版本 2.2 (预计 2003/08/15)
    • 提前完成:2003/07/22

  • 第四阶段
    • 添加“我的下载”部分,包含
      • 为 ASP.NET Web 控件添加“添加到项目”功能;
      • 检查更新 - 将 mydownloads.xml 中的版本与 codestore.xml 中的版本进行比较。
    • 版本 3.0 (预计 2003/09/01)

      添加自动更新通知 (拉取而非推送) - 基于选项中的更新间隔。

    • 版本 3.1 (预计 2003/09/08)
  • 第五阶段
    • 添加新的列表控件,支持
    • 下载进度显示;
    • 可排序的列 (通过单击列标题);
    • 可点击链接 (用于“更多信息”链接);
    • 多行项目以显示长文本。
    • 版本 4.0 (预计 2003/09/30)
  • 第六阶段
    • 服务器开发,通过 Web 服务提供服务器端功能。
    • 支持搜索,从而减小组件列表下载量。
    • 支持上传过程
    • 确定组件版本;
    • 从压缩存档中的文件列表中选择要注册的文件;
    • 从组件版本信息中确定作者;
    • 确定组件类型 (UI、非UI、ASP.NET);
    • 检查请求的安全权限。
    • 预计 ??
© . All rights reserved.