Process.Start 返回 null

问题描述 投票:0回答:5

我正在编写一个程序,在 s 目录中启动一个随机文件。文件可以是任何类型,但主要是视频或图像文件。 每次启动一个文件时,我都想关闭之前打开的文件。

代码:

string FolderSelected = "";
string FileName = "";
Process proc;
            
List<string> FilesDisplayed = new List<string>();

private void button2_Click(object sender, EventArgs e)
{
    if (FolderSelected == string.Empty)
        FolderSelected = Properties.Settings.Default.FilesDefaultFolder;

    if (proc != null)
    {
        proc.CloseMainWindow();
        proc.Close();
    }
    FileName = FetchRandomFile();
    proc = Process.Start(FileName);
}

问题是,我不断收到

proc = null
(文件已正确启动),并且我无法获取以前打开的进程以关闭它。我知道 .NET 重用进程,这就是它返回 Null 的原因,但我需要重写此行为。

c# process
5个回答
16
投票

编辑:感谢leppie的评论,我怀疑我知道答案:我的猜测是你正在“启动”类似图像的东西,并且它正在重用现有的进程来打开文档而不是创建新的进程。

我用这个简单的测试应用程序重现了这个:

using System;
using System.Diagnostics;

public class Test
{
    static void Main()
    {
        Process proc = Process.Start("image.tif");
        Console.WriteLine(proc == null);
    }
}

这会打印“true”,因为它使用

dllhost.exe
来托管 Windows 图像查看器,而不是创建新进程。


1
投票

要解决此问题,您必须将

UseShellExecute
设置为 false 以绕过 shell。

而不是

Process.Start("filename", "args")

使用

Process.Start(new ProcessStartInfo() {
    FileName = "filename",
    Arguments = "args",
    UseShellExecute = false
});

0
投票

您在方法范围内声明“proc”,因此当在该方法的顶部检查时,它当然会始终为空。如果您希望引用存在于函数之外,请将其声明为类级别变量。

您每次(可能)都会生成一个进程,Process.Start 不会返回 null,但当 i 超出范围时,您只是丢失了对它的引用。


0
投票

这甚至无法编译(明确的分配)。作为一个 方法变量

proc
仅对于声明方法(/作用域)是本地的 - 即
button2_Click
,这解释了为什么你不能保留值。如果
proc
旨在在调用之间持续存在,请将其提升为 field(每个实例变量):

Process proc;
private void button2_Click(object sender, EventArgs e)
{
    if (proc != null)
    ...

0
投票

到目前为止这对我有用。已经尝试过图像和视频。不知道检查文件名的方法是否适用于每个实例,因此我在拥有进程 ID 时使用它。

就我而言,如果 GetProcess 错过了正在运行的进程,那也没什么大不了的,所以对我来说没关系。

public class ProcessFinder
{
    public virtual Process GetProcess(int processId)
    {
        return Process.GetProcesses().FirstOrDefault(p => p.Id == processId);
    }

    public virtual Process GetProcess(string fileName)
    {
        return Process.GetProcesses().FirstOrDefault(p => p.MainWindowTitle.StartsWith(fileName));
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.