Вы не упоминаете, используете ли вы замечательный ( кашель ) MAGE.EXE для генерации манифеста развертывания. Однако я столкнулся с той же ошибкой «Файл x уже существует», и она вызвана управляемыми сборками, которые вызывают функции в собственных сборках через P / Invoke.
Для каждой управляемой сборки в местоположении, указанном аргументом -FromDirectory в MAGE.EXE, MAGE создаст набор <dependency><dependentAssembly>...</dependentAssembly></dependency>
элементов (включая кодовую базу сборки, идентификатор, размер, хэш и т. Д.). Для каждого другого файла (включая неуправляемые собственные сборки) MAGE.EXE создаст элемент <file>...</file>
.
Однако во время установки, похоже, что ClickOnce фактически проверяет метаданные манифеста каждой управляемой сборки. Поэтому, если в вашем приложении есть ManagedAssemblyA, которая вызывает P / вызывает код в 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, чтобы подписать манифест.