【发布时间】:2016-05-08 08:35:58
【问题描述】:
Windows shell 允许通过扩展名将文件类型与某个应用程序相关联。此关联通常提供ShellNew 命令,该命令允许使用应用程序提供的默认模板创建给定类型的新文件。当您在 Windows 资源管理器的上下文菜单中选择 New 时,它会提供不同文件类型的选择,可以通过这种方式创建。我想从我的 C# 应用程序中实现此操作。
如下打开现有文件很简单。
System.Diagnostics.ProcessStartInfo psi =
new System.Diagnostics.ProcessStartInfo(path);
psi.UseShellExecute = true;
System.Diagnostics.Process.Start(psi);
如果您传递现有文件的任何有效路径,并为外壳“打开”命令注册了扩展名,它将在其默认应用程序中打开给定文件。
例如,传递path = "text.txt",记事本会为您打开“text.txt”。
但是,我找不到以类似方式创建新文件的代码。
例如,Microsoft Word 是“新建”命令的注册应用程序。我可以直接从 Windows 资源管理器中使用默认模板创建新的 MS Word 文档,而无需打开 MS Word。我想在我的 C# 应用程序中做同样的事情:创建新的 MS Word 文件而不链接到 MS Word 自动化。
我确信可以为 Windows shell 中的“新建”命令正确注册的任何文件类型执行此操作。但奇怪的是,我尝试过的所有标准搜索都没有涵盖这个主题。
建议的解决方案
在绝望地找到任何现成的代码 sn-p 之后,我编写了这个函数来从注册表中提取信息。它从请求的新文件的完整路径获取文件扩展名。然后它找到给定扩展的关联类信息,并从“ShellNew”子键中提取“FileName”值。最后,它将一个模板从注册表中找到的路径复制到新文件的目标位置。
public static bool CreateFileOfKnownType(string path)
{
try
{
string extension = System.IO.Path.GetExtension(path);
if (string.IsNullOrEmpty(extension)) return false;
using (var rExt = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(extension))
{
string[] apps = rExt.GetSubKeyNames();
foreach (string app in apps)
{
if (app.Contains("."))
{
string shellNew = apps[0] + "\\ShellNew";
using (Microsoft.Win32.RegistryKey rApp = rExt.OpenSubKey(shellNew))
{
string newFileTemplate = rApp.GetValue("FileName").ToString();
System.IO.File.Copy(newFileTemplate, path);
return true;
}
}
}
}
return false;
}
catch { return false; }
}
当“文件名”包含应用程序模板的完整路径时,此代码在某些情况下可以正常工作。但是,在其他情况下,“文件名”仅包含模板的文件名,没有完整路径。然后这段代码失败了。如果有人知道可以普遍使用的改进方法,将不胜感激。
【问题讨论】:
-
提供了一个额外的信息,以便听起来更准确,因为之前的讨论中揭示了一些混乱。
-
我在这里找到了有用的信息。它描述了如何获取符合“新建”命令的所有文件扩展名的列表:social.msdn.microsoft.com/Forums/vstudio/en-US/…