2008/04/17 | res协议使用详解
类别(零零碎碎) | 评论(0) | 阅读(123) | 发表于 13:22
什么是res协议?
 
当在IE的地址栏里面输入了一个错误的地址的时候,IE会显示错误页面。在错误页面上,右击然后点属性,查看页面的来源你会发现它是一个类似这样的连接:
res://C:\WINDOWS\system32\shdoclc.dll/dnserror.htm
 
以上面这个地址就是res协议的一个例子。
 
"RES://"协议是IE 4.0预定义的一个协议,它可以用来提取程序模块中的资源,如图片,声音,字符串等等。这里的程序模块一般来说指的是符合WIN32 PE格式的文件,如普通的EXE,DLL等。
 
可以尝试在IE地址栏里面输入以下的内容:
res://shell32.dll/2/131
res://shell32.dll/2/147
 
注:
第一个是windows xp professional的表示图案。
第二个是windows xp home edition的表示图案。
 
让我们来看看MSDN对res protocol是怎么说的:
 
res Protocol

Specifies a resource that will be obtained from a module.
Syntax
res://sFile[/sType]/sID
Tokens
sFile
Path and file name of the module that contains the resource.
sType
Optional. String or numerical resource type. This can be either a custom resource or one of the RT_ predefined resource types described in the FindResource function reference. If a numerical resource type is specified, the actual number of the identifier, not the identifier name, must follow a # character. See the example for more information. If this parameter is not specified, the default resource type is RT_HTML.
sID
String or numerical identifier of the resource. If a numerical identifier is specified, the actual number of the identifier, not the identifier itself, must follow a # character. See the example for more information.
Remarks
Available as of Microsoft® Internet Explorer 4.0 or later.
Remember, URLs require that special characters such as '#' be escaped. Use '%23' to escape the '#' character.
Note  Internet Explorer 6 Service Pack 1 (SP1) no longer allows browsing a local machine from the Internet zone. For instance, if an Internet site contains a link to a local file, Internet Explorer 6 SP1 displays a blank page when a user clicks on the link. Previous versions of Internet Explorer followed the link to the local file.
Example
This example shows the correct and incorrect ways to format the numerical identifier for the resource type.
#define MYBITMAP 234
 // This is correct.
"res://mydll.dll/#2/#234"
 // This is not correct.
"res://mydll.dll/#2/MYBITMAP"
 
以上可以看到res协议较全面的信息。包括了语法,应用,示例及其相关的说明。
不过这里有2个小问题:
 
1、MSDN上对res协议的语法的说明中指出,如果路径中sType和sId是数字的话,必须在前面冠以’#’符,以保证正确,然而我在装了SP2的IE6.0中试验的时候发现,如果把sType和sID前面加上’#’符,会出现错误;相反,不加的时候就完全没有问题。
猜想可能是微软在SP2中更正了res的用法,或者是MSDN出现错误(这个可能性似乎不是很大)。不过我们的应用完全可以用字符串来代替数字,所以即便是SP2出现的更正也不影响兼容性。
2、以”res://d:\test\mydll.dll/2/234”为例,d:\test\mydll.dll部分,即sFile部分必须是windows格式的路径,比如你不能写成d:/test/mydll.dll的形式。
后面sType和sID部分则必须是’/’的形式,不然会出问题。
 
还有一个小问题,怎样知道一个dll或者exe里面有什么资源呢?
这当然要用到大名鼎鼎的资源提取工具eXeScope。用eXeScope打开一个exe或者dll,就可以很方便的浏览,修改,提取它的资源,即便是某些加壳的程序,所以eXeScope也可用作简单的软件汉化。
 
到现在,res协议的应用方面没问题了,我们讨论的下一个问题是创建一个资源DLL。
以VC6为例,
1、新建一个工程,类型选择Win32 Dynamic-Link Library。输入工程名字Test。点击OK
2、DLL类型中,选择An Empty DLL Project。然后点击Finish。
3、这个时候工程是空的,什么都没有。我们需要为其添加一个资源脚本。点File->New,
在Files选项卡里面选择Resource Script,输入文件名字test.rc,然后点OK。
这样工程中就包含了一个资源脚本文件。点开File View,在Source Files中可以看到它。选中它,然后点击右键,选择打开,在Work Space中就会出现Resource View选项卡。方便以后的添加资源操作。
4、点Project->settings…,然后Setting For选择Win32 Release,右边点开link选项卡,在最下面Project Options里面添加/NOENTRY参数,记得与之前或者之后的参数用空格间开。这个参数是资源DLL连接成功的基础。
5、点Build->Batch Build…,只选则Win32 Release,然后点Build。生成Release版本的资源DLL。
 
当然以上步骤创建的DLL仅仅是个空壳,没有资源在内,下面讨论添加资源进DLL。
在Resource View中,右键然后选择Insert,弹出对话框,选择新建(new)或者import。以import为例,如果想添加的资源是位图等预定义的,可直接选中要引入的文件然后import。如果是自定义类型的,就要填写类型的名称(将来res地址中的sType)。一般引入资源后,VC自动为资源定义一个ID,一般都是数字的形式。当然我们也可以自定义ID,如我们想为一个JPG图像定义ID为Test.jpg,则打开该资源的属性对话框,然后ID栏里面填写”Test.jpg”,注意,这里的””不能省略,否则VC会不接受输入(‘.’的存在),或者仍然为他设置一个数字作为ID(如设置为TEST,则仍然是一个数字)。
 
再有,如果要添加的资源包含目录层次该怎么办呢?
比如所,要添加一个页面test.htm,页面中有个连接指向images文件夹下的miki.jpg,即:<img src=”images/miki.jpg”>.该怎么添加呢?
首先肯定的一点是他们都必须放在同一种类型的资源下,比如自定义资源TEST。然后再TEST底下添加一个目录吗?我试了很久都没添加上(如果某位Super high hand知道怎么做,麻烦跟我共享下)。所以采用了一种比较笨的方法:在设定资源ID的时候体现出这个目录层次来,即test.htm的ID设为“test.htm”, miki.jpg的ID设为“images/miki.jpg”。然后做成资源DLL测试”res://test.dll/TEST/test.htm”成功。同时为了确保资源释放的时候是按照目录层次,而不是因为把”images/miki.jpg”作为一个名字来释放(因为这时候test.htm仍然能够正确连接图片),重新作了一个测试:
1、test.htm中的连接改为<img src=”../images/miki.jpg”>.
2、修改test.htm的ID为”test/test.htm”,此时miki.jpg的ID为”images/miki.jpg”.
生成DLL后测试”res://test.dll/TEST/test/test.htm”成功。
证明这种方法是有效的。
0

评论Comments