Reputation: 3044
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?
Upvotes: 0
Views: 168
Reputation: 9383
If embedded test.bat
contains this text:
@echo off
title Testing...
echo Lorem ipsum is placeholder text commonly used in
echo the graphic, print, and publishing industries for
echo previewing layouts and visual mockups.
pause
and the objective is to run it programmatically...
... from an embedded resource:
Then here's one way to copy it to a tmp file and run it (see explanation in the comments).
public MainForm()
{
InitializeComponent();
buttonRunBatch.Click += runFromEmbedded;
}
private void runFromEmbedded(object sender, EventArgs e)
{
var asm = GetType().Assembly;
// Obtain the full resource path (different from a file path).
var res =
asm
.GetManifestResourceNames()
.Where(_ => _.Contains("Scripts.test.bat"))
.FirstOrDefault();
// Make path for a temporary file
var tmp = Path.Combine(Path.GetTempPath(), "tmp.bat");
// Get the byte stream for the embedded resource...
byte[] bytes;
using (var stream = asm.GetManifestResourceStream(res))
{
bytes = new byte[stream.Length];
stream.Read(bytes, 0, (int)stream.Length);
}
// ... and write it to the tmp file
using (FileStream fileStream = new FileStream(tmp, FileMode.Create))
{
try
{
fileStream.Lock(0, bytes.Length);
fileStream.Write(bytes, 0, bytes.Length);
}
catch (Exception ex)
{
Debug.Assert(false, ex.Message);
}
finally
{
fileStream.Unlock(0, bytes.Length);
}
}
// RUN the bat file.
var process = Process.Start(fileName: tmp);
SetForegroundWindow(process.MainWindowHandle);
process.WaitForExit();
// Clean up.
File.Delete(tmp);
}
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
Upvotes: 1