C# 实现文件关联

转摘地址:http://blog.csdn.net/snaill/article/details/5073853

和其他语言一样,C#实现文件关联同样需要直接操作注册表,即按规则分别设置文件扩展名,文档类型说明,友好名称,图标,调用方法等键值即可,网上随便查查就可以写出以下的代码。

using Microsoft.Win32;

RegistryKey key = Registry.ClassesRoot.OpenSubKey(".jb");
if (key == null)
{
    key = Registry.ClassesRoot.CreateSubKey(".jb");
    key.SetValue("", "Jeebook.Reader.jb");
    key.SetValue("Content Type", "application/jb");

    key = Registry.ClassesRoot.CreateSubKey("Jeebook.Reader.jb");
    key.SetValue("", "Jeebook Document");

    RegistryKey keySub = key.CreateSubKey("DefaultIcon");
    keySub.SetValue("", System.Windows.Forms.Application.StartupPath + "Jeebook.ico");
    keySub = key.CreateSubKey("shell//open//command");
    keySub.SetValue("", "/"" + System.Windows.Forms.Application.ExecutablePath + "/" /"%1/"");
}

相对来说,C#实现比较麻烦的是图标路径,一般文件类型注册的都是执行文件的资源,格式如下:

格式:<执行程序exe路径>,<资源ID>   // 资源ID为正数,表示资源的索引号,否则为资源ID

在C++中很容易获取资源ID,但C#中还没搞清楚如何取道资源的ID,所以索性在程序执行目录下附带一个图标文件用于注册,这样倒也方便随时修改:)

此外,就是如何验证图标是否设置正确。现在的系统超爱缓存,除非LOG OFF级别的操作,否则手工修改注册表很难马上响应,当然通过程序调用应该刷新系统状态,这个下次有时间再研究吧

如果只是用于XP以下的程序,以上的代码就已经足够了。可惜的是,Vista以后引入了UAC,上面的代码在UAC下会弹出异常,这肯定不是我们希望的。

一种解决方法是通过创建一个Mainifest文件,添加以下脚本:










这样程序图标上会出现一个小盾牌,表示该程序需要在管理员模式下运行,每次运行都会自动弹出UAC的验证窗口。但这个对某些只是需要书写一次注册表的程序来说,每次都弹出提示是无法忍受的,那么如何能够通过代码弹出UAC验证窗口呢?

Google的结果,貌似没有在运行中触发提示并将进程改变为管理员模式的办法,不过只要在执行进程时将Verb设置为runas就可以自动触发UAC验证,使被调用的程序在管理员模式下运行。那么,只要在程序中重新启动自己就可以达到触发UAC验证窗口的目的,代码如下:

System.Diagnostics.ProcessStartInfo start = new System.Diagnostics.ProcessStartInfo();
System.Diagnostics.Process p = new System.Diagnostics.Process();
start.WorkingDirectory = System.Windows.Forms.Application.StartupPath;
start.Verb = "runas";
start.FileName = System.Windows.Forms.Application.ExecutablePath;
System.Diagnostics.Process.Start(start);

当然,如果你将上面的代码直接放入你的FormLoad中,那将是场灾难,因为你的程序会不断的启动自己直到把你的机器资源耗光为止。所以我们还需要有能够判断是否已经进入管理员模式的代码,如下:

WindowsIdentity wi = WindowsIdentity.GetCurrent();
WindowsPrincipal wp = new WindowsPrincipal(wi);

if (!wp.IsInRole(WindowsBuiltInRole.Administrator))

wi代表的是当前用户,WindowsBuiltInRole.Administrator是管理员的标识符(比较奇怪的是VB好像有自己特殊的名字空间来实现以上的功能,不知为什么,当然我们用标准的方法判断也没什么不好)

由此将以上所有的代码整合起来,得到以下的结果:

if ( null != Registry.ClassesRoot.OpenSubKey(".jb") )
    return;

WindowsIdentity wi = WindowsIdentity.GetCurrent();
WindowsPrincipal wp = new WindowsPrincipal(wi);

if (!wp.IsInRole(WindowsBuiltInRole.Administrator))
{
    System.Diagnostics.ProcessStartInfo start = new  
    System.Diagnostics.ProcessStartInfo();
    System.Diagnostics.Process p = new System.Diagnostics.Process();
    start.WorkingDirectory = System.Windows.Forms.Application.StartupPath;
    start.Verb = "runas";
    start.FileName = System.Windows.Forms.Application.ExecutablePath;
    System.Diagnostics.Process.Start(start);
    Application.Exit();
    return;
}

RegistryKey key = Registry.ClassesRoot.OpenSubKey(".jb");
if (key == null)
{
    key = Registry.ClassesRoot.CreateSubKey(".jb");
    key.SetValue("", "Jeebook.Reader.jb");
    key.SetValue("Content Type", "application/jb");

    key = Registry.ClassesRoot.CreateSubKey("Jeebook.Reader.jb");
    key.SetValue("", "Jeebook Document");

    RegistryKey keySub = key.CreateSubKey("DefaultIcon");
    keySub.SetValue("", System.Windows.Forms.Application.StartupPath + "Jeebook.ico");
    keySub = key.CreateSubKey("shell//open//command");
    keySub.SetValue("", "/"" + System.Windows.Forms.Application.ExecutablePath + "/" /"%1/"");
}

文件关联是个很常用很简单的功能,但真要做的好,还得费点功夫啊:)


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值