8

深くネストされた (長い名前空間) ファイルを含むプロジェクトに取り組んでいます。ほとんどのリソース ファイルのファイル名が長すぎるため、プロジェクトはコンパイルされません。たとえば。

Resource file
"obj\Debug\xxxx.xxxxxxxxxxxxx.xxxx.Services.DeliveryChannels.Web.Common.Resources.xxxxxxxxxxxxxxxxxxx.resources" has an invalid name. The item metadata "%(FullPath)" cannot be applied to the path
"obj\Debug\xxxx.xxxxxxxxxxxxx.xxxx.Services.DeliveryChannels.Web.Common.Resources.xxxxxxxxxxxxxxxxxxx.resources".
D:\Projects\XXXXX\TFS\xxxxx.xxxxx\src\xxxxx.xxxxxxxx.xxxxx\svcs\channels\web\src\xxxxxxx.Web.Common\obj\Debug\xxxx.xxxxxxxxxxxx.xxxxxx.Services.xxxxxxxxxx.Web.Common.Resources.xxxxxxxxxxxxxxxxxx.resources

別のエラー:

File name
'..\..\..\..\..\obj\Debug\xxxx.xxxxxxxxxxxxx.xxxx.Services.DeliveryChannels.Web.Common.Resources.xxxxxxxxxxxxxxxxxxx.resources' is too long or invalid

コンパイラが .resource ファイルの名前を名前空間に変更しないようにするにはどうすればよいですか? コンパイル後にリソース ファイル名を同じにしたいと考えています。

4

1 に答える 1

10

C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.Targets の 2291 行を編集します。

<GenerateResource
    Sources="@(EmbeddedResource)"
    UseSourcePath="$(UseSourcePath)"
    References="@(ReferencePath)"
    AdditionalInputs="$(MSBuildAllProjects)"
    NeverLockTypeAssemblies="$(GenerateResourceNeverLockTypeAssemblies)"
    StateFile="$(IntermediateOutputPath)$(MSBuildProjectFile).GenerateResource.Cache"
    StronglyTypedClassName="%(EmbeddedResource.StronglyTypedClassName)"
    StronglyTypedFileName="%(EmbeddedResource.StronglyTypedFileName)"
    StronglyTypedLanguage="%(EmbeddedResource.StronglyTypedLanguage)"
    StronglyTypedNamespace="%(EmbeddedResource.StronglyTypedNamespace)"
    StronglyTypedManifestPrefix="%(EmbeddedResource.StronglyTypedManifestPrefix)"
    PublicClass="%(EmbeddedResource.PublicClass)"
    OutputResources="@(EmbeddedResource->'$(IntermediateOutputPath)%(ManifestResourceName).resources')"
    Condition="'%(EmbeddedResource.Type)' == 'Resx' and '%(EmbeddedResource.GenerateResource)' != 'false' and '$(GenerateResourceMSBuildRuntime)' != 'CLR2'"
    SdkToolsPath="$(ResgenToolPath)"
    ExecuteAsTool="$(ResGenExecuteAsTool)"
    EnvironmentVariables="$(ResGenEnvironment)"
    MSBuildRuntime="$(GenerateResourceMSBuildRuntime)"
    MSBuildArchitecture="$(GenerateResourceMSBuildArchitecture)">

出力ファイル名をソース ファイル名のような短い名前に変更し、衝突がないことを望みます。

OutputResources="@(EmbeddedResource->'$(IntermediateOutputPath)%(Filename).resources')"

これは dotnet システム ファイルへのハックです。これをオーバーライドする他の方法があるはずです。MsBuild のドキュメントを確認する必要があります。

編集

I found a solution without needing to mess with system files.

ここMSDN http://blogs.msdn.com/b/visualstudio/archive/2010/02/15/if-your-build-fails-with-msb6002-the-command-line-for-the-resgen-taskを参照してください-is-too-long.aspx .

プロジェクト内にターゲット全体を貼り付けることができます。この方法では、システム ファイルを変更する必要はありません。</Project>これをタグの前に貼り付けるだけです。

<Target
    Name="CoreResGen"
    DependsOnTargets="$(CoreResGenDependsOn)">

    <ItemGroup>
        <_Temporary Remove="@(_Temporary)" />
    </ItemGroup>

    <PropertyGroup>
        <GenerateResourceMSBuildArchitecture Condition="'$(GenerateResourceMSBuildArchitecture)' == ''">$(PlatformTargetAsMSBuildArchitecture)</GenerateResourceMSBuildArchitecture>

        <ResgenToolPath Condition="'$(ResgenToolPath)' == ''">$(TargetFrameworkSDKToolsDirectory)</ResgenToolPath>
    </PropertyGroup>

    <PropertyGroup Condition="'$(TargetFrameworkAsMSBuildRuntime)' != '' and '$(GenerateResourceMSBuildArchitecture)' != ''">
        <!-- In the general case, we want to fail to run the task if the task host it's requesting doesn't exist, because we'd rather let the
       user know there's something wrong than just silently generate something that's probably not quite right. However, in a few 
       circumstances, there are tasks that are already aware of runtime / bitness concerns, in which case even if we go ahead and run 
       the more recent version of the task, it should be able to generate something correct.  GenerateResource is one such task, so 
       we check for the existence of the targeted task host so that we can use it preferentially, but if it can't be found, we'll fall 
       back to the current task since it's still mostly correct.

       In particular, we need to do this because otherwise people with Dev10 on a machine that they upgrade to Win8 will be broken: 
       they'll have ResGen from the 7.0A SDK installed, so launching ResGen will still work, but the CLR2 task host is only installed by 
       the 8.0A SDK, which they won't have installed, and thus without this fallback mechanism, their projects targeting v3.5 will 
       suddenly start failing to build.-->
        <GenerateResourceMSBuildRuntime
            Condition="'$(GenerateResourceMSBuildRuntime)' == '' and 
                 $([MSBuild]::DoesTaskHostExist(`$(TargetFrameworkAsMSBuildRuntime)`, `$(GenerateResourceMSBuildArchitecture)`))">$(TargetFrameworkAsMSBuildRuntime)</GenerateResourceMSBuildRuntime>

        <!-- If the targeted runtime doesn't exist, fall back to current -->
        <GenerateResourceMSBuildRuntime Condition="'$(GenerateResourceMSBuildRuntime)' == ''">CurrentRuntime</GenerateResourceMSBuildRuntime>
    </PropertyGroup>

    <!-- 4.0 task has some new parameters that we want to make use of if we're targeting 4.0 -->
    <GenerateResource
        Sources="@(EmbeddedResource)"
        UseSourcePath="$(UseSourcePath)"
        References="@(ReferencePath)"
        AdditionalInputs="$(MSBuildAllProjects)"
        NeverLockTypeAssemblies="$(GenerateResourceNeverLockTypeAssemblies)"
        StateFile="$(IntermediateOutputPath)$(MSBuildProjectFile).GenerateResource.Cache"
        StronglyTypedClassName="%(EmbeddedResource.StronglyTypedClassName)"
        StronglyTypedFileName="%(EmbeddedResource.StronglyTypedFileName)"
        StronglyTypedLanguage="%(EmbeddedResource.StronglyTypedLanguage)"
        StronglyTypedNamespace="%(EmbeddedResource.StronglyTypedNamespace)"
        StronglyTypedManifestPrefix="%(EmbeddedResource.StronglyTypedManifestPrefix)"
        PublicClass="%(EmbeddedResource.PublicClass)"
        OutputResources="@(EmbeddedResource->'$(IntermediateOutputPath)%(Filename).resources')"
        Condition="'%(EmbeddedResource.Type)' == 'Resx' and '%(EmbeddedResource.GenerateResource)' != 'false' and '$(GenerateResourceMSBuildRuntime)' != 'CLR2'"
        SdkToolsPath="$(ResgenToolPath)"
        ExecuteAsTool="$(ResGenExecuteAsTool)"
        EnvironmentVariables="$(ResGenEnvironment)"
        MSBuildRuntime="$(GenerateResourceMSBuildRuntime)"
        MSBuildArchitecture="$(GenerateResourceMSBuildArchitecture)">

        <Output TaskParameter="FilesWritten"
                ItemName="FileWrites"/>
        <Output TaskParameter="StronglyTypedFileName"
                ItemName="Compile"/>

        <!-- Gather Sources as an output since it will contain OutputResource metadata indicating the final output resource that it was compiled into -->
        <Output TaskParameter="Sources"
                ItemName="_Temporary" />

    </GenerateResource>

    <!-- But we can't use those parameters if we're targeting 3.5, since we're using the 3.5 task -->
    <GenerateResource
        Sources="@(EmbeddedResource)"
        UseSourcePath="$(UseSourcePath)"
        References="@(ReferencePath)"
        AdditionalInputs="$(MSBuildAllProjects)"
        NeverLockTypeAssemblies="$(GenerateResourceNeverLockTypeAssemblies)"
        StateFile="$(IntermediateOutputPath)$(MSBuildProjectFile).GenerateResource.Cache"
        StronglyTypedClassName="%(EmbeddedResource.StronglyTypedClassName)"
        StronglyTypedFileName="%(EmbeddedResource.StronglyTypedFileName)"
        StronglyTypedLanguage="%(EmbeddedResource.StronglyTypedLanguage)"
        StronglyTypedNamespace="%(EmbeddedResource.StronglyTypedNamespace)"
        StronglyTypedManifestPrefix="%(EmbeddedResource.StronglyTypedManifestPrefix)"
        PublicClass="%(EmbeddedResource.PublicClass)"
        OutputResources="@(EmbeddedResource->'$(IntermediateOutputPath)%(ManifestResourceName).resources')"
        MSBuildRuntime="$(GenerateResourceMSBuildRuntime)"
        MSBuildArchitecture="$(GenerateResourceMSBuildArchitecture)"
        Condition="'%(EmbeddedResource.Type)' == 'Resx' and '%(EmbeddedResource.GenerateResource)' != 'false' and '$(GenerateResourceMSBuildRuntime)' == 'CLR2'">

        <Output TaskParameter="FilesWritten"
                ItemName="FileWrites"/>
        <Output TaskParameter="StronglyTypedFileName"
                ItemName="Compile"/>

        <!-- Gather Sources as an output since it will contain OutputResource metadata indicating the final output resource that it was compiled into -->
        <Output TaskParameter="Sources"
                ItemName="_Temporary" />

    </GenerateResource>

    <ItemGroup>
        <EmbeddedResource Remove="@(_Temporary)" />

        <!-- Add back the Sources list (with OutputResource metadata) that we output from GenerateResource into EmbeddedResource -->
        <EmbeddedResource Include="@(_Temporary)" />
        <_Temporary Remove="@(_Temporary)" />

        <!-- EMITTED FOR COMPATIBILITY REASONS ONLY. CONSUME EMBEDDEDRESOURCE INSTEAD -->
        <ManifestResourceWithNoCulture Include="@(EmbeddedResource->'%(OutputResource)')"
                                       Condition="'%(EmbeddedResource.WithCulture)'=='false' and '%(EmbeddedResource.Type)' == 'Resx'">
            <EmittedForCompatibilityOnly>true</EmittedForCompatibilityOnly>
        </ManifestResourceWithNoCulture>
        <ManifestNonResxWithNoCultureOnDisk Include="@(EmbeddedResource)"
                                            Condition="'%(EmbeddedResource.WithCulture)'=='false' and '%(EmbeddedResource.Type)' == 'Non-Resx'">
            <EmittedForCompatibilityOnly>true</EmittedForCompatibilityOnly>
        </ManifestNonResxWithNoCultureOnDisk>

        <!-- EMITTED FOR COMPATIBILITY REASONS ONLY. CONSUME EMBEDDEDRESOURCE INSTEAD -->
        <ManifestResourceWithCulture Include="@(EmbeddedResource->'%(OutputResource)')"
                                     Condition="'%(EmbeddedResource.WithCulture)'=='true' and '%(EmbeddedResource.Type)' == 'Resx'">
            <EmittedForCompatibilityOnly>true</EmittedForCompatibilityOnly>
        </ManifestResourceWithCulture>
        <ManifestNonResxWithCultureOnDisk Include="@(EmbeddedResource)"
                                          Condition="'%(EmbeddedResource.WithCulture)'=='true' and '%(EmbeddedResource.Type)' == 'Non-Resx'">
            <EmittedForCompatibilityOnly>true</EmittedForCompatibilityOnly>
        </ManifestNonResxWithCultureOnDisk>

    </ItemGroup>

</Target>
于 2013-10-16T14:19:55.030 に答える