20

I'm writing a program that launches a random file in s directory. the file can be of any type, but mostly video or image files. Each time I launch a file I want to close the previous opened one.

Code :

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);
}

Problem is, that I keep getting proc = null (the file is launched properly) and I cannot fetch the previously opened process in order to close it. I know that .NET reuses processes and that's why it returns Null but I need to override this behavior.

BeRT2me
  • 12,699
  • 2
  • 13
  • 31
gash25
  • 297
  • 1
  • 3
  • 8

4 Answers4

16

EDIT: Thanks to leppie's comment, I suspect I know the answer: my guess is that you're "starting" something like an image, and it's reusing an existing process to open the document instead of creating a new one.

I've reproduced this with this simple test app:

using System;
using System.Diagnostics;

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

This prints "true" because it's using dllhost.exe to host the Windows Image Viewer, rather than creating a new process.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 4
    `static Process Start(ProcessStartInfo startInfo)` can return `null`, if the process didn't start (or is already started). – leppie Aug 11 '10 at 08:15
  • 1
    I need to override this behavior, because i want to close the last opened file before opening a new one. how can i do this? – gash25 Aug 11 '10 at 08:36
  • 2
    @gash25: I don't *think* you can. You can use a `ProcessStartInfo` with `UseShellExecute` set to false, but I suspect that'll just make it fail to start. If you know which process should be used, you could explicitly start that executable. – Jon Skeet Aug 11 '10 at 08:40
  • thanks, But finding out which process is too much of a overhead. i just need a simple random open and close file program. – gash25 Aug 11 '10 at 08:47
1

To fix this problem, you have to set UseShellExecute to false to bypass the shell.

Instead of

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

use

Process.Start(new ProcessStartInfo() {
    FileName = "filename",
    Arguments = "args",
    UseShellExecute = false
});
Nubok
  • 3,502
  • 7
  • 27
  • 47
Despertar
  • 21,627
  • 11
  • 81
  • 79
  • 3
    It doesn't work in my case. I'm getting exception which says that the file is not a correct Win32 application (in my case it's a video file). This works only with executables. – P.W. Nov 18 '14 at 19:00
  • This will not solve the problem in case `UseShellExecute` will mainly assist to find the application to use the wanted file (like image/pdf/doc/...). If it works with `UseShellExecute = false` it even will also work with `UseShellExecute = true` and respond with a valid process. – Nasenbaer Jul 27 '18 at 13:24
0

You are declaring 'proc' at method scope, so of course it will always be null when checked at the top of that method. If you want the reference to live beyond the function, declare it is a class level variable.

You are spawning a process each time (probably), Process.Start is not returning null, but you simply lose the reference to it when i goes out of scope.

Ed S.
  • 122,712
  • 22
  • 185
  • 265
0

That won't even compile (definite assignment). As a method variable, proc is local only to the declaring method(/scope) - i.e. button2_Click, which explains why you can't retain values. If proc is meant to persist between calls, promote it to a field (per-instance variable):

Process proc;
private void button2_Click(object sender, EventArgs e)
{
    if (proc != null)
    ...
Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900