修改文件版本信息(PE文件版本信息、资源Version)

本文介绍如何使用C#来读取和修改PE文件(dll和exe)的版本信息,包括通过编译前事件和编译后事件进行自动化处理。在VS2010中,通过配置不同生成选项(如Debug或Release)来设置不同的版本备注。文中提供了不依赖IDE自动更新的解决方案,以及简单的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此处的文件版本信息,指:

也就是VS开发环境中的资源Version:

对于信息的读取,用C#实现起来很简单:

System.Diagnostics.FileVersionInfo fvi = System.Diagnostics.FileVersionInfo.GetVersionInfo(dllOrExeFilePathName);
fvi...

虽然C#获取的信息并不完整(当然,在大多数情况下这些信息已经足够)。
用资源修改工具或PE修改工具,可以对版本信息进行修改。

由于一些原因,需要对一些dll和exe进行批量修改、反复修改,并且将这些操作配置在VS2010的生成选项中(比如,选择Debug配置,则版本信息中的备注为“调试”,选择Release为“发行”)。

当然,在RC文件中,也是可以使用宏和预处理的:

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "080404b0"
        BEGIN
            VALUE "CompanyName", "INFO"
#ifdef DEBUG
            VALUE "Comment", "调试"
#else
            VALUE "Comment", "发行"
#endif
            VALUE "FileDescription", "INFO"
            VALUE "FileVersion", "1.0.0.1"
            VALUE "InternalName", "INFO"
            VALUE "LegalCopyright", "INFO"
            VALUE "OriginalFilename", "INFO"
            VALUE "ProductName", "INFO"
            VALUE "ProductVersion", "1.0.0.1"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x804, 1200
    END
END

但问题在于,在IDE中一旦对资源进行了更改,则用户添加的任何内容都会丢失;也就是说,资源文件的内容是由IDE自动更新和维护的。

当然,这不是问题。我们可以使用编译前事件,写个小程序,根据配置修改rc文件中的相关内容。这个实现比较简单。

不过,本人采取了另外一种方法:使用编译后事件,对已经生成的dll或exe注入相关内容。这样做的好处是,对执行注入的程序稍加修改,就能批量处理任意数目、任意位置的dll和exe。

从网上逛了一圈,找到了一些示例,可惜的是,没看到有完整的。于是自己写了一个。

由于本人水平有限,加之时间有限,代码不大好,勿喷,欢迎改善之:

头文件:

#pragma once

class CVersionUpdater
{
public:
	class CResourcePacker
	{
	public:
		CResourcePacker() : Resource(NULL), Size(0) {}
		~CResourcePacker() { Reset(); }

	public:
		void Reset();

		void AppendWord(WORD value_);
		void AppendWords(const WORD* value_, DWORD count_);
		void AppendWChar(WCHAR value_);
		void AppendWString(const WCHAR* value_);
		void AppendAlignment() ;
		void Append(const void* value_, DWORD size_);

		inline BYTE* GetResource() const { return this->Resource; }
		inline DWORD GetSize() const { return this->Size; }

	private:
		BYTE* Resource;
		DWORD Size;
	};
	class CResourceParser
	{
	public:
		CResourceParser(const BYTE* data_) : Data(data_),ParsedSize(0) {}

	public:
		WORD Word();
		WCHAR WChar();
		void Alignment();
		const BYTE* Move(long size_);
		long GetParsedSize() const { return this->ParsedSize; }

	private:
		const BYTE* Data;
		long ParsedSize;
	};

	struct structLangageAndCodePage 
	{
 		WORD Language;
 		WORD CodePage;
 	};

	class CStringTable : public structLangageAndCodePage
	{ 
	public:
		CStringTable();
		~CStringTable();

	public:
		inline const CString* GetComments() const { return this->Comments; }
		inline const CString* GetCompanyName() const { return this->CompanyName; }
		inline const CString* GetFileDescription() const { return this->FileDescription; }
		inline const CString* GetFileVersion() const { return this->FileVersion; }
		inline const CString* GetInternalName() const { return this->InternalName; }
		inline const CString* GetLegalCopyright() const { return this->LegalCopyright; }
		inline const CString* GetLegalTrademarks() const { return this->LegalTrademarks; }
		inline const CString* GetOriginalFilename() const { return this->OriginalFilename; }
		inline const CString* GetPrivateBuild() const { return this->PrivateBuild; }
		inline const CString* GetProductName() const { return this->ProductName; }
		inline const CString* GetProductVersion() const { return this->ProductVersion; }
		inline const CString* GetSpecialBuild() const { return this->SpecialBuild; }
		
		inline void SetComments(LPCTSTR value_) { this->Set(Comments, value_); }
		inline void SetCompanyName(LPCTSTR value_) { this->Set(CompanyName, value_); }
		inline void SetFileDescription(LPCTSTR value_) { this->Set(FileDescription, value_); }
		inline void SetFileVersion(LPCTSTR value_) { this->Set(FileVersion, value_); }
		inline void SetInternalName(LPCTSTR value_)
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值