.NET Framework WinForms迁移SDK-Style遇MissingManifestResourceException问题
MissingManifestResourceException for WinForms in Subdirectories After SDK-Style Project Migration Root Cause
When migrating to the SDK-style project format, Visual Studio fails to preserve the <DependentUpon> relationships for .Designer.cs and .resx files located in subdirectories. Additionally, the embedded resources' logical names don't align with the form class's full namespace, causing the resource manager to fail locating the required resources at runtime.
Step-by-Step Solutions
1. Validate Form Namespaces
Ensure every form in a subdirectory uses a namespace that matches the directory structure (using valid C# syntax—no spaces or special characters). For example, a form in the Main Class Files directory should have a namespace like MainApp.MainClassFiles (replace spaces with underscores or remove them entirely).
2. Restore Dependencies and Correct Resource Logical Names
You can fix this manually for individual forms or use wildcard rules to automate the process for large projects.
Manual Fix Example (For a Single Form)
Update your .csproj to include these entries for the affected form:
<ItemGroup> <Compile Update="Main Class Files\Main.cs"> <SubType>Form</SubType> </Compile> <Compile Update="Main Class Files\Main.Designer.cs"> <DependentUpon>Main.cs</DependentUpon> </Compile> <EmbeddedResource Update="Main Class Files\Main.resx"> <SubType>Designer</SubType> <DependentUpon>Main.cs</DependentUpon> <!-- Match the full namespace of your form class --> <LogicalName>MainApp.MainClassFiles.Main.resources</LogicalName> </EmbeddedResource> </ItemGroup>
Automated Wildcard Rule (For Large Projects)
Add these groups to your .csproj to apply the correct settings to all forms automatically:
<!-- Link all .Designer.cs files to their parent .cs files --> <ItemGroup> <Compile Update="**\*.Designer.cs"> <DependentUpon>$([System.String]::Copy('%(Filename)').Replace('.Designer', '')).cs</DependentUpon> </Compile> </ItemGroup> <!-- Link resx files to parent .cs and set correct logical names --> <ItemGroup> <!-- Skip general Resources.resx to avoid conflicts --> <EmbeddedResource Update="**\*.resx" Condition="!%(Filename.Equals('Resources'))"> <SubType>Designer</SubType> <DependentUpon>$([System.String]::Copy('%(Filename)')).cs</DependentUpon> <!-- Generate logical name from root namespace and directory structure --> <LogicalName>$(RootNamespace).%(RelativeDir.Replace('\', '.').TrimEnd('.').Replace(' ', '_')).%(Filename).resources</LogicalName> </EmbeddedResource> </ItemGroup>
The .Replace(' ', '_') part handles directory names with spaces by converting them to valid namespace syntax.
3. Clean and Rebuild
After updating the .csproj:
- Delete the
binandobjdirectories manually to remove leftover old resources. - Run
Build > Clean Solutionfollowed byBuild > Rebuild Solution.
4. Verify Resource Embedding
To confirm resources are embedded correctly:
- Use
ildasm.exe(included with .NET Framework) to open your compiled assembly. - Check the manifest resources to ensure the resource name matches the form's full namespace + class name +
.resources(e.g.,MainApp.MainClassFiles.Main.resources).
Additional Checks
- Confirm the
<RootNamespace>property in your.csprojmatches your application's base namespace (e.g.,<RootNamespace>MainApp</RootNamespace>). - For forms you previously moved, double-check their namespace and
.csprojentries to eliminate mismatches.
内容的提问来源于stack exchange,提问作者NⵙⵙB

