ClickOnce - 文件已经存在错误 - 为什么DLL文件试图被ClickOnce复制两次?

Chr*_*l52 19 .net clickonce manifest

ClickOnce是否仅查看应用程序清单文件以确定要复制到客户端计算机的dll文件,还是查询程序集的内部以确定依赖项文件?

我问的原因是因为我在尝试启动已使用ClickOnce发布的WPF .NET 4应用程序时遇到以下ClickOnce错误:该文件C:\Users\CNelson\AppData\Local\Temp\Deployment\PGX6P33A.35N\AJQL8AC8.D60\tx16_rtf.dll已存在.

在我引用了两个引用非托管dll文件(tx16_rtf.dll)的第三方.NET dll之后,就开始出现此错误.我希望将tx16_rtf.dll复制到客户端PC上的bin文件夹中,以便将其包含在我的项目中,并将Build Action设置为'Content',将Copy to Output Directory设置为'Always Always'.

但是,出于某种原因,当我尝试启动应用程序时,ClickOnce尝试将文件'tx16_rtf.dll'复制两次,这会导致错误.

如果我查看部署清单文件,我可以清楚地看到文件'tx16_rtf.dll'的一个且只有一个条目.所以,我的问题是,为什么ClickOnce尝试复制文件'tx16_rtf.dll'两次,如果它只在部署清单文件中存在一次?

下面是引用'tx16_rtf.dll'的部署清单文件的片段:

  <file name="tx16_rtf.dll" size="839680">
    <hash>
      <dsig:Transforms>
        <dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity" />
      </dsig:Transforms>
      <dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
      <dsig:DigestValue>V6i2QcARl3+1SJHCugoazb9zrOY=</dsig:DigestValue>
    </hash>
  </file>
Run Code Online (Sandbox Code Playgroud)

Rob*_*Net 11

在Visual Studio解决方案中,如何添加文件?请尝试以下方法.

将dll添加到项目中.

如果您在引用中引用了dll,请在dll上设置属性,如下所示:Build Action = none,Copy to output directory ="do not copy".然后删除引用,然后重新添加引用,但指向本地项目文件夹中的该DLL.在REFER上,将"copy local"设置为true.

如果您没有dll的Reference,请在dll上设置属性,如下所示:Build Action ="copy".复制到输出目录="始终复制".

如果您有引用,则希望包含它的原因基于引用,而不是基于dll属性.如果您没有引用,则需要将dll专门设置为包含在内.

同时检查"应用程序文件"对话框,确保dll未标记为"包含(先决条件)",但包括"包含"或"包括"(必需).

  • 很抱歉很晚才加入派对,但为了搜索者的利益,我遇到了类似Automapper.Net4.dll的问题.问题是我引用了'Automapper.Net4.dll'和'Automapper.dll'(我后来发现它引用了Net4.dll本身).遵循上面的建议.删除了参考ClickOnce Complained about,删除了bin文件夹并重新构建了项目.Net 4 dll神奇地重新出现,因此不需要直接参考.之后没有ClickOnce的probs. (13认同)

Jam*_*ter 9

您没有提到是否使用精彩(咳嗽)MAGE.EXE来生成部署清单.但是我遇到了相同的'文件x已存在'错误,它是由托管程序集引起的,它通过P/Invoke调用本机程序集中的函数.

对于在由-FromDirectory参数MAGE.EXE指定的位置中的每个管理器组件,MAGE将创建一个<dependency><dependentAssembly>...</dependentAssembly></dependency>组元素(包括组件的代码库,身份,尺寸,散列等).对于每个其他文件(包括非托管本机程序集),MAGE.EXE将创建一个<file>...</file>元素.

但是,在安装时,ClickOnce似乎实际上检查了每个托管程序集的清单元数据.因此,如果您的应用程序具有ManagedAssemblyA,其中P/Invoked NativeAssemblyB中的代码(或者tx16_rtf.dll在您的情况下),您将通过ILDASM 看到ManagedAssemblyA的清单具有.module extern NativeAssemblyB.dll语句.

我只能假设的ClickOnce,而处理<dependentAssembly codebase="ManagedAssemblyA.dll">元件,检查装配的元数据,看到有引用的本机汇编,看到它也是在同一部署位置,并将其复制下来.然后,当稍后处理该<file name="NativeAssemblyB.dll">元素时,它会因为已经复制了该文件而导致错误,并且假定无法安装是最安全的操作过程.我没有在任何地方发现Microsoft记录此行为.

因此,解决方案是在使用MAGE.EXE生成部署清单之后,但在签署之前,删除<file>任何本机程序集的元素.仍需要在与ClickOnce应用程序所需的其他程序集相同的部署位置中提供本机程序集.

在我们的例子中,我们自动化了这一点,因为我们还使用每个持续集成构建自动生成部署清单(而不是使用Visual Studio 2010中的发布向导,它可以提供更多控制); 我们有一个Powershell脚本,它调用MAGE.EXE来创建部署清单,更多的Powershell来操作XML并删除<file>元素(使用Powershell非常容易......运气好,使用批处理文件!)然后我们调用MAGE .EXE签署清单.