Home > Net >  How to start a process that is a resource?
How to start a process that is a resource?

Time:12-07

I add my test.bat as a resource via resx. I then try

proc.StartInfo.FileName = myNamespace.Properties.Resources.test;

but it says

System.ComponentModel.Win32Exception: The system cannot find the file specified.'

How can I fix this?

Here is my full code:

public async void button_A_Click(object sender, EventArgs e)
        {
            button_A.Enabled = false;
            await Task.Run(() => {
                var proc = new Process();
                proc.StartInfo.FileName = LOS_Installer.Properties.Resources.test;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.Arguments = path;
                if (proc.Start())
                {
                    void outputCallback(string data)
                    {
                        textBoxLog.AppendText(data);
                        textBoxLog.AppendText(Environment.NewLine);
                    }
                    proc.OutputDataReceived  = (_, e) => Invoke(outputCallback, e.Data);
                    proc.ErrorDataReceived  = (_, e) => Invoke(outputCallback, e.Data);
                    proc.BeginOutputReadLine();
                    proc.BeginErrorReadLine();

                }
                proc.WaitForExit();
            });
            button_A.Enabled = true;
        }

Minor question: it seems that the resource manager doesn't care about file's extension. So what if I have 2 files with the same name yet different extensions?

CodePudding user response:

There are a few potential causes for this error, and the solution will depend on the specific details of your project. Here are a few things you can try:

Make sure that the file you are trying to run is actually included as a resource in your project. You can check this by looking for the file in the Solution Explorer window in Visual Studio. If it is not there, you will need to add it as a resource to your project.

Make sure that the file you are trying to run is marked as an "Embedded Resource" in your project. By default, files added as resources are marked as "Content" files, which are not compiled into the assembly and are not accessible at runtime. To fix this, right-click on the file in the Solution Explorer window and select "Properties." In the Properties window, set the "Build Action" property to "Embedded Resource."

When you specify the path to the file, you need to use the correct syntax to access the resource. The correct syntax is myNamespace.Properties.Resources.test. Note that the name of the resource (in this case, "test") is not case-sensitive, but the namespace and class names are.

If you are still having trouble, you can try using the GetObject method of the ResourceManager class to get the resource as a Stream object, and then use the Stream.ReadToEnd method to read the contents of the file into a string. You can then use the StartInfo.Arguments property of the Process object to pass the contents of the file as an argument to the program you are trying to run.

As for your minor question, it is possible to have multiple resources with the same name but different extensions in a project. However, the ResourceManager class does not provide any built-in way to differentiate between them. If you need to access a specific resource with a specific extension, you will need to use a different approach, such as the one described in the previous paragraph.

CodePudding user response:

public async void button_A_Click(object sender, EventArgs e)
{
    button_A.Enabled = false;
    await Task.Run(() => {
        var proc = new Process();

        // Write the contents of the "test.bat" file to a temporary file
        string tempFile = Path.GetTempFileName();
        File.WriteAllText(tempFile, LOS_Installer.Properties.Resources.test);

        // Use the path to the temporary file as the FileName for the Process object
        proc.StartInfo.FileName = tempFile;
        proc.StartInfo.RedirectStandardOutput = true;
        proc.StartInfo.RedirectStandardError = true;
        proc.StartInfo.CreateNoWindow = true;
        proc.StartInfo.Arguments = path;
        if (proc.Start())
        {
            void outputCallback(string data)
            {
                textBoxLog.AppendText(data);
                textBoxLog.AppendText(Environment.NewLine);
            }
            proc.OutputDataReceived  = (_, e) => Invoke(outputCallback, e.Data);
            proc.ErrorDataReceived  = (_, e) => Invoke(outputCallback, e.Data);
            proc.BeginOutputReadLine();
            proc.BeginErrorReadLine();

        }
        proc.WaitForExit();

        // Clean up the temporary file
        File.Delete(tempFile);
    });
    button_A_Click.Enabled = true;
}
  • Related