【问题标题】:Process.Start returns nullProcess.Start 返回 null
【发布时间】:2010-08-11 07:55:50
【问题描述】:

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

    string FolderSelected = "";
    string FileName = "";
    Process proc;

    List<string> FilesDisplayed = new List<string>();

    public Form1()
    {
        InitializeComponent();
    }

    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


    【解决方案1】:

    编辑:感谢 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 图像查看器,而不是创建一个新进程。

    【讨论】:

    • static Process Start(ProcessStartInfo startInfo) 可以返回 null,如果进程没有启动(或已经启动)。
    • 我需要覆盖此行为,因为我想在打开新文件之前关闭最后打开的文件。我该怎么做?
    • @gash25:我不认为你可以。您可以使用ProcessStartInfo 并将UseShellExecute 设置为false,但我怀疑这只会使其无法启动。如果您知道应该使用哪个进程,则可以显式启动该可执行文件。
    • 谢谢,但是找出哪个进程的开销太大了。我只需要一个简单的随机打开和关闭文件程序。
    【解决方案2】:

    要解决此问题,您必须将 UseShellExecute 设置为 false 以绕过 shell。

    而不是

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

    使用

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

    【讨论】:

    • 它在我的情况下不起作用。我收到异常,说该文件不是正确的 Win32 应用程序(在我的情况下它是一个视频文件)。这仅适用于可执行文件。
    • 这不会解决问题,因为UseShellExecute主要是帮助找到应用程序来使用想要的文件(如image/pdf/doc/...)。如果它与UseShellExecute = false 一起使用,它甚至也可以与UseShellExecute = true 一起使用并以有效的进程响应。
    【解决方案3】:

    这甚至不会编译(明确的分配)。作为一个方法变量proc 仅对声明方法(/范围)是本地的——即button2_Click,这解释了为什么你不能保留值。如果proc 打算在调用之间持续存在,请将其提升为字段(每个实例变量):

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

    【讨论】:

      【解决方案4】:

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

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

      【讨论】:

        猜你喜欢
        • 2015-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        相关资源
        最近更新 更多