C# Pass FILE STREAM to EXE file - c#

I have an a FILE STREAM that I want to pass to an EXE to be processed. Is this possible?
using (FileStream fs = File.Create(path))
{
Addfile(fs, fileinmemory.ToString());
}
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.Arguments = Addfile //filestream from above
p.StartInfo.FileName = "load.exe"; //used withabove argument to be passed into exe
p.Start();
p.WaitForExit();

simple :
mempry mapped files.
http://blogs.msdn.com/b/salvapatuel/archive/2009/06/08/working-with-memory-mapped-files-in-net-4.aspx

I don't believe this is possible, not directly through the command line.
The arguments expected are command line arguments, normally in C# and C based applications this would be a string[].
If you were to use a file that was accessible to both processes you would need to pass the file path (or have a pre-agreed file location), then you could use that, but this is not the same as passing in a stream to an executable.

You can create the file physically and pass it's path, or you can create a memory mapped file for exchange

Related

forcing to close a file

I have file that another process using it.
and I want to force closing the file. so that I will work on the fill.
I tried to use Handle.exe however it didn't find the process
would appreiciate some help here is my code:
Process tool = new Process();
tool.StartInfo.FileName = handlPath;
tool.StartInfo.Arguments = _pathDirectory + " /accepteula";
tool.StartInfo.UseShellExecute = false;
tool.StartInfo.RedirectStandardOutput = true;
tool.Start();
tool.WaitForExit();
string outputTool = tool.StandardOutput.ReadToEnd();
string matchPattern = #"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";
foreach (Match match in Regex.Matches(outputTool, matchPattern))
{
Process.GetProcessById(int.Parse(match.Value)).Kill();
}
I'm sure, that if a program really holds an exclusive access to a file, it has a reason to do it. For example, Windows Explorer holds it when the file is in copying process.
Very often, programs open a file for a writing, but do not actively write to it. For example, when you open a document in MS Word, it is copied to the temp file and a source file is just "open for writing". You'll still have an exception if you use standard File.Open method, but you can copy it to a temp file using File.Copy.
Alternatively, you can explicitly specify FileShare.ReadWrite parameter and get an access to a file. In this case, other program will have problems with accessing a file.
If you have mentioned the file name or type it would have been more easier, anyway try using the cmd for this. Get the process name and replace ProcessName.exe of the following code.
First you'll have to add using System.Diagnostics; on top.
Process.Start("cmd.exe", "/c taskkill /F /IM ProcessName.exe");

Print multiple images using Process.StartInfo.Verb=“print” command

I am using this code for print with windows print pictures...
string fileName = #"C:\Images\12.jpg";
var p = new Process();
p.StartInfo.FileName = fileName;
p.StartInfo.Verb = "Print";
p.Start();
I want to open multiple images from directory into this, how can i do it?
I tried this code, but does not work:
var p = new Process();
DirectoryInfo d = new DirectoryInfo(#"Directory address");
FileInfo[] Files = d.GetFiles("*.jpg");
foreach (FileInfo file in Files)
{
p.StartInfo.FileName += file.FullName.ToList();
p.StartInfo.Verb = "Print";
p.Start();
}
From your code example, it appears you want to simply invoke separate "print" verb commands for each file. If so, then you should be able to accomplish that by simply assigning the file name in your loop, instead of enumerating the characters of the file name and appending that to the FileName property:
DirectoryInfo d = new DirectoryInfo(#"Directory address");
FileInfo[] Files = d.GetFiles("*.jpg");
ProcessStartInfo psi = new ProcessStartInfo();
psi.Verb = "Print";
foreach (FileInfo file in Files)
{
psi.FileName = file.FullName;
Process.Start(psi);
}
Note that you can't reuse a single Process object for this purpose. Once a given Process object has been started, it can't be started again. But you can reuse a ProcessStartInfo object, starting a new process with each iteration of the loop.
EDIT:
From your comment:
I do not want to simply invoke separate "print" verb commands for each file...I want to add all files in one "print" verb command
This is not possible using the Process class. By definition, the DDE "print" verb (i.e. "command") handles only a single document. If you are willing to do a lot of extra work, you can write your own DDE client that attempts to use DDEEXEC to iteratively interact with a DDE server that knows how to print your image files. But a) this is a lot more work, and b) it still will only work if you happen to have a program installed that handles printing of image files via DDEEXEC (the Windows built-in support for printing images does not).
I recommend you stick with the above.
(And for future reference, if you only want to call Process.Start() once, putting it inside a loop is definitely not the way to go. Your question would have been more clear if your example code bore any resemblance at all to what you were actually trying to do. :) )

