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

 

posted @ 2026-05-12 15:23  家煜宝宝  阅读(11)  评论(0)    收藏  举报