3

我在让 xbuild 编译 Web 应用程序项目时遇到问题。我们有一些资源文件,它们是 .html 文件。

目前失败的是'KwasantCore\Resources\HTMLEventInvitation.html'

该资源在 KwasantCore.csproj 中定义为

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

在 ubuntu 上构建时,文件位于此处:

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

运行 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".

我检查了文件,它就在那里——问题是区分大小写。资源在 .csproj 中被正确引用,因此在某处,资源从'Resources/HTMLEventInvitation.html'到小写'resources/htmleventinvitation.html'

我查看了 ubuntu 盒子上的 Microsoft.Common.targets 文件。第 125 行是完全不相关的(它显示了我</PropertyGroup>)。查看 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>

引用的目标是:

<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>

现在,这对我来说看起来很可疑,但我无法弄清楚这些Include="@(ResourcesWithNoCulture)"行在做什么——在别处搜索它们并没有给我任何提示。它是一个 .html 文件(而不是 .resx)这一事实让我怀疑 GenerateTargets 目标,因为它只调用目标的 resx 版本。

我不是 .targets 文件方面的专家 - 谁能帮帮我?我用谷歌搜索,但没有找到任何帮助。我认为这将是一个相当常见的错误,因为资源并不是非常稀有(但也许没有 .resx 它们是)。

编辑:再次查看后,与“GenerateResources”相关的错误并不完全有意义:它应该在“CopyNonResxEmbeddedResources”失败,因为资源不是.resx。他们 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>

在“GenerateResources”之前直接调用目标“CopyNonResxEmbeddedResources”

4

3 回答 3

3

我不知道为什么会发生这种情况(我的大脑无法容纳更多构建系统的配置细微差别),但我在此过程中学到的技巧之一是:

MONO_IOMAP=case xbuild ...

该环境变量告诉 Mono 在搜索文件时不区分大小写。Mono 文档使用它来解决跨 Windows <-> Mac <-> Linux 文件系统的区分大小写的移植,但该MONO_IOMAP工具提供了几个其他文件系统和 I/O 映射操作。

如果不起作用,您可以尝试ciopfs,这是一个 Linux 用户空间不区分大小写的文件系统。不过我从来没用过。

于 2014-10-22T13:38:16.200 回答
0

我不能告诉你为什么这样做,但我的解决方案是更改资源的名称以匹配它正在寻找的内容。

看起来它确实正在尝试将某些东西处理为 Resx ......

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

也许检查你的设置?

于 2014-08-15T13:23:12.727 回答
0

编译器试图将其解释为资源文件而不是资源。资源文件是一个 .txt 或 .resx 文件,用于指定特定格式的资源(例如字符串、图像),而不是资源本身。

GenerateResource任务根本不应该在资源上运行,因为它的目的是将 .txt 或 .resx 文件转换为 .resource 文件以嵌入到程序集中。

如果没有实际的资源文件(.txt 或 .resx),那么您应该从项目的构建中完全删除该任务。否则,您只需要确保仅将正确的文件传递给它。如果无法查看更多配置,我无法确切告诉您如何执行此操作,但这是一项常见的配置任务,因此您应该能够在 Google 上找到指导。

于 2014-08-15T14:13:48.717 回答