4

出于某种原因,我们有一个脚本可以创建批处理文件,以将我们编译的程序集、配置文件和各种其他文件 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 不依赖。这就是我要找的:

  • 行政
    • 管理员程序
    • 管理员.exe.config
    • 异常处理程序.dll
    • 实用程序.dll
  • 客户
    • 客户端.exe
    • 客户端.exe.config
    • 异常处理程序.dll
    • 实用程序.dll
  • 服务器
    • 服务器.exe
    • 服务器.exe.config
    • 异常处理程序.dll

由于引用的程序集都是相同的,我得到的是:

  • 行政
    • 管理员程序
    • 管理员.exe.config
    • 异常处理程序.dll
    • 实用程序.dll
  • 客户
    • 客户端.exe
    • 客户端.exe.config
  • 服务器
    • 服务器.exe
    • 服务器.exe.config

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

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

再次编辑:所有引用的 DLL 都设置为“复制本地”,并且一直如此。我找到了一篇关于使用 NAnt 和 XSLT 获取文件列表的不错的文章,因此正如 neouser99 建议的那样,这也可能是一个可能的解决方案。

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

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

4

5 回答 5

1

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

编辑:

我明白了,您有 3 个文件夹用于输出。但是安装项目只检测到 ExceptionHandler.dll 和 Util.dll 一次,所以它只会选择第一个文件夹并将其放入其中。

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

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

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

于 2009-05-01T15:04:37.410 回答
1

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

于 2009-05-01T15:34:55.123 回答
1

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

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

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

于 2009-05-05T21:20:58.173 回答
0

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

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

于 2009-05-09T07:49:34.213 回答
0

以下 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。

于 2009-05-10T19:57:33.497 回答