C# 以编程方式获取内容文件和主输出

C# 以编程方式获取内容文件和主输出,c#,installation,setup-project,C#,Installation,Setup Project,出于某种原因,我们有一个脚本,可以创建批处理文件,将编译的程序集、配置文件和各种其他文件复制到网络共享中,供beta测试人员使用。我们确实有一个安装程序,但有些人没有运行安装程序所需的权限,或者他们正在Citrix上运行 如果你一提到XCOPY和Citrix就吐得满桌都是,那就把它当作早点回家的借口。不客气 该代码目前有数百行,如: CreateScripts(basePath, "Client", outputDir, FileType.EXE | FileType.DLL | FileTyp

出于某种原因,我们有一个脚本,可以创建批处理文件,将编译的程序集、配置文件和各种其他文件复制到网络共享中,供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都被设置为“复制本地”,并且始终被复制。我在上找到了一篇不错的文章,所以正如neouser99所建议的那样,这可能也是一个可行的解决方案

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


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

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

编辑:

我知道了,你有3个文件夹用于输出。但是安装项目只检测一次ExceptionHandler.dll和Util.dll,因此它只会选择第一个文件夹并将其放入其中

你可以为每个项目做一个安装项目-可能有点烦人

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


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

尽管它是作为一个构建工具设计的,但您可能会发现它在您所谈论的内容中非常有用。您可以定义的任务(构建、复制、移动、删除等)允许非常细粒度的文件查找,最多可查找一般的完整文件夹。如果您还将NAnt合并到构建过程中,我想您会发现它在很多方面都比NAnt更有用。

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

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


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

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


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

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


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