Click here to Skip to main content
15,886,919 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to create a program, where in the Windows Forms Form a program will be started when a button is clicked.
In the Console app, some folders and files are created and then with a logging class the messages are logged in a txt file.
What I want to do is to return this message also as an output in the Form textbox.

I am new to C# and not sure how I can send this message back to my Form. I already tried with console output and to read it in Form. But the Problem was that the output was only available when the program was finished. Preferably the message should be sent every time the logWrite is called.

What I have tried:

DwnldVwrForm1.cs:
C#
using System;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using Newtonsoft.Json;
using System.Management;

namespace DownloadViewer
{
    public partial class DwnldVwrForm1 : Form
    {
        private Process firstProc;
        private Process logProc;
        private int processId;
        private string maxRegmonth;
        private string selectedFlow;
        public string logTextBox;

        public DwnldVwrForm1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
        }
        

        private void button1_Click(object sender, EventArgs e)
        {
            
            //Path JSON File
            string pathJsonFile = @"C:\Projects\DownloadViewer\FolderPath.json";
            string pathJsonString = File.ReadAllText(pathJsonFile);
            FolderPath folderpath1 = JsonConvert.DeserializeObject<FolderPath>(pathJsonString);

            for (int i = 0; i < folderpath1.FolderPathLinks.Count; i++)
            {
                if (folderpath1.FolderPathLinks[i].Projectname == selectedFlow)
                {
                    string dirPath = folderpath1.FolderPathLinks[i].Destinationpath;

                    
                    try
                    {
                        firstProc = new Process();
                        firstProc.StartInfo.FileName = @"C:\Programs\"+ selectedFlow + @"\setup.exe";
                        firstProc.StartInfo.RedirectStandardOutput = true;
                        firstProc.StartInfo.RedirectStandardError = true;
                        firstProc.EnableRaisingEvents = true;
                        firstProc.StartInfo.CreateNoWindow = true;
                        firstProc.StartInfo.UseShellExecute = false;
                        firstProc.Start();
                        
                        processId = firstProc.Id;

                        label1.Text = "Folder path: " + dirPath;

                   }
                   catch (Exception ex)
                   {
                        MessageBox.Show(ex.Message);
                   }
                }
            }
        }

        private void listBox1_Click(object sender, EventArgs e)
        {
            //Selected Flow from the list
            selectedFlow = listBox1.SelectedItem.ToString();
        }
    }
}



Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.IO;
using Newtonsoft.Json;
using System.Windows.Forms;

namespace CreateFiles
{
    class Program
    {
        static void Main(string[] args)
        {
          Directory.CreateDirectory(@"C:\test\202308);
          LogWriter.LogWrite("Folder 202308 was created");
        }
    }
}


LogWriter.cs

using System;
using System.IO;

namespace CreateFiles
{
    public static class LogWriter
    {
        public static void LogWrite(string logMessage)
        {
           //Preferably here i can send the logMessage to the form, which will then be appended to the textbox
            string pathMainLogFile = @"C:\Output\Logs\MainLog.txt";
            try
            {
                using (StreamWriter z = File.AppendText(pathMainLogFile))
                {
                    Log(logMessage, z);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

        public static void Log(string logMessage, TextWriter txtWriter)
        {
            try
            {
                txtWriter.WriteLine("{0} {1} {2} {3} {4}", "CHOD", DateTime.Now.ToLongDateString(), DateTime.Now.ToLongTimeString(), " :", logMessage);

            }
            catch (Exception ex)
            {
            }
        }
    }
}
Posted
Updated 21-Sep-23 6:46am
v2
Comments
Richard MacCutchan 21-Sep-23 5:22am    
There is no simple way to do this. But why are you separating the two processes? You can easily create the files within your Form application.
Eliz98 21-Sep-23 5:33am    
Program.cs has to do lot more than just creating folders such as checking files and contents. And there are different Projects, which the user can select. But the log happens mainly when the folders are created. That is why I just copied that code.
Is it possible to do that with an EventHandler?
Richard MacCutchan 21-Sep-23 5:54am    
You cannot subscribe to a Form's event handler from an external program. The only way that the console app can send data to the form is via the redirected output. If you could run the console app as a new process for each file to be created, then the forms app can see the results quicker. But maybe you need to go back to design level to consider what it is you are trying to achieve overall.

There is no simple and reliable way to do this, other than directly connecting the two apps: I'd use a TcpListener instance in the GUI app (in a BackgroundWorker) to listen for updates from the console with a TcpClient.

There is a description of how I process File Explorer generated app open requests here: Double Clicking a File in Explorer and Adding It to Your App while it's Running[^]

It uses a similar mechanism, but it's the same app at both ends: File Explorer kicks up a new instance, which passes it to the already running app and closes itself. It should be relatively simple to fix that in your app, assuming an intermediate level of experience.
 
Share this answer
 
v2
Another option would be creating an anonymous pipe and pass data back and forth over the pipe.

AnonymousPipeServerStream Class (System.IO.Pipes) | Microsoft Learn[^]

AnonymousPipeClientStream Class (System.IO.Pipes) | Microsoft Learn[^]
 
Share this answer
 
Since you're already dealing with "files and folders", get the console app to "log" individual messages (as files) in a separate folder.

In the Windows Forms app, add a "FileSystemWatcher", which will be notified when there are new messages (files).

Consume the messages by reading them; then deleting (archiving or whatever) the "read" message.

FileSystemWatcher Class (System.IO) | Microsoft Learn[^]
 
Share this answer
 
Comments
Eliz98 22-Sep-23 6:04am    
Actually, I had tried this with the whole logfile. But with individual messages in a seperate file, it works better. Thanks
Eliz98 22-Sep-23 8:15am    
Is there any way to overcome the FileSystemWatcher event being raised twice?
[no name] 22-Sep-23 10:02am    
You'd have to look at the events in detail. You're implying they're the "same", of which there is no evidence. And if there is "always 2", then use the 2nd as a "confirmation". Things are only a problem if they're not predictable. (and if you "delete" after you read, I expect that is an "event").

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900