【问题标题】:Getting Content Files and Primary Output programmatically以编程方式获取内容文件和主要输出
【发布时间】:2009-05-01 14:46:49
【问题描述】:

出于某种原因,我们有一个脚本可以创建批处理文件,以将我们编译的程序集、配置文件和各种其他文件 XCOPY 到网络共享中,供我们的 beta 测试人员使用。我们确实有安装程序,但有些没有运行安装程序所需的权限,或者它们在 Citrix 上运行。

如果您一提到 XCOPY 和 Citrix,就吐得满桌都是,那就以此为借口早点回家吧。不客气。

代码目前有数百行,如:

CreateScripts(basePath, "Client", outputDir, FileType.EXE | FileType.DLL | FileType.XML | FileType.CONFIG);

过去更糟糕,有 20 个 int 参数(每种文件类型一个)表示是否将该文件类型复制到输出目录。

这数百行创建了具有数千行 XCOPY 行的上传/下载批处理文件。在我们的设置项目中,我们可以引用诸如“来自客户端的主要输出”和“来自客户端的内容文件”之类的内容。我希望能够通过非设置项目以编程方式执行此操作,但我不知所措。

显然,MS 使用 API 或通过解析 .csproj 文件来做到这一点。我该怎么做呢?我只是在寻找一种方法来获取任何设置类别的文件列表,即:

  • 主要输出
  • 本地化资源
  • 内容文件
  • 文档文件

编辑: 我有一个像哈斯建议的设置项目,它是我正在寻找的一半。唯一无法成为完美解决方案的问题是多个项目依赖于位于各自文件夹中的相同程序集,并且设置只会复制文件一次。

例子:

项目 Admin、Client 和 Server 都依赖 ExceptionHandler.dll,Admin 和 Client 都依赖 Util.dll,而 Server 不依赖。这就是我要找的:

  • 管理员
    • Admin.exe
    • Admin.exe.config
    • ExceptionHandler.dll
    • Util.dll
  • 客户端
    • Client.exe
    • Client.exe.config
    • ExceptionHandler.dll
    • Util.dll
  • 服务器
    • Server.exe
    • Server.exe.config
    • ExceptionHandler.dll

由于引用的程序集都是一样的,我得到的是这样的:

  • 管理员
    • Admin.exe
    • Admin.exe.config
    • ExceptionHandler.dll
    • Util.dll
  • 客户端
    • Client.exe
    • Client.exe.config
  • 服务器
    • Server.exe
    • Server.exe.config

当客户端或服务器找不到它所期望的两个 DLL 之一时,这会导致 FileNotFoundException。

我是否缺少一个设置属性以使其始终复制输出,即使它在另一个项目的输出中的其他地方重复?

再次编辑:所有引用的 DLL 都设置为“复制本地”,并且一直如此。我在using NAnt and XSLT to grab the list of files 上找到了一篇不错的文章,因此这可能也是一个可能的解决方案,正如 neouser99 所建议的那样。

接受的解决方案:我几乎回到了我开始的地方。所有 .exe 和 .dll 输出都放在安装项目中的“bin”目录中,松散地打包。其他每个应用程序文件夹包含该目录中可执行文件的快捷方式。

现在不同的是,我将向安装程序添加一个自定义操作以使用反射,枚举每个可执行输出的依赖项,并将 .exe 和 .dll 文件复制到单独的目录中。有点痛苦,因为我只是假设有一种方法可以通过一些设置库以编程方式检测将包含哪些文件。

【问题讨论】:

    标签: c# installation setup-project


    【解决方案1】:

    为什么不使用另一个安装项目,只需将“包文件”设置为松散未压缩文件(安装项目->属性)?然后共享文件夹..或其他东西。

    编辑:

    我明白了,您的输出有 3 个文件夹。但是安装项目只检测到 ExceptionHandler.dll 和 Util.dll 一次,所以它只会选择第一个文件夹并把它放在那里。

    你可以为每个项目做一个设置项目——也许有点烦人..

    您可以手动将 dll 添加到缺少程序集的项目中 如果您在同一解决方案中有这些项目,则可以通过“添加文件”或“添加程序集”或“添加项目输出”添加文件。(我怀疑是这种情况)。

    或者只是将它们全部转储到一个输出目录中......

    【讨论】:

    • 它部分工作。我已经用我现在遇到的问题更新了问题。
    【解决方案2】:

    虽然它被设计为构建工具,但您可能会发现 NAnt 在您所谈论的内容中非常有用。您可以定义的任务(构建、复制、移动、删除等)允许非常细粒度的文件查找,直至一般的完整文件夹。如果您还将 NAnt 纳入您的构建过程中,我认为您会发现它在更多方面有所帮助。

    【讨论】:

    • 您是否有任何关于如何获取内容文件或项目输出的参考资料或示例?我找到了一篇关于它的不错的文章,我已将其添加到原始帖子中。
    【解决方案3】:

    过去对我有用的另一种方法是添加共享资源(程序集、DLL 或项目)作为对每个管理、服务器和客户端项目的引用。然后打开每个项目中引用项的属性面板,并将“复制本地”设置为 true。

    现在,当您构建项目时,每个项目都会将自己的程序集实例复制到其输出文件夹中。

    这也会导致以这种方式添加的共享组件被复制到安装包的每个输出文件夹中。

    【讨论】:

    • 所有这些都设置为“复制本地”,这就是我们当前 XCOPY 解决方案的工作方式。不幸的是,安装项目将共享依赖项检测为已经存在,因此它不会将其复制到第二个文件夹。
    【解决方案4】:

    另一种完全不同的方法是将它们设置为网络共享上的符号链接。符号链接基本上是一种捷径,文件系统隐藏了它是捷径的事实,因此所有其他应用程序实际上都认为该文件已被复制(http://en.wikipedia.org/wiki/NTFS_symbolic_link)。

    这种方法的一个优点是文件会在文件更改时立即更新,而不仅仅是在您构建项目时。因此,例如,当您使用文本编辑器保存其中一个配置文件时,会立即应用更新。

    【讨论】:

      【解决方案5】:

      以下 MSBuild 脚本部分可以构建您的 SLN 文件(您可以将其替换为 .csproj),并将报告已构建的所有项目的列表(Dlls、EXE)。

       <MSBuild Projects="MySolution.sln" Targets="Clean; Rebuild" Properties="Configuration=$(BuildMode);">
          <Output TaskParameter="TargetOutputs"
                      ItemName="AssembliesBuilt" />
          </MSBuild>
      

      现在,这并不能真正解决您的问题,但它会为您提供已构建的所有内容的列表。您也有 copylocal,因此您可能只需使用 AssembiesBuild 并从那里复制所有 DLL 和 .CONFIG 文件。

      例子:

      AssembliesBuild = c:\myproj\something1\build.dll

      您将转到 c:\myproj\something1\ 并简单地搜索所有 *.dll 和 *.config 文件并包含它们。如果你安装了 MSBuild 或 powershell,你可以很容易地做到这一点。要从 MSBuild 输出 XCOPY 脚本,我认为您需要安装 MSBuild contrib projct。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-04-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-24
        • 1970-01-01
        • 2011-05-01
        • 2010-12-13
        相关资源
        最近更新 更多