@@ -98,7 +98,7 @@ internal ArrayList UnsuccessfullyCreatedOutFiles
9898 /// <summary>
9999 /// Whether we successfully created the STR class
100100 /// </summary>
101- internal bool StronglyTypedResourceSuccessfullyCreated { get ; } = false ;
101+ internal bool StronglyTypedResourceSuccessfullyCreated { get ; private set ; } = false ;
102102
103103 /// <summary>
104104 /// Indicates whether the resource reader should use the source file's
@@ -423,6 +423,56 @@ public void CreateStronglyTypedResources(string inputFileName, CodeDomProvider p
423423 {
424424 throw new ApplicationException ( errors [ 0 ] ) ;
425425 }
426+
427+ StronglyTypedResourceSuccessfullyCreated = true ;
428+ }
429+
430+ /// <summary>
431+ /// Generates a strongly typed resource class from in-memory .resx content.
432+ /// Used by the VS custom tool so that unsaved designer edits are reflected
433+ /// immediately without waiting for the file to be written to disk.
434+ /// </summary>
435+ public void CreateStronglyTypedResources ( string inputFileName , string inputFileContent , CodeDomProvider provider , TextWriter writer , string resourceName )
436+ {
437+ Init ( ) ;
438+
439+ ReadResources ( inputFileName , inputFileContent , true ) ;
440+
441+ string [ ] errors = null ;
442+
443+ CreateStronglyTypedResources ( provider , writer , resourceName , out errors ) ;
444+
445+ if ( errors != null && errors . Length > 0 )
446+ {
447+ throw new ApplicationException ( errors [ 0 ] ) ;
448+ }
449+
450+ StronglyTypedResourceSuccessfullyCreated = true ;
451+ }
452+
453+ /// <summary>
454+ /// Reads resources from in-memory .resx content. For ResXFileRef entries the
455+ /// linked files are still resolved from disk using the directory of
456+ /// <paramref name="filename"/> as the base path.
457+ /// </summary>
458+ public void ReadResources ( String filename , string fileContent , bool shouldUseSourcePath )
459+ {
460+ Format format = GetFormat ( filename ) ;
461+ if ( format == Format . XML )
462+ {
463+ ResXResourceReader resXReader = assemblyList != null
464+ ? new ResXResourceReader ( new StringReader ( fileContent ) , assemblyList )
465+ : new ResXResourceReader ( new StringReader ( fileContent ) ) ;
466+ if ( shouldUseSourcePath )
467+ {
468+ resXReader . BasePath = Path . GetDirectoryName ( Path . GetFullPath ( filename ) ) ;
469+ }
470+ ReadResources ( resXReader , filename ) ;
471+ }
472+ else
473+ {
474+ ReadResources ( filename , shouldUseSourcePath ) ;
475+ }
426476 }
427477
428478 private CodeNamespace CreateNamespace ( CodeCompileUnit ccu , string ns , Hashtable tableNamespaces )
@@ -678,13 +728,22 @@ private void ReadResources(IResourceReader reader, String fileName)
678728 while ( resEnum . MoveNext ( ) )
679729 {
680730 string name = ( string ) resEnum . Key ;
681- // Replace dot in the name with underscore.
731+ // Replace dot in the name with underscore.
682732 // 1. First reason - this is what desktop resource generator does.
683733 // 2. Second reason - Extra dots causes resource generator to create name space and enumerations.
684734 // This complicates the syntax and finally create invalid code if 2 or more dots are present.
685735 // So we just make longer name.
686736 name = name . Replace ( '.' , '_' ) ;
687- object value = resEnum . Value ;
737+ object value ;
738+ try
739+ {
740+ value = resEnum . Value ;
741+ }
742+ catch ( Exception ex )
743+ {
744+ logger ? . LogWarning ( null , fileName , 0 , 0 , 0 , 0 , "GenerateResource.CannotLoadResource" , ( string ) resEnum . Key , ex . Message ) ;
745+ continue ;
746+ }
688747 AddResource ( name , value , fileName ) ;
689748 }
690749 }
@@ -837,11 +896,18 @@ private void WriteTextResources(String fileName)
837896 /// <param name="linePosition">Column number for messages</param>
838897 private void AddResource ( string name , object value , String inputFileName , int lineNumber , int linePosition )
839898 {
899+ if ( resourcesHashTable . ContainsKey ( name ) )
900+ {
901+ logger ? . LogWarning ( null , inputFileName , lineNumber , linePosition , 0 , 0 , "GenerateResource.DuplicateResourceName" , name ) ;
902+ return ;
903+ }
904+
840905 Entry entry = Entry . CreateEntry ( name , value , StronglyTypedNamespace , GenerateNestedEnums ? StronglyTypedClassName : string . Empty ) ;
841906
842907 Debug . Assert ( entry . ClassName . Length > 0 ) ;
843908
844909 resources . Add ( entry ) ;
910+ resourcesHashTable [ name ] = entry ;
845911 }
846912
847913 private void AddResource ( string name , object value , String inputFileName )
@@ -944,8 +1010,7 @@ public static Entry CreateEntry(string name, object value, string defaultNamespa
9441010 // Examples - .wav
9451011 // this is a binary resource
9461012 MemoryStream msOther = ( MemoryStream ) value ;
947- byte [ ] memoryData = new byte [ msOther . Length ] ;
948- msOther . Read ( memoryData , 0 , 0 ) ;
1013+ byte [ ] memoryData = msOther . ToArray ( ) ;
9491014 entry = new BinaryEntry ( name , memoryData ) ;
9501015 break ;
9511016 default :
@@ -954,7 +1019,7 @@ public static Entry CreateEntry(string name, object value, string defaultNamespa
9541019
9551020 if ( entry == null )
9561021 {
957- throw new Exception ( ) ;
1022+ throw new Exception ( $ "Resource ' { name } ' has unsupported type ' { value . GetType ( ) . FullName } '." ) ;
9581023 }
9591024
9601025 if ( entry . Namespace . Length == 0 )
0 commit comments