Is there a way to execute an exe stored with a temp file name?

I'm writing a native exe stored as an embedded resource to the file returned by Path.GetTempFileName. That function is desirable since it lets me ignore the implementation details that avoid the race condition. The only downside is that it returns a filename with the extension .tmp.
Process.Start opens the tmp-named-exe file in Notepad, on my system. Apparently you can specify the class and verb manually using p/invoke (see https://stackoverflow.com/a/12681219/521757). Before I do that, is there any way to accomplish the same thing using the .NET framework?
I think it is possible.. set the Process.StartInfo.UseShellExecute property to False prior to starting the process, e.g.:
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.FileName = #"c:\tmp\a123.tmp";
p.StartInfo.UseShellExecute = false;
p.Start();
This will start the process directly and the file should be considered to be executable itself. Does it work for you?
Why don't you use Path.GetRandomFileName() in conjunction with Path.GetTempPath()?
This way you still have a unique temporary file and path name and you can append '.exe', eliminating the current problem that you have with executing a file with a '.tmp' extension.
As a sideline, I hope that you remember to delete the temporary files after you have used them, especially when using Path.GetTempFileName(), since it can cause issues when you reach 65535 temporary files. Which is very possible and frustrating to debug when that actually happens on production code.
this should work for you
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.StartInfo.FileName = //your filename .tmp
proc.StartInfo.UseShellExecute = false;
proc.Start();

How to write a "*.bat" file?

Why "1.bat" can't run successfully? Any help will be appreciate. "1.bat" was created successfully.It can run without error, but can't rename the files.
private void button1_Click(object sender, EventArgs e)
{
string str = System.Environment.CurrentDirectory;
str += "\\1.bat";
string txt = "";
txt = "ren *.mp3 *.wav";
StreamWriter sw = new StreamWriter(str,false, Encoding.UTF8);
sw.Write(txt);
sw.Close();
Process p = new Process();
p.StartInfo.FileName = str;
p.StartInfo.Arguments = "";
p.StartInfo.UseShellExecute = false;
p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
p.Start();
}
One problem is that your file is being written with a UTF-8 BOM. Try passing Encoding.Default to test this out. Or pass new UTF8Encoding(false) as the encoding to pass a UTF-8 encoding that omits the BOM.
Another problem (which you just added in an edit) is that you set UseShellExecute to false. That requires the file you pass to be an executable file. Your file isn't. You need UseShellExecute to be true to allow the shell to work out how to process your .bat file.
And yet another possible problem is that the current directory may not be what you think it is.
When faced with problems like this there is no need at all to be helpless. Do some debugging. Add a pause at the end of your batch file and make sure that you can see the console. You'll find out immediately what the problem is. Learning how to debug is just as important as learning how to program. You won't be able to do the latter until you can do the former.
If I were having to do it this way, with an external process, I would:
Set UseShellExecute to false.
Pass cmd.exe as the executable file.
Pass the command to be executed as the command line.
However, it would be much easier to do this directly using C# and so avoid having to spin up external processes.

How to pass string to batch file through c# and how batch file will accept string argument?

My scenario in C# project is user will pass path like "c:\homedir\mydir" to batch file then batch file should accept this path and create directory at the specified path.
I don't know how to pass string to batch file through c# and how batch file will accept string and process it.
Create a process and pass your argument(s) through the StartInfo.Arguments property.
Process proc = new Process();
proc.StartInfo.FileName = //path to your BAT file
proc.StartInfo.Arguments = String.Format("{0}", #"C:\homedir\mydir");
//set the rest of the process settings
proc.Start();
That will load your BAT file and pass whichever arguments you've added. Your BAT file can access the arguments using %1 for the first argument, %2 for the second one etc...
Since you didn't gave us any information, I just give an example of these subjects.
First of all, you need to use Process class include System.Diagnostics namespace.
Provides access to local and remote processes and enables you to start
and stop local system processes.
An example with a batch file:
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "yourbatchfile.bat";
p.Start();
For passing arguments, you can use ProcessStartInfo.Arguments property.
Gets or sets the set of command-line arguments to use when starting
the application.

Categories