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

时间:2009-05-01 14:46:50

标签: c# installation setup-project

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

如果您在XCOPY和Citrix的提及下呕吐在整个桌面上,请以此为借口早日回家。不客气。

代码目前有数百行,如:

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

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

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

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

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

修改: 我有一个像Hath建议的设置项目,它正在我正在寻找的一半。唯一的问题是,保持这是一个完美的解决方案是多个项目依赖于他们自己的文件夹中的相同程序集,并且安装程序将只复制文件一次。

示例:

项目管理员,客户端和服务器都依赖于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都设置为“Copy Local”,并且一直都是。我在using NAnt and XSLT to grab the list of files找到了一篇不错的文章,所以这可能是一个可能的解决方案,正如neouser99所说的那样。

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

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

5 个答案:

答案 0 :(得分:1)

为什么不使用其他设置项目并将“包文件”设置设置为As Loose未压缩文件(setup project-> properties)?然后分享文件夹......或者其他东西。

编辑:

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

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

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

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

答案 1 :(得分:1)

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

答案 2 :(得分:1)

过去对我有用的另一种方法是添加共享资源(程序集,DLL或项目)作为对每个Admin,Server和Client项目的引用。然后打开每个项目中引用项的属性面板,并将“Copy Local”设置为true。

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

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

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

以下MSBuild脚本部分可以构建您的SLN文件(您可以将其替换为.csproj),并将报告所有正在构建的项目(Dll,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。