2013-10-15 37 views
5

我正在與一些深層嵌套(長命名空間)文件的項目。該項目不會編譯,因爲大部分資源文件的文件名太長。例如。資源文件名過長

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文件重命名爲命名空間中的編譯器?我希望資源文件名在編譯後保持不變。

+2

我討厭問清楚,但是有沒有可能將項目移動到名稱較短或更接近根驅動器的目錄? –

回答

9

編輯就爲C的線2291:\ WINDOWS \ Microsoft.NET \框架\ v4.0.30319 \ Microsoft.Common.Targets

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

更改輸出文件名的東西短,如源文件名和希望沒有collisons。

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

您可以將整個Target粘貼到您的項目中,這樣您就不需要更改系統文件。只需在</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> 
+0

我已經應用了上述修復程序,它似乎可行,但我還需要修改文件「Resources.Designer.cs」,因爲修復程序似乎更改了資源文件的名稱。修改後的行是: global :: System.Resources.ResourceManager temp = new global :: System.Resources.ResourceManager(「Resources」,typeof(Resources).Assembly); – Cathartis

+0

對我來說,將項目移動到文件夾的根目錄解決了問題。這是因爲Windows的路徑字符限制 – Thaadikkaaran