.net 资源文件名太长

.net 资源文件名太长,.net,visual-studio,.net,Visual Studio,我正在处理一个包含一些深度嵌套(长名称空间)文件的项目。项目无法编译,因为大多数资源文件的文件名太长。例如 Resource file "obj\Debug\xxxx.xxxxxxxxxxxxx.xxxx.Services.DeliveryChannels.Web.Common.Resources.xxxxxxxxxxxxxxxxxxx.resources" has an invalid name. The item metadata "%(FullPath)" cannot be applie

我正在处理一个包含一些深度嵌套(长名称空间)文件的项目。项目无法编译,因为大多数资源文件的文件名太长。例如

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文件重命名为命名空间?我希望资源文件名在编译后保持不变。

编辑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)">
这是对dotnet系统文件的攻击,必须有其他方法来覆盖它,我需要检查MsBuild文档

编辑

I found a solution without needing to mess with system files.
请看这里的MSDN

您可以将整个目标粘贴到项目中,这样就不需要更改系统文件。只需将此粘贴到
标记之前

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

$(平台TargetasBuildArchitecture)
$(TargetFrameworkDKToolsDirectory)
$(TargetFrameworkAsMSBuildRuntime)
当前运行时
真的
真的
真的
真的

我不想问显而易见的问题,但您是否有可能将项目移动到一个名称较短或更靠近根驱动器的目录中?我已经应用了上面的修复程序,它似乎有效,但我还需要修改文件“Resources.Designer.cs”,因为该修复程序似乎会更改资源文件的名称。修改的行是:global::System.Resources.ResourceManager temp=new global::System.Resources.ResourceManager(“Resources”,typeof(Resources).Assembly);对我来说,将项目移动到文件夹的根目录解决了这个问题。这是因为Windows的路径字符限制
<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>