简体   繁体   English

xbuild使用(.html)资源文件失败

[英]xbuild failing with (.html) resource files

I'm having a problem getting xbuild to compile a web application project. 我在使用xbuild编译Web应用程序项目时遇到问题。 We have some resource files, which are .html files. 我们有一些资源文件,它们是.html文件。

The one that's failing currently is 'KwasantCore\\Resources\\HTMLEventInvitation.html' 目前失败的是'KwasantCore\\Resources\\HTMLEventInvitation.html'

The resource is defined in KwasantCore.csproj as 资源在KwasantCore.csproj中定义为

<Content Include="Resources\HTMLEventInvitation.html" />

When building on ubuntu, the file is located here: 在ubuntu上构建时,文件位于:

/home/gitlab_ci_runner/gitlab-ci-runner/tmp/builds/project-1/KwasantCore/Resources/HTMLEventInvitation.html

When running xbuild, I get this error: 运行xbuild时,我收到此错误:

/home/gitlab_ci_runner/gitlab-ci-runner/tmp/builds/project-1/Kwasant.sln (default targets) ->
(Build target) ->
/home/gitlab_ci_runner/gitlab-ci-runner/tmp/builds/project-1/KwasantCore/KwasantCore.csproj (default targets) ->
/usr/lib/mono/xbuild/12.0/bin/Microsoft.Common.targets (GenerateResources target) ->

    /usr/lib/mono/xbuild/12.0/bin/Microsoft.Common.targets: error : Tool exited with code: 1. Output: Error: Invalid ResX input.
Position: Line 123, Column 5.
Inner exception: Could not find a part of the path "/home/gitlab_ci_runner/gitlab-ci-runner/tmp/builds/project-1/KwasantCore/resources/htmleventinvitation.html".

I checked the file, and it's there - the problem is case sensitivity. 我检查了文件,它就在那里 - 问题是区分大小写。 The resource is correctly referenced in the .csproj, so somewhere along the line, the resource is getting lowercased from 'Resources/HTMLEventInvitation.html' to 'resources/htmleventinvitation.html' 资源在.csproj中被正确引用,因此在该行的某处,资源从'Resources/HTMLEventInvitation.html'变为'resources/htmleventinvitation.html'

I've taken a look at the Microsoft.Common.targets file on the ubuntu box. 我看了一下ubuntu盒子上的Microsoft.Common.targets文件。 Line 125 is something completely unrelated (it shows me </PropertyGroup> ). 第125行是完全不相关的东西(它显示我</PropertyGroup> )。 Looking at the GenerateResources target, it shows me this: 查看GenerateResources目标,它向我显示:

<Target Name = "GenerateResources">
        <GenerateResource
            Sources = "@(ResxWithNoCulture)"
            UseSourcePath = "true"
            OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
            Condition = "'@(ResxWithNoCulture)' != '' ">

            <Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithNoCulture"/>
            <Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
        </GenerateResource>

        <GenerateResource
            Sources = "@(ResxWithCulture)"
            UseSourcePath = "true"
            OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
            Condition = "'@(ResxWithCulture)' != '' ">

            <Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithCulture"/>
            <Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
        </GenerateResource>
    </Target>

with the referenced targets being: 引用的目标是:

<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' == '.resx'">
    <Output TaskParameter="Include" ItemName="ResxWithNoCulture"/>
</CreateItem>

<CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' != '.resx'">
    <Output TaskParameter="Include" ItemName="NonResxWithNoCulture"/>
</CreateItem>

<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' == '.resx'">
    <Output TaskParameter="Include" ItemName="ResxWithCulture"/>
</CreateItem>

<CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' != '.resx'">
    <Output TaskParameter="Include" ItemName="NonResxWithCulture"/>
</CreateItem>

Now, this looks suspicious to me, but I can't figure out what these Include="@(ResourcesWithNoCulture)" lines are doing - a search for them elsewhere doesn't give me any hints. 现在,这看起来很可疑,但我无法弄清楚这些Include="@(ResourcesWithNoCulture)"行正在做什么 - 在别处搜索它们并没有给我任何提示。 The fact that it's a .html file (and not .resx), makes me suspicious of the GenerateTargets target, as it's only calling the resx versions of the targets. 事实上它是.html文件(而不是.resx),让我怀疑GenerateTargets目标,因为它只调用目标的resx版本。

I'm not an expert on .targets files - can anyone give me a hand? 我不是.targets文件的专家 - 有人能帮我一把吗? I've googled around, but found no help. 我用Google搜索过,但没有找到任何帮助。 I would assume that it would be a fairly common bug, as resources aren't extremely rare (but perhaps without .resx they are). 我认为这将是一个相当常见的错误,因为资源并不是非常罕见(但可能没有.resx)。

Edit: Having looked at it again, the error related to 'GenerateResources' doesn't exactly make sense: it should be failing at 'CopyNonResxEmbeddedResources', as the resources are not .resx. 编辑:再次查看它,与'GenerateResources'相关的错误并不完全有意义:它应该在'CopyNonResxEmbeddedResources'失败,因为资源不是.resx。 They GenerateResources target shouldn't be touching the .html files - as it's only looking at 'ResxWithNoCulture' and 'ResxWithCulture' 他们的GenerateResources目标不应该触及.html文件 - 因为它只关注'ResxWithNoCulture'和'ResxWithCulture'

<Target Name = "CopyNonResxEmbeddedResources"
        Condition = "'@(NonResxWithCulture)' != '' or '@(NonResxWithNoCulture)' != '' or '@(ManifestNonResxWithCulture)' != '' or '@(ManifestNonResxWithNoCulture)' != ''">

        <MakeDir Directories="$(IntermediateOutputPath)%(ManifestNonResxWithCulture.Culture)"/>
        <Copy SourceFiles = "@(NonResxWithCulture)"
            DestinationFiles = "@(ManifestNonResxWithCulture->'$(IntermediateOutputPath)%(Identity)')"
            SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
            <Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithCultureOnDisk"/>
            <Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
        </Copy>

        <Copy SourceFiles = "@(NonResxWithNoCulture)"
            DestinationFiles = "@(ManifestNonResxWithNoCulture->'$(IntermediateOutputPath)%(Identity)')"
            SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
            <Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithNoCultureOnDisk"/>
            <Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
        </Copy>
    </Target>

The target 'CopyNonResxEmbeddedResources' is called directly before 'GenerateResources' 在'GenerateResources'之前直接调用目标'CopyNonResxEmbeddedResources'

I don't know why this happens (my brain just can't hold any more build systems' configuration nuances), but one of the tricks I've picked up along the way is: 我不知道为什么会发生这种情况(我的大脑不能再容纳任何构建系统的配置细微差别),但我沿途拾取的一个技巧是:

MONO_IOMAP=case xbuild ...

That environment variable tells Mono to be case-insensitive when searching for files. 该环境变量告诉Mono在搜索文件时不区分大小写。 The Mono documentation uses this for solving case sensitivity porting across Windows <-> Mac <-> Linux filesystems, but the MONO_IOMAP facility provides several other filesystem and I/O mapping operations. Mono文档使用它来解决跨Windows < - > Mac < - > Linux文件系统的区分大小写的移植,但MONO_IOMAP工具提供了其他几个文件系统和I / O映射操作。

In the event that doesn't work, you could try ciopfs , which is a Linux user-space case-insensitive filesystem. 如果不起作用,您可以尝试ciopfs ,这是一个Linux用户空间不区分大小写的文件系统。 I've never used it, though. 但我从来没有用过它。

I can't tell you WHY it's doing that, but my solution would be to change the name of the resource to match what it's looking for. 我不能告诉你为什么这样做,但我的解决方案是改变资源的名称以匹配它正在寻找的东西。

It DOES look like it's trying to process something as Resx... 它看起来像是在尝试处理Resx ...

 Tool exited with code: 1. Output: Error: Invalid ResX input.

Maybe check your settings? 也许检查你的设置?

The compiler is trying to interpret this as a resource file rather than a resource. 编译器试图将其解释为资源文件而不是资源。 A resource file is a .txt or .resx file which is used to specify resources (eg strings, images) in a specific format, rather than a resource itself. 资源文件是.txt或.resx文件,用于指定特定格式的资源(例如字符串,图像),而不是资源本身。

The GenerateResource task shouldn't be run on resources at all, because its purpose is to convert .txt or .resx files into .resource files to be embedded into an assembly. GenerateResource任务根本不应该在资源上运行,因为它的目的是将.txt或.resx文件转换为.resource文件以嵌入到程序集中。

If there are no actual resource files (.txt or .resx), then you should remove that task from the project's build altogether. 如果没有实际的资源文件(.txt或.resx),那么您应该完全从项目的构建中删除该任务。 Otherwise you just need to make sure that only the correct files are passed to it. 否则,您只需要确保只传递正确的文件。 I can't tell you exactly how to do this without being able to see more of your configuration, but this is a common configuration task, so you should be able to find guidance on Google. 我无法确切地告诉您如何在不能看到更多配置的情况下完成此操作,但这是一项常见的配置任务,因此您应该能够在Google上找到指导。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM