winform 创建图片资源文件
很多图片需要手动添加进资源文件,或者可以使用代码直接创建资源文件.resx 和.Designer.cs
/// <summary> /// 创建Bitmap资源文件 /// </summary> /// <param name="resxPath"></param> /// <param name="imageFolder"></param> /// <param name="fileNames"></param> public static void CreateBitMapResxWithFileRef(string resxPath, string imageFolder) { if (!Directory.Exists(imageFolder)) throw new DirectoryNotFoundException($"文件夹不存在: {imageFolder}"); // 获取文件夹下所有文件(也可根据需要过滤图片扩展名) string[] files = Directory.GetFiles(imageFolder); using (var writer = new ResXResourceWriter(resxPath)) { foreach (string fullPath in files) { // 跳过非图片文件?按原始逻辑不会自动过滤,此处保留全文件处理。 // 如需只处理图片,可加上扩展名过滤: // string ext = Path.GetExtension(fullPath).ToLower(); // if (ext != ".png" && ext != ".jpg" ...) continue; string fileName = Path.GetFileName(fullPath); string resourceKey = Path.GetFileNameWithoutExtension(fileName); // 键名不含扩展名 // 创建文件引用,编译时会将实际图片数据嵌入 string targetPath = fullPath; ////相对于当前这个软件工程的相对路径 //string NowProjectPath = AppDomain.CurrentDomain.BaseDirectory; // 获取相对路径 //string relativePath = GetRelativePath(NowProjectPath, targetPath); string resxDir = Path.GetDirectoryName(resxPath); string relativePath = GetRelativePath(resxDir, targetPath); var fileRef = new ResXFileRef(relativePath, typeof(Bitmap).AssemblyQualifiedName); writer.AddResource(resourceKey, fileRef); } writer.Generate(); } } [DllImport("shlwapi.dll", CharSet = CharSet.Auto)] static extern bool PathRelativePathTo( StringBuilder pszPath, string pszFrom, uint attrFrom, string pszTo, uint attrTo); const uint FILE_ATTRIBUTE_DIRECTORY = 0x10; const uint FILE_ATTRIBUTE_NORMAL = 0x80; public static string GetRelativePath(string from, string to) { var sb = new StringBuilder(260); PathRelativePathTo(sb, from, FILE_ATTRIBUTE_DIRECTORY, to, FILE_ATTRIBUTE_NORMAL); return sb.ToString(); } /// <summary> /// 创建设计文件 /// </summary> /// <param name="resxFilePath"></param> /// <param name="outputCsPath"></param> /// <param name="namespaceName"></param> /// <param name="className"></param> /// <param name="resourceBaseName"></param> /// <param name="internalClass"></param> /// <returns></returns> public static bool GenerateBitmapDesignerFile( string resxFilePath, string outputCsPath, string namespaceName,//命名空间 string className,//类名 string resourceBaseName,//资源基类名 bool internalClass = false) { if (!File.Exists(resxFilePath)) throw new FileNotFoundException($"资源文件不存在: {resxFilePath}"); try { //ResXResourceReader 解析 .resx 中引用的文件(比如.png)时,默认使用的是当前进程的工作目录,而不是.resx 文件所在的目录。 //解决办法:在读取资源前,把 ResXResourceReader 的 BasePath 设成.resx 文件所在的目录: // 1. 将 .resx 读入 IDictionary (Hashtable) var resources = new Hashtable(); using (var reader = new ResXResourceReader(resxFilePath)) { // 添加这一行,让相对路径基于 .resx 所在目录解析 reader.BasePath = Path.GetDirectoryName(resxFilePath); var enumerator = reader.GetEnumerator(); while (enumerator.MoveNext()) { resources.Add(enumerator.Key, enumerator.Value); } } // 2. 创建代码提供程序 var codeProvider = CodeDomProvider.CreateProvider("CSharp"); // 3. 调用接受 IDictionary 的重载(绝对不会错) var code = StronglyTypedResourceBuilder.Create( resources, // IDictionary resourceBaseName, // 资源基名 namespaceName, // 命名空间 codeProvider, // 代码提供程序 internalClass, // 是否 internal out string[] errors // 错误信息 ); // 4. 检查错误 if (errors != null && errors.Length > 0) { Console.WriteLine("生成时错误:"); foreach (var e in errors) Console.WriteLine(" - " + e); return false; } // 5. 写出 C# 文件 using (var writer = new StreamWriter(outputCsPath, false, System.Text.Encoding.UTF8)) { var options = new CodeGeneratorOptions { BracingStyle = "C", BlankLinesBetweenMembers = true }; codeProvider.GenerateCodeFromCompileUnit(code, writer, options); } return true; } catch (Exception ex) { Console.WriteLine($"生成失败: {ex.Message}"); //MessageBox.Show($"生成设计文件失败: {ex.Message}"); return false; } }

浙公网安备 33010602011771号