如何通过windows 10.x上的sdk注册windows文件扩展名



注意:这个问题不是关于dart,而是关于windows注册表。

我已经实现了一个库和工具(称为dcli),用dart语言编写cli应用程序。

当用户在命令行上输入一个dart脚本的名称时,我需要windows启动dcli并传递dart脚本和任何命令行参数。

hellow.dart a b c

将导致运行以下命令

dcli.bat hellow.dart a b c

我需要通过'C'注册表api来做到这一点(我使用它的外部函数接口(ffi)从dart调用注册表api,它允许它调用C入口点)。这部分问题已经解决了,我可以成功地从dart中添加注册表项。

我的问题是不知道该创建什么注册表设置,因为,特别是随着windows 10的出现,文档是一团糟。

到目前为止,这是我相当糟糕的尝试。


// create a ProgID for dcli 'noojee.dcli'
regSetString(HKEY_CURRENT_USER, 
r'SoftwareClassesnoojee.dcli',
defaultRegistryValueName, 'dcli');
// associate the .dart extension with dcli's prog id
regSetString(HKEY_CURRENT_USER, r'SoftwareClasses.dart',
defaultRegistryValueName, 'noojee.dcli');
regSetString(HKEY_CURRENT_USER, 
r'SOFTWAREClasses.dartOpenWithProgids',
'noojee.dcli.dart', '');
// this path doesn't look correct
regSetExpandString(
HKEY_CURRENT_USER,
r'dclishellopencommand',
defaultRegistryValueName,
'c:pathtodcli.bat  %1 %2 %3 %4 %5 %6 %7 %8 %9');

regSetString(
HKEY_CURRENT_USER,
r'SOFTWAREMicrosoftWindowsCurrentVersionExplorerFileExts.dartOpenWithList',
'a',
'dcli.bat');
regSetString(
HKEY_CURRENT_USER,
r'SOFTWAREMicrosoftWindowsCurrentVersionExplorerFileExts.dart',
'MRUList',
'a');
regSetNone(
HKEY_CURRENT_USER,
r'SOFTWAREMicrosoftWindowsCurrentVersionExplorerFileExts.dartOpenWithProgids',
'noojee.dcli');

让我困惑的一件事是HKEY_CLASSES_ROOT的使用。文档似乎说它是只读的,但接着展示了在它下面创建键的示例。

我有额外的复杂性,vscode与部分代码扩展喜欢添加自己的关联(这是没有意义的),我需要覆盖这一点,如果它存在,但理想情况下,使它在资源管理器菜单上的替代。

HKEY_CLASSES_ROOTHKEY_CURRENT_USERSoftwareClassesHKEY_LOCAL_MACHINESoftwareClasses的虚拟合并视图(在Win2000及以后版本)。它不是只读的,但写入它并不是最好的主意,因为写入通常是到机器部分,除非它不在机器部分。

FileExts键没有文件,不要写

在你的代码中,r'dclishellopencommand'是不正确的,类键中的第一个组件应该是扩展指向的progid,试试r'SOFTWAREClassesnoojee.dclishellopencommand'

它基本上是这样的:

  • HKEY_CURRENT_USERSoftwareClasses.myext=myprogid
  • HKEY_CURRENT_USERSoftwareClassesmyprogidshellverbcommand="c:pathapp.exe" "%1"(其中%1被文件路径取代,%2仅用于打印机)。

感谢@Anders,我达到了以下目标:

注意:defaultRegistryValueName只是一个空字符串"。


const progIdPath = r'SoftwareClasses.dartOpenWithProgids';
if (regKeyExists(HKEY_CURRENT_USER, progIdPath)) {
regDeleteKey(HKEY_CURRENT_USER, progIdPath);
}
regCreateKey(HKEY_CURRENT_USER, progIdPath);
regSetString(HKEY_CURRENT_USER, progIdPath, 'noojee.dcli', '');
const commandPath = r'SoftwareClassesnoojee.dclishellopencommand';
if (regKeyExists(HKEY_CURRENT_USER, commandPath)) {
regDeleteKey(HKEY_CURRENT_USER, commandPath);
}
regCreateKey(HKEY_CURRENT_USER, commandPath);
regSetString(
HKEY_CURRENT_USER,
commandPath,
defaultRegistryValueName,
'"${DCliPaths().pathToDCli}" '
'"%1"%*');

唯一的问题是%*似乎没有做任何有用的事情。从医生那里,我发现它应该扩展任何不。但是我只得到8个参数(因为%1是命令本身)和"%1"产生与"%1"%*

相同的结果。