繁体   English   中英

如何在C中与外部文本编辑器进行交互

[英]How to interact with an external text editor in C

我正在用C(Linux环境)开发命令行应用程序,以编辑特定的文件格式。 此文件格式是纯XML文件,先压缩后再加密,然后再加密签名。

我想为用户提供一个选项,以一种简单的方式来编辑此类文件,而无需手动提取文件,对其进行编辑,然后对其进行压缩,加密和签名的麻烦。

理想情况下,在调用时,我的应用程序应执行以下操作:

  1. 打开加密/压缩的文件并将其解压缩到一个临时位置(如/tmp
  2. 调用一个外部文本编辑器,例如nanosublime-textgedit这取决于安装的安装程序以及用户的偏好。 等待用户编辑文件并关闭文本编辑器。
  3. 读取修改后的临时文件并加密/压缩,以替换旧的加密/压缩文件

我怎样才能获得要点。 2?

我考虑过使用system()调用nano并等待其返回,或者将inotify()放在临时文件上以了解图形文本编辑器何时对其进行了修改。

哪种解决方案更好? 如何调用用户的默认文本编辑器? 还有什么可以做的更好的方法吗?

首先,考虑不要自己编写一个实际的应用程序或包装程序,后者会调用另一个编辑器,而是为一些现有的编辑器编写某种插件,该插件足够灵活以支持其他格式并通过解压缩传递其输入。

当然,这不是唯一的解决方案,但是对您来说可能更容易。

使用您的特定方法,您可以:

  • 使用EDITOR和/或VISUAL命令行变量 (也由@KamilCuk指出)来确定要使用的编辑器。
  • 将编辑器作为子进程运行,以便您知道何时结束执行,而不必与之通信。 通知文件更改,甚至打开或关闭文件的更改,还不够好,因为编辑器可能会更改多个文件,有些编辑器甚至在您在其中处理文件时甚至没有打开文件。
  • 请记住处理未出现编辑器的情况; 或悬挂 或者您收到通知以停止等待编辑器;或者 等等

调用一个外部文本编辑器,例如nano或sublime-text或gedit,这取决于安装的安装程序以及用户的偏好。 等待用户编辑文件并关闭文本编辑器。

有趣的问题。 使用用户的默认编辑器打开xml文件的一种方法是使用xdg-open ,但是它没有提供应用程序的pid ,用户可以在其中编辑文件。

您可以使用xdg-mime query default application/xml来查找默认编辑器的.desktop文件,但是随后您必须解析此文件以找出程序的可执行路径-这正是xdg-open实际工作的方式 ,在search_desktop_file()函数中,仅从*.desktop提取以Exec=条目开头的行,以调用编辑器可执行文件并将目标文件作为参数传递...我想说的是,在找到编辑器可执行文件,您可以启动它,然后等待它关闭,然后检查文件内容是否已更改。 好吧,这看起来像很多不必要的工作...

而是可以尝试使用固定的知名编辑器(例如gedit )来实现所需的工作流程。 您还可以为用户提供一种方法(即提示或配置文件)来设置默认的xml编辑器,即/usr/bin/sublime_text ,然后可以在下次运行时在您的程序中使用它。

但是,关键是要打开一个阻止调用过程的编辑器,直到用户关闭该编辑器为止。 关闭编辑器后,您可以简单地检查文件是否已更改,如果已更改,请执行进一步的操作。

要找出文件内容是否已修改,可以在打开文件之前使用stat系统调用获取文件的inode change time ,然后在关闭时将时间戳记值与当前值进行比较。

即:

stat -c %Z filename

输出: 1558650334

包起来:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

void execute_command(char* cmd, char* result) {
  FILE *fp;
  fp = popen(cmd, "r");
  fscanf (fp, "%s" , result);
}

int get_changetime(char* filename) {
  char cmd[4096];
  char output[10];
  sprintf(cmd, "stat -c %%Z %s", filename);
  execute_command(cmd, output);
  return atoi(output);
}

int main() {
  char cmd[4096];
  char* filename = "path/to/xml-file.xml";

  uint ctime = get_changetime(filename);

  sprintf(cmd, "gedit %s", filename);
  execute_command(cmd, NULL);

  if (ctime != get_changetime(filename)) {
      printf("file modified!");
      // do your work here...
  }

  return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM