文件扩展名新建与绑定

说正事前先让我吐点槽

昨天一整个晚上没有开空调,接着与蚊子大战,结果发生了什么你猜?我感冒啦!哈哈哈,这强有力地证明了我不是笨蛋^ - ^(斜眼看向橙大人

感觉好久没写博客,心中满满的负罪感。其实上个礼拜就把要写的东西(PCA)学好了,但是呢,不知道怎么就给自己放了几天假(需要一点小小的安慰,之后刷了纸牌屋、朝五晚九……(好多日剧想看怎么破?233

PCA的部分呢,我保证在明后两天里放上来!(认真脸)
这几天在看WPF编程宝典,本打算每天八章的,然而只有第一天做到了,看来在八月前把这本书看完是无望了。

说了这么多,祭出本文的重点:文件扩展名。感觉上这和UI没什么关系,但还是挺新奇的,那就放上来吧!

关于工程实现的文章我还是第一次写,完全不知道从哪里写起,是不是我只要贴代码就行了?(咳咳,感觉这样太水了,先试试吧

我们知道在Windows下,基本上每个文件都有一个扩展名(俗称后缀,不要笑!然后呢,到本文结束,你就知道怎么新建一个自定义的后缀,以及如何绑定自己写的程序来打开这个自定义后缀的文件了(俗称默认打开方式。

先说一下预备知识:
这里的操作实质上就是在修改注册表
progID是CLSID的简化名字
.Net本身的SetValue是这样的:

public void SetValue(
        string name,
        object value,
        RegistryValueKind valueKind
)

public void SetValue(
        string name,
        object value
)

为了使用方便,我们对它们进行重载

于是,上代码:

public class FileRegistrationHelper
{
    public static void SetFileAssociation(string extension, string progID)
    {
        // 新建扩展名子键
        SetValue(Registry.ClassesRoot, extension, progID);

        // 新建progID子键
        string assemblyFullPath = System.Reflection.Assembly.GetExecutingAssembly().Location.Replace("/", @"\");
        MessageBox.Show(assemblyFullPath);
        StringBuilder sbShellEntry = new StringBuilder();
        sbShellEntry.AppendFormat("\"{0}\" \"%1\"", assemblyFullPath);
        MessageBox.Show(sbShellEntry.ToString());
        SetValue(Registry.ClassesRoot, progID + @"\shell\open\command", sbShellEntry.ToString());
        StringBuilder sbDefaultIconEntry = new StringBuilder();
        sbDefaultIconEntry.AppendFormat("\"{0}\",0", assemblyFullPath);
        MessageBox.Show(sbDefaultIconEntry.ToString());
        SetValue(Registry.ClassesRoot, progID + @"\DefaultIcon", sbDefaultIconEntry.ToString());

        // 新建应用程序子键
        SetValue(Registry.ClassesRoot, @"Applications\" + Path.GetFileName(assemblyFullPath), "", "NoOpenWith");
        MessageBox.Show(@"Applications\" + Path.GetFileName(assemblyFullPath));
    }

    private static void SetValue(RegistryKey root, string subKey, object keyValue)
    {
        SetValue(root, subKey, keyValue, null);
    }
    private static void SetValue(RegistryKey root, string subKey, object keyValue, string valueName)
    {
        bool hasSubKey = ((subKey != null) && (subKey.Length > 0));
        RegistryKey key = root;

        try
        {
            if (hasSubKey) key = root.CreateSubKey(subKey);
            key.SetValue(valueName, keyValue);
        }
        finally
        {
            if (hasSubKey && (key != null)) key.Close();
        }
    }
}            

整体思路还是很清楚的,先新建一个类,然后里面定义SetFileAssociation这个静态方法,在这个方法里面:
1.新建扩展名子键
2.新建progID子键,这里面绑定打开的方式以及用这种打开方式的图标,我们可以从代码里看到绑定的是目前程序集所在的位置,很合理对不对?这里面用了反射,不像很久以前的程序一样使用的是绝对路径了,大赞!
3.新建应用程序子键,让其它文件也可以找到用这种方式来打开!

怎么样?应该还算挺容易理解的吧!哈哈哈