自定文件双击打开事件,需要在注册表中注册文件的图标,文件打开的启动软件路径。
首先,注册表中添加描述、图标、启动软件路径
代码如下:为操作注册表的事件
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
namespace UltraUV
{
class CFileTypeRegister
{
/// <summary>
/// RegisterFileType 使文件类型与对应的图标及应用程序关联起来。
/// </summary>
public static void RegisterFileType(CFileTypeRegInfo regInfo)
{
string strFileType = regInfo.strExtendName;
string strDescription = regInfo.strDescription;
string strIconPath = regInfo.strIcoPath;
string strOpenExe = regInfo.strExePath;
// 注册表顶级节点
RegistryKey hkRoot = Registry.ClassesRoot;
// 在HKEY_CLASSES_ROOT目录下创建文件类型
if (!strFileType.StartsWith("."))
{
strFileType = "." + strFileType;
}
if (null == hkRoot.OpenSubKey(strFileType))
{
}
else
{
#if DEBUG
// 调试期间由于反复更换目录,暂时每次都先删除\
hkRoot.DeleteSubKeyTree(strFileType);
#endif
}
// 注册表中尚未关联指定的文件类型,注册文件类型并进行关联
RegistryKey pgID = hkRoot.CreateSubKey(strFileType);
if (pgID == null)
{
// 注册表操作关闭
hkRoot.Close();
throw new Exception("Failed when creating progID");
}
// 文件类型描述
pgID.SetValue("", strDescription, RegistryValueKind.String);
// 关联图标
RegistryKey defaultIcon = pgID.CreateSubKey("DefaultIcon");
if (defaultIcon == null)
{
// 逐级关闭注册表
pgID.Close();
hkRoot.Close();
throw new Exception("Failed when creating icon");
}
// 设定图标
defaultIcon.SetValue("", strIconPath, RegistryValueKind.String);
defaultIcon.Close();
// 关联相关动作
// 创建shell子键
RegistryKey shell = pgID.CreateSubKey("shell");
if (shell == null)
{
// 逐级关闭注册表
pgID.Close();
hkRoot.Close();
throw new Exception("Failed when creating shell key");
}
// 创建打开子键
RegistryKey open = shell.CreateSubKey("open");
if (open == null)
{
// 逐级关闭注册表
shell.Close();
pgID.Close();
hkRoot.Close();
throw new Exception("Failed when creating shell-open key");
}
// 创建打开子键
RegistryKey command = open.CreateSubKey("command");
if (command == null)
{
// 逐级关闭注册表
open.Close();
shell.Close();
pgID.Close();
hkRoot.Close();
throw new Exception("Failed when creating shell-open-command key");
}
// 设定打开程序
command.SetValue("", "\"" + strOpenExe + "\" \"%1\"", RegistryValueKind.String);
// 逐级关闭注册表
command.Close();
open.Close();
shell.Close();
pgID.Close();
hkRoot.Close();
}
/**/
/// <summary>
/// GetFileTypeRegInfo 得到指定文件类型关联信息
/// </summary>
public static CFileTypeRegInfo GetFileTypeRegInfo(string extendName)
{
if (!CFileTypeRegister.FileTypeRegistered(extendName))
{
return null;
}
CFileTypeRegInfo cRegInfo = new CFileTypeRegInfo(extendName);
string strRelationName = extendName.Substring(1, extendName.Length - 1).ToUpper() + "_FileType";
RegistryKey cRelationKey = Registry.ClassesRoot.OpenSubKey(strRelationName);
cRegInfo.strDescription = cRelationKey.GetValue("").ToString();
RegistryKey cIconKey = cRelationKey.OpenSubKey("DefaultIcon");
cRegInfo.strIcoPath = cIconKey.GetValue("").ToString();
RegistryKey cShellKey = cRelationKey.OpenSubKey("Shell");
RegistryKey cOpenKey = cShellKey.OpenSubKey("Open");
RegistryKey cCommandKey = cOpenKey.OpenSubKey("Command");
string strTemp = cCommandKey.GetValue("").ToString();
cRegInfo.strExePath = strTemp.Substring(0, strTemp.Length - 3);
return cRegInfo;
}
/**/
/// <summary>
/// UpdateFileTypeRegInfo 更新指定文件类型关联信息
/// </summary>
public static bool UpdateFileTypeRegInfo(CFileTypeRegInfo regInfo)
{
if (!CFileTypeRegister.FileTypeRegistered(regInfo.strExtendName))
{
return false;
}
string strExtendName = regInfo.strExtendName;
string strRelationName = strExtendName.Substring(1, strExtendName.Length - 1).ToUpper() + "_FileType";
RegistryKey cRelationKey = Registry.ClassesRoot.OpenSubKey(strRelationName, true);
cRelationKey.SetValue("", regInfo.strDescription);
RegistryKey cIconKey = cRelationKey.OpenSubKey("DefaultIcon", true);
cIconKey.SetValue("", regInfo.strIcoPath);
RegistryKey cShellKey = cRelationKey.OpenSubKey("Shell");
RegistryKey cOpenKey = cShellKey.OpenSubKey("Open");
RegistryKey cCommandKey = cOpenKey.OpenSubKey("Command", true);
cCommandKey.SetValue("", regInfo.strExePath + " %1");
cRelationKey.Close();
return true;
}
/**/
/// <summary>
/// FileTypeRegistered 指定文件类型是否已经注册
/// </summary>
public static bool FileTypeRegistered(string extendName)
{
RegistryKey cSoftwareKey = Registry.ClassesRoot.OpenSubKey(extendName);
if (cSoftwareKey != null)
{
return true;//暂时改为false,还要改为true
}
return false;
}
}
}
其次调用,注册表的操作事件,注册注册表
m_cFileTypeRegInfo.strExtendName = ".sdf";
m_cFileTypeRegInfo.strDescription = Properties.Resource.STR_SDF_NAME_METHODFILE;
m_cFileTypeRegInfo.strIcoPath = Application.StartupPath + "\\sharedDLL.dll,0"; //图标在dll文件中的位置,0表示第一个图标。
m_cFileTypeRegInfo.strExePath = Application.ExecutablePath;
CFileTypeRegister.RegisterFileType(m_cFileTypeRegInfo);
图标的排序是按照图标在资源文件的顺序排列的,如下图,0号图标就为UltraUV Project.ico.ico。
为了注册完成后,自定义文件的图标能够及时更新,使用API函数实现,在注册完后调用SHChangeNotify()函数,更新图标。
[System.Runtime.InteropServices.DllImport("shell32.dll")]
public static extern void SHChangeNotify(uint wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
SHChangeNotify(0x8000000, 0, IntPtr.Zero, IntPtr.Zero);
为了能够找到图标的位置,还需要设置项目中资源文件路径:
项目-->属性-->应用程序-->资源文件