SonFra
SonFra

Reputation: 3

Cannot run a .exe file from windows form - Visual Studio

I have build a simple windows form where when i press a button run a process indicated in a TextBox

I have tried with this code

Try
    System.Diagnostics.Process.Start(TextBox1.Text)
Catch ex As Exception
    MsgBox("Error")
End Try

Code works, but I don't understand why I canno't run a .exe genereted from a compiled c project using gcc (which is my goal).

I have tried to execute as Administrator too.

Someone can explain me?

Upvotes: 0

Views: 878

Answers (2)

SonFra
SonFra

Reputation: 3

I post here the code who I have written in Button click event. Maybe can be useful for someone

Try
    Dim startInfo As New ProcessStartInfo
    startInfo.UseShellExecute = True
    startInfo.WorkingDirectory = "C:\workDirectory"
    startInfo.FileName = TextBox1.Text
    System.Diagnostics.Process.Start(startInfo)
Catch ex As Exception
    MsgBox("Error")
End Try

Thanks @Dai for help

Upvotes: 0

Dai
Dai

Reputation: 155608

(Converting my comment to an answer)

Code works, but I don't understand why I canno't run a .exe genereted from a compiled c project using gcc (which is my goal).

I suspect the problem is that your gcc-compiled executable has runtime dependencies on files located in the same filesystem directory as your gcc-compiled executable and it references those files only by their short-names (e.g. "someFile.txt") instead of by their absolute-path filenames (e.g. "C:\my-gcc-program\bin\someFile.txt") then the OS looks inside that process' Working Directory (aka Current Directory).

Note that when your program uses Process.Start(String fileName) then the newly created (child) OS process inherits your process's Working Directory rather than it being reset to the new process' executable's filename's parent directory!

So if your child process expects "someFile.txt" to be in its working-directory then you need to launch the child-process with the correct working-directory instead of it inheriting it from your process.

You can do this in 2 different ways, both of which require you to use ProcessStartInfo instead of any of the Process.Start overloads that accept String fileName.

Option 1: Set ProcessStartInfo.WorkingDirectory directly:

ProcessStartInfo psi = new ProcessStartInfo()
{
    FileName = @"C:\my-gcc-program\bin\program.exe",
    WorkingDirectory = @"C:\my-gcc-program\bin",
}

using( Process p = Process.Start( psi ) )
{
    p.WaitForExit();
}

Option 2: Use ProcessStartInfo.UseShellExecute;

The UseShellExecute option creates the new process as though the user started it through their OS shell, such as cmd.exe or Explorer.exe rather than as a child process of your process. (One of the many) effects of this option is that the OS handles setting the Working-directory of this new process automatically for you.

Note that in .NET Framework, this is true by default - but false in .NET Core (and will cause errors if used in UWP). Because it's not true by default in .NET Core you should set it explicitly if you're depending on it to work on all platforms besides UWP.

Note that when using UseShellExecute == true, you still must provide a valid WorkingDirectory path, however its purposes changes:

  • The WorkingDirectory property behaves differently when UseShellExecute is true than when UseShellExecute is false.
    • When UseShellExecute is true, the WorkingDirectory property specifies the location of the executable.
      • If WorkingDirectory is an empty string, the current directory is understood to contain the executable.
      • When UseShellExecute is true, the working directory of the application that starts the executable is also the working directory of the executable.
    • When UseShellExecute is false, the WorkingDirectory property is not used to find the executable. Instead, its value applies to the process that is started and only has meaning within the context of the new process.
ProcessStartInfo psi = new ProcessStartInfo()
{
    FileName = @"program.exe",
    WorkingDirectory = @"C:\my-gcc-program\bin",
    UseShellExecute = true
}

using( Process p = Process.Start( psi ) )
{
    p.WaitForExit();
}

Upvotes: 1

Related Questions