【问题标题】:Open and close image in default image viewer在默认图像查看器中打开和关闭图像
【发布时间】:2021-01-16 00:58:12
【问题描述】:

我正在尝试创建一个简短的方法,在默认图像查看器中打开图像,并在 time 毫秒后关闭它。

现在看起来是这样的:

    public static async void OpenImage(string path, int time)
    {
        var process = new Process();
        process.StartInfo.FileName = path;
        process.Start();
        await Task.Delay(time);
        process.Kill()
        process.Close()
    }

我可以看到图像,但随后process.Kill() 抛出InvalidOperationException,“没有进程与此对象关联。”

我错过了什么还是有其他方法可以做到这一点?


更新:

现在也测试了这个:

    public static async void OpenImage(string path, int time)
    {
        var process = Process.Start(path)
        await Task.Delay(time);
        process.Kill()
        process.Close()
    }

然后Process.Start() 返回null。所以也许我必须像 faljbour 评论的那样直接致电.exe

【问题讨论】:

  • 我认为你的进程在你调用 kill 之前就终止了,如果你删除了 kill() 和 close(),你的异常可能会消失
  • 但是它永远不会关闭?我仍然可以看到图像查看器是打开的,所以在我调用 kill() 之前它并没有关闭。这就是为什么我对这个异常有点困惑。
  • 能否发布调用此 OpenImage 方法的代码,我想看看路径中的内容。
  • 发帖有点长,但是路径只是我电脑上一张图片的正常路径,例如“C:\SomeFolder\image.png”
  • 但是你想杀死什么可执行文件。您必须使用可执行文件来显示图像

标签: c# process


【解决方案1】:

这里的问题是你并没有真正启动一个进程,而是将一个文件路径传递给 Windows Shell (explorer.exe) 来处理。 shell 计算出如何打开文件并 it 启动进程。

当这种情况发生时,您的代码不会取回进程 ID,因此它不知道要杀死哪个进程。

您应该做的是找到该文件的默认应用程序,然后显式启动该应用程序(而不是让 shell 找出它)。

找到文件的默认应用程序我能想到的最简洁的方法是使用 Win32 API FindExecutable()


当默认应用程序包含在 dll 中时,事情会有些复杂。默认的 Windows 照片查看器 (C:\Program Files (x86)\Windows Photo Viewer\PhotoViewer.dll) 就是这种情况。由于它不是exe,因此您无法直接启动它,但是可以使用rundll32 启动应用程序。


这应该适合你:

[DllImport("shell32.dll")]
static extern int FindExecutable(string lpFile, string lpDirectory, [Out] StringBuilder lpResult);

public static async void OpenImage(string imagePath, int time)
{
    var exePathReturnValue = new StringBuilder();
    FindExecutable(Path.GetFileName(imagePath), Path.GetDirectoryName(imagePath), exePathReturnValue);
    var exePath = exePathReturnValue.ToString();
    var arguments = "\"" + imagePath + "\"";

    // Handle cases where the default application is photoviewer.dll.
    if (Path.GetFileName(exePath).Equals("photoviewer.dll", StringComparison.InvariantCultureIgnoreCase))
    {
        arguments = "\"" + exePath + "\", ImageView_Fullscreen " + imagePath;
        exePath = "rundll32";
    }

    var process = new Process();
    process.StartInfo.FileName = exePath;
    process.StartInfo.Arguments = arguments;

    process.Start();

    await Task.Delay(time);

    process.Kill();
    process.Close();
}

此代码演示了这个概念,但如果您想满足更多具有不寻常参数格式的默认应用程序(如photoviewer.dll 所示),您应该搜索registry yourself 或使用第三方库找到正确的命令要使用的行。

例如,

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 2013-07-23
    • 2015-12-31
    相关资源
    最近更新 更多