How can a Windows Service create a process? - c#

I want to create program that run all the time (not a Windows Service exactly). I want it to have no view to the user.
I would like it to be a process, the reason I don't want it to be service is because I want to create to process and I want one service to start them.
I don't know how to create the program without any UI as if I create console application the CMD open when I run the program.

I'm taking a guess as to what you're trying to do, but here's a really simple console application that runs until you hit the ENTER key. It will print out a line to the console every second.
class Program
{
static void Main(string[] args)
{
using (System.Threading.Timer processTimer = new System.Threading.Timer(DoSomething, "fun", 0, 1000))
{
Console.ReadLine();
}
}
static void DoSomething(object data)
{
Console.WriteLine("doing something {0}...", data.ToString());
}
}
You can replace the contents of DoSomething with what you need your console runner to do.
I hope this helps.

Related

C# Console Application Crashing

On Visual Studio, the C# Console application keeps on terminating when I try to run a program. I tested this by just writing Hello World, shown here:
(screenshot of what I wrote)
When I run it, the command prompt window appears for a second, then immediately closes. Is there a way to fix this?
When a console application runs it executes the code and exits, console applications do not have a message loop to keep them alive, it is the same as creating a batch file and double clicking it, the command window will open and then close when execution finishes. If you want then console window to hang around afterwards then you need to use Console.ReadLine(); which will wait for user input before closing (i.e. pressing Enter).
You code (which should be in your question) simply outputs some text to the console and then exits.
Suggested reading Creating a Console Application
class Program
{
static void Main (string[] args)
{
Console.WriteLine("Hello World");
Console.ReadLine();
}
}
The application is not crashing, it runs and then exits. If you want read the output after it's done you can use Console.ReadLine();
using System;
namespace Hello_World
{
class Program
{
static void Main (string[] args)
{
Console.WriteLine("Hello World");
Console.ReadKey();
}
}
}
The issue is not crashing really but that all the instructions are executed then the program exits. If you desire to pause, you could insert the statement:
Console.ReadKey();
which will wait for you to type a key to exit.

Console app scheduled task run two different ways

I have a program for a client that needs to run one set of code every 30 minutes via a scheduled task.
at 1:30 am it needs to run a separate set of code.
Both sets of code will generate a file and place it in a directory.
How do I set it up to be able to run two sets of SQL code?
I could do it getting the current date time and comparing it but that seems bulky to me.
Is there a way a schedule task can run a program which would pass in something to my Main(string[] args)?
Is there a correct way to do it without creating two separate apps?
Make your program accept parameters, then schedule your console app (using Windows scheduler) with the different parameters... something like:
void Main(string[] args)
{
var firstArg = args.FirstOrDefault();
if (firstArg == "option1")
{
// do stuff
}
else if (firstArg == "option2")
{
// do other stuff
}
}
In scheduler do something like:
Write to flat file your param result from the first process, or database and get it from there with the second process.. Or just have your process always running and use stopwatch to perform events every 30 minutes instead of using the task scheduler, then you can keep it in memory. You have a lot of options.

Logic for Windows Services & Getting Updates

I developed a Windows service using vb.net which does the following using OnStart Even...
Grabs all Entries from a SQL Table
Creates Schedules from returned rows
it works fine, schedules fire on their time and stuff.
Problem: Whenever I have to ADD a new row to my Table, I have to restart the Service, So it can Grab the Newly created rows. This is causing problems for me...there could be a task which is running already and restarting service might break the system.
So what is the best way to handle this? Can the new rows be loaded into Service without a restart?
Thanks
Use the concept of Polling into the Database. Use the System.Threading.Timer class, set some interval after which a callback method will be invoked and that will be responsible to Poll the Database for new entries.
This OnStart was provided here by Marc Gravell:
public void OnStart(string[] args) // should this be override?
{
var worker = new Thread(DoWork);
worker.Name = "MyWorker";
worker.IsBackground = false;
worker.Start();
}
void DoWork()
{
// do long-running stuff
}
Note that OnStart can launch multiple threads or the first thread started may be used to start additional threads as needed. This allows you to set up either database polling or a thread that waits on a message queue for data.
A useful tip:
Adding a Main to your service allows you to run it as a console application in Visual Studio. This greatly simplifies debugging.
static void Main(string[] args)
{
ServiceTemplate service = new ServiceTemplate();
if (Environment.UserInteractive)
{
// The application is running from a console window, perhaps creating by Visual Studio.
try
{
if (Console.WindowHeight < 10)
Console.WindowHeight = 10;
if (Console.WindowWidth < 240) // Maximum supported width.
Console.WindowWidth = 240;
}
catch (Exception)
{
// We couldn't resize the console window. So it goes.
}
service.OnStart(args);
Console.Write("Press any key to stop program: ");
Console.ReadKey();
Console.Write("\r\nInvoking OnStop() ...");
service.OnStop();
Console.Write("Press any key to exit: ");
Console.ReadKey();
}
else
{
// The application is running as a service.
// Misnomer. The following registers the services with the Service Control Manager (SCM). It doesn't run anything.
ServiceBase.Run(service);
}
}

Open two console windows from C#

[DllImport("kernel32.dll")]
private static extern Int32 AllocConsole();
I can open cmd.exe with this command. But i can open only one console window and write in it. How can i open another one? Is any clean and fast solution for opening two console windows?
So you can do multiple console windows within one single C# windows app, but to do so you would have to have a few things. Process.start(), and command-line parameters.
If you do it this way you can have your app create another instance of itself, but with different command line parameters to have each part do different things.
Here is a simplistic example of how to do it.
namespace Proof_of_Concept_2
{
class Program
{
static void Main(string[] args)
{
if (args.Length!= 0)
{
if (args[0] == "1")
{
AlternatePathOfExecution();
}
//add other options here and below
}
else
{
NormalPathOfExectution();
}
}
private static void NormalPathOfExectution()
{
Console.WriteLine("Doing something here");
//need one of these for each additional console window
System.Diagnostics.Process.Start("Proof of Concept 2.exe", "1");
Console.ReadLine();
}
private static void AlternatePathOfExecution()
{
Console.WriteLine("Write something different on other Console");
Console.ReadLine();
}
}
}
Here is a screenshot of it working.
In conclusion,
Getting 2 console windows is easy, getting them to talk to each other is a separate question in and of itself. But I would suggest named pipes. Relevant Stackoverflow Post
You have to change your thinking because the 2 Consoles once run on different processes don't automatically talk to each other. Whatever calculation you are doing on one of them, the other one is completely unaware.
You can do
Process.Start("cmd.exe");
as many times as you would like. Is this what you mean?
Unfortunately not, sorry — you cannot have more than one console window per application in Windows.
Run the Console app (first window)
Got to bin > debug and open the YourApplication.exe file (second window)

how to run a winform from console application?

How do I create, execute and control a winform from within a console application?
The easiest option is to start a windows forms project, then change the output-type to Console Application. Alternatively, just add a reference to System.Windows.Forms.dll, and start coding:
using System.Windows.Forms;
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.Run(new Form()); // or whatever
}
The important bit is the [STAThread] on your Main() method, required for full COM support.
I recently wanted to do this and found that I was not happy with any of the answers here.
If you follow Marc's advice and set the output-type to Console Application there are two problems:
1) If you launch the application from Explorer, you get an annoying console window behind your Form which doesn't go away until your program exits. We can mitigate this problem by calling FreeConsole prior to showing the GUI (Application.Run). The annoyance here is that the console window still appears. It immediately goes away, but is there for a moment none-the-less.
2) If you launch it from a console, and display a GUI, the console is blocked until the GUI exits. This is because the console (cmd.exe) thinks it should launch Console apps synchronously and Windows apps asynchronously (the unix equivalent of "myprocess &").
If you leave the output-type as Windows Application, but correctly call AttachConsole, you don't get a second console window when invoked from a console and you don't get the unnecessary console when invoked from Explorer. The correct way to call AttachConsole is to pass -1 to it. This causes our process to attach to the console of our parent process (the console window that launched us).
However, this has two different problems:
1) Because the console launches Windows apps in the background, it immediately displays the prompt and allows further input. On the one hand this is good news, the console is not blocked on your GUI app, but in the case where you want to dump output to the console and never show the GUI, your program's output comes after the prompt and no new prompt is displayed when you're done. This looks a bit confusing, not to mention that your "console app" is running in the background and the user is free to execute other commands while it's running.
2) Stream redirection gets messed up as well, e.g. "myapp some parameters > somefile" fails to redirect. The stream redirection problem requires a significant amount of p/Invoke to fixup the standard handles, but it is solvable.
After many hours of hunting and experimenting, I've come to the conclusion that there is no way to do this perfectly. You simply cannot get all the benefits of both console and window without any side effects. It's a matter of picking which side effects are least annoying for your application's purposes.
Here is the best method that I've found:
First, set your projects output type to "Windows Application", then P/Invoke AllocConsole to create a console window.
internal static class NativeMethods
{
[DllImport("kernel32.dll")]
internal static extern Boolean AllocConsole();
}
static class Program
{
static void Main(string[] args) {
if (args.Length == 0) {
// run as windows app
Application.EnableVisualStyles();
Application.Run(new Form1());
} else {
// run as console app
NativeMethods.AllocConsole();
Console.WriteLine("Hello World");
Console.ReadLine();
}
}
}
It´s very simple to do:
Just add following attribute and code to your Main-method:
[STAThread]
void Main(string[] args])
{
Application.EnableVisualStyles();
//Do some stuff...
while(!Exit)
{
Application.DoEvents(); //Now if you call "form.Show()" your form won´t be frozen
//Do your stuff
}
}
Now you´re fully able to show WinForms :)
You can create a winform project in VS2005/ VS2008 and then change its properties to be a command line application. It can then be started from the command line, but will still open a winform.
All the above answers are great help, but I thought to add some more tips for the absolute beginner.
So, you want to do something with Windows Forms, in a Console Application:
Add a reference to System.Windows.Forms.dll in your Console application project in Solution Explorer. (Right Click on Solution-name->add->Reference...)
Specify the name space in code: using System.Windows.Forms;
Declare the needed properties in your class for the controls you wish to add to the form.
e.g. int Left { get; set; } // need to specify the LEFT position of the button on the Form
And then add the following code snippet in Main():
static void Main(string[] args)
{
Application.EnableVisualStyles();
Form frm = new Form(); // create aForm object
Button btn = new Button()
{
Left = 120,
Width = 130,
Height = 30,
Top = 150,
Text = "Biju Joseph, Redmond, WA"
};
//… more code
frm.Controls.Add(btn); // add button to the Form
// …. add more code here as needed
frm.ShowDialog(); // a modal dialog
}
This worked for my needs...
Task mytask = Task.Run(() =>
{
MyForm form = new MyForm();
form.ShowDialog();
});
This starts the from in a new thread and does not release the thread until the form is closed. Task is in .Net 4 and later.
You should be able to use the Application class in the same way as Winform apps do. Probably the easiest way to start a new project is to do what Marc suggested: create a new Winform project, and then change it in the options to a console application
Its totally depends upon your choice, that how you are implementing.
a. Attached process , ex: input on form and print on console
b. Independent process, ex: start a timer, don't close even if console exit.
for a,
Application.Run(new Form1());
//or -------------
Form1 f = new Form1();
f.ShowDialog();
for b,
Use thread, or task anything,
How to open win form independently?
If you want to escape from Form Freeze and use editing (like text for a button) use this code
Form form = new Form();
Form.Button.Text = "randomText";
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.Run(form);

Categories

Resources