前言:
我在编码的时候,遇到了一个需求,是在程序中接收到一个文件名,要求我创建进程并根据目标文件的后缀启动对应的打开程序打开目标文件。其中涉及到的详细原理在http://blog.csdn.net/arvon2012/article/details/7818909有描述,对刚接触注册表编程的朋友请看入门文章http://blog.csdn.net/arvon2012/article/details/7839659.
本文对应的完整版代码在http://download.csdn.net/detail/arvon2012/4482614
基本原理:
理论上的原理很简单,就是在注册表中查询和后缀一致的键,通过一步一步的查询,找到打开对应后缀文件的命令,然后在创建进程的时候,把查询到并整理好的命令传入创建进程的函数中。文件就会像被双击后一样用默认打开方式打开。
实现步骤详解:
1.打开注册表中和后缀一致的键,并读取该键默认值(这个值是另一个键的名称)
//从文件名中得到后缀
subfix = wcsrchr(pathname, '.');//subfix负责存放后缀
//打开后缀对应的注册表项
RegOpenKeyExW(HKEY_CLASSES_ROOT,subfix,0,KEY_ALL_ACCESS,&hKey);
//获取上面打开项的默认(default)值
RegQueryValueExW(hKey,NULL,0,(LPDWORD)val,(BYTE *)result,dwSize);
RegCloseKey(hKey);
倒数第二行的result中存放了我们查到的值
2.用上面查到的值打开对应的键及其子键
下面要打开存放了打开这类文件命令的键,位置在result\shell\open\command,打开后获取该键的默认值,就是一个打开命令
//根据result值打开存放打开命令的项:.xxx\shell\open\command
wcscat(result,L"\\shell\\open\\command");
if(ERROR_SUCCESS != RegOpenKeyExW(HKEY_CLASSES_ROOT,result,0,KEY_ALL_ACCESS,&hKey))
{
printf("Open target failed!\n");
}
//获取命令
RegQueryValueExW(hKey,NULL,0,(LPDWORD)val,(BYTE *)result,dwSize1);
命令存放在最后一行的result中。
3.整理组装可用的命令
获得的命令不是直接可以用的格式,我们要提取需要的部分,然后组装上目标文件路径
一般获得的命令有两种形式,一种是%SystemRoot%开头的,这种如下处理:
if(szCommandLine[0]=='%')
{
strcpy(TszCommandLine,"C:\\windows\\");
i = 13;
while(szCommandLine[i]!=' ')
{
TszCommandLine[i-2] = szCommandLine[i];
i++;
}
TszCommandLine[i-2] = '\0';
}
另一种格式是类似“C:\filename” “”这样的。这类命令如下处理:
//否则:
else
{
i = 1;
while(szCommandLine[i]!='"')
{
TszCommandLine[i-1] = szCommandLine[i];
i++;
}
TszCommandLine[i-1] = '\0';
}
命令的前半部分整理好后,把目标文件的路径拼接到后半部分上:
//将要打开的文件名组装到命令中
strcat(TszCommandLine," ");
char *tmp_pathname = new char[260];
i = 0;
//用Char型变量存放原来宽字节形式的路径名
while(pathname[i])
{
tmp_pathname[i] = pathname[i];
i++;
}
tmp_pathname[i] = '\0';
strcat(TszCommandLine,tmp_pathname);//正式组装
3.创建进程打开文件
创建进程,把前面整理好的命令,作为参数传入createProcess中。文件打开成功
//创建进程,运行命令
BOOL bRet = CreateProcessA(
NULL, //不在此指定可执行文件的文件名
TszCommandLine, //命令行参数
NULL, //默认进程安全性
NULL, //默认线程安全性
FALSE, //当前进程内的句柄不可以被子进程继承
CREATE_NEW_CONSOLE, //为新进程创建一个新的控制台窗口
NULL, //使用本进程的环境变量
NULL, //使用本进程的驱动器和目录
&si, //父进程传给子进程的一些信息
&pi); //保存新进程信息的结构
本文介绍如何在VC程序中,根据文件后缀查询注册表找到对应的打开程序,并利用查询结果创建进程来打开目标文件。详细步骤包括查询注册表键、获取打开命令、整理命令格式以及最终创建进程执行操作。

2万+

被折叠的 条评论
为什么被折叠?



