I have a console application which is an FTP server. This console application works fine. Now, I want to run this FTP Server using Windows Service.
I have an unhandled exception trapper which traps an unhandled exception. After this exception occurs, I want to stop the service, destruct the class for FTP Server, delay it for 10 seconds and restart the service.
Following is my code (The ftp server and service works fine if there is no unhandled exception but I want to successfully stop and restart the service. This code stops the service fine but doesn't restart it). Any ideas?
public partial class FTPService : ServiceBase
{
private static FtpServer _ftpServer;
public FTPService(string[] args)
{
InitializeComponent();
string eventSourceName = "Ftp Server Events";
eventLog1 = new System.Diagnostics.EventLog();
string logName = "Ftp Server Log";
if (args.Count() > 0)
{
eventSourceName = args[0];
}
if (args.Count() > 1)
{
logName = args[1];
}
eventLog1 = new System.Diagnostics.EventLog();
if (!System.Diagnostics.EventLog.SourceExists(eventSourceName))
{
System.Diagnostics.EventLog.CreateEventSource(eventSourceName, logName);
}
eventLog1.Source = eventSourceName;
eventLog1.Log = logName;
if (!System.Diagnostics.EventLog.SourceExists("Ftp Server Events"))
{
System.Diagnostics.EventLog.CreateEventSource(
"Ftp Server Events", "Ftp Server Log");
}
this.ServiceName = "FTP Service";
this.AutoLog = true;
}
public static void Main(string[] args)
{
ServiceBase.Run(new FTPService(new string[0]));
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
var database = new Database(); // Gets database details as FTP server tals to database.
var configurationManager = new ConfigurationManagerWrapper(); // Same as above
_ftpServer = new FtpServer(new Assemblies.Ftp.FileSystem.StandardFileSystemClassFactory(database, configurationManager));
_ftpServer.Start(); //Starts the service (FTP Server works fine if there is no handled exception)
eventLog1.WriteEntry("Started");
FtpServerMessageHandler.Message += MessageHandler_Message;
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
}
protected override void OnStop()
{
_ftpServer.Stop(); // This calls the destructor for FTP Server, to close any TCP Listening connections, etc
base.OnStop(); // Here I stop the service itself.
eventLog1.WriteEntry("Stopped");
Thread.Sleep(10000);
}
protected void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e) // unhandled exception handler
{
eventLog1.WriteEntry(e.ExceptionObject.ToString());
Thread.Sleep(5000);
OnStop(); // Calls onstop which stops FTP Server and destroys previous objects of FTP server
var serviceMgr = new ServiceController();
serviceMgr.Start(); // Here I want to restart the service (it doesn't work)
}
}
Try following:
services.msc -> your Service-> Properties -> Recovery
set properties for you
-> Save -> your Service -> restart
Related
I'm trying to connect to a StreamSocketListener in my Windows 10 app. This is working if the client socket is inside the same app. But if I try to connect from another application (e.g. Putty) it doesn't work. After a few seconds putty says "Network Error: Connection Refused".
Here is my sample code:
public sealed partial class MainPage : Page
{
private StreamSocketListener listener;
public MainPage()
{
this.InitializeComponent();
listener = new StreamSocketListener();
listener.ConnectionReceived += Listener_ConnectionReceived;
listener.BindServiceNameAsync("12345").AsTask().Wait();
}
private async void Listener_ConnectionReceived(StreamSocketListener sender, StreamSocketListenerConnectionReceivedEventArgs args)
{
Debug.WriteLine("new connection");
string message = "Hello World!";
using (var dw = new DataWriter(args.Socket.OutputStream))
{
dw.WriteString(message);
await dw.StoreAsync();
dw.DetachStream();
}
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
// Test connection
var serverHost = new HostName("localhost");
var socket = new StreamSocket();
await socket.ConnectAsync(serverHost, "12345");
using (var dr = new DataReader(socket.InputStream))
{
dr.InputStreamOptions = InputStreamOptions.Partial;
await dr.LoadAsync(12);
var input = dr.ReadString(12);
Debug.WriteLine("received: " + input);
}
}
}
In XAML i added a button to test the client connection.
In the manifest i have checked "Internet (Client)", "Internet (Client & Server)" and "Private Networks (Client & Server)".
EDIT: I'm trying to connect on the same computer. Firewall is deactivated.
You cannot connect to a StreamSocketListener from another app or process running in the same computer, not even with a loopback exemption. You will need to run the client in a different machine.
You can connect to a localhost UWP server app only if you disable the windows firewall (via the control panel) before starting the app, and then quit the firewall service ("net stop MpsSvc", from elevated command prompt) after the app has been started. Loopbackexemption doesn't enable connections to UWP apps, only from UWP apps, in my experience at least...
regards
.Net application which will subscribe to streaming notification. This application executes well, this subscription disconnected after 30 mints so I added the code to reconnect the connection .I tested the application by adding break point at the reconnect line and waited for some time before it established the connection again. During that time I created a few new emails and watched if console displays those events. It did not as connection was disconnected then I run the code again and I was able to see the events which were created during the time connection disconnected and connected. I need to know if this is the right way to make this process run continuously and track the events which occurred during the disconnect and reconnect of the application. also need to know why the below code is not notifying about delete mail event. kindly looking for help.
namespace NewMailNotification
{
class Program
{
static void Main(string[] args)
{
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
//***********New**********************
ExchangeService mailbox = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
string mailboxEmail = ConfigurationSettings.AppSettings["user-id"];
WebCredentials wbcred = new WebCredentials(ConfigurationSettings.AppSettings["user"], ConfigurationSettings.AppSettings["PWD"]);
mailbox.Credentials = wbcred;
// mailbox.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, mailboxEmail);
mailbox.AutodiscoverUrl(mailboxEmail, RedirectionUrlValidationCallback);
mailbox.HttpHeaders.Add("X-AnchorMailBox", mailboxEmail);
FolderId mb1Inbox = new FolderId(WellKnownFolderName.Inbox, mailboxEmail);
SetStreamingNotification(mailbox, mb1Inbox);
bool run = true;
bool reconnect = false;
while (run)
{
System.Threading.Thread.Sleep(100);
}
}
internal static bool RedirectionUrlValidationCallback(string redirectionUrl)
{
//The default for the validation callback is to reject the URL
bool result=false;
Uri redirectionUri=new Uri(redirectionUrl);
if(redirectionUri.Scheme=="https")
{
result=true;
}
return result;
}
static void SetStreamingNotification(ExchangeService service,FolderId fldId)
{
StreamingSubscription streamingssubscription=service.SubscribeToStreamingNotifications(new FolderId[]{fldId},
EventType.NewMail,
EventType.Created,
EventType.Deleted);
StreamingSubscriptionConnection connection=new StreamingSubscriptionConnection(service,30);
connection.AddSubscription(streamingssubscription);
//Delagate event handlers
connection.OnNotificationEvent+=new StreamingSubscriptionConnection.NotificationEventDelegate(OnEvent);
connection.OnDisconnect += new StreamingSubscriptionConnection.SubscriptionErrorDelegate(Connection_OnDisconnect);
connection.OnSubscriptionError+=new StreamingSubscriptionConnection.SubscriptionErrorDelegate(OnError);
connection.Open();
}
static private void Connection_OnDisconnect(object sender, SubscriptionErrorEventArgs args)
{
StreamingSubscriptionConnection connection = (StreamingSubscriptionConnection)sender;
if (!connection.IsOpen)
{
// Console.WriteLine("no connection");
connection.Open();
}
}
static void OnEvent(object sender,NotificationEventArgs args)
{
StreamingSubscription subscription=args.Subscription;
if(subscription.Service.HttpHeaders.ContainsKey("X-AnchorMailBox"))
{
Console.WriteLine("event for nailbox"+subscription.Service.HttpHeaders["X-AnchorMailBox"]);
}
//loop through all the item-related events.
foreach(NotificationEvent notification in args.Events)
{
switch(notification.EventType)
{
case EventType.NewMail:
Console.WriteLine("\n----------------Mail Received-----");
break;
case EventType.Created:
Console.WriteLine("\n-------------Item or Folder deleted-------");
break;
case EventType.Deleted:
Console.WriteLine("\n------------Item or folder deleted---------");
break;
}
//Display notification identifier
if(notification is ItemEvent)
{
//The NotificationEvent for an email message is an ItemEvent
ItemEvent itemEvent=(ItemEvent)notification;
Console.WriteLine("\nItemId:"+ itemEvent.ItemId.UniqueId);
Item NewItem=Item.Bind(subscription.Service,itemEvent.ItemId);
if(NewItem is EmailMessage)
{
Console.WriteLine(NewItem.Subject);
}
}
else
{
//the Notification for a Folder is an FolderEvent
FolderEvent folderEvent=(FolderEvent)notification;
Console.WriteLine("\nFolderId:"+folderEvent.FolderId.UniqueId);
}
}
}
static void OnError(object sender,SubscriptionErrorEventArgs args)
{
//Handle error conditions.
Exception e=args.Exception;
Console.WriteLine("\n-----Error-----"+e.Message+"--------");
}
}
}
Here is an example :
_BackroundSyncThread = new Thread(streamNotification.SynchronizeChangesPeriodically); _BackroundSyncThread.Start();
private void SynchronizeChangesPeriodically()
{
while (true)
{
try
{
// Get all changes from the server and process them according to the business
// rules.
SynchronizeChanges(new FolderId(WellKnownFolderName.Calendar));
}
catch (Exception ex)
{
Console.WriteLine("Failed to synchronize items. Error: {0}", ex);
}
// Since the SyncFolderItems operation is a
// rather expensive operation, only do this every 10 minutes
Thread.Sleep(TimeSpan.FromMinutes(10));
}
}
public void SynchronizeChanges(FolderId folderId)
{
bool moreChangesAvailable;
do
{
Debug.WriteLine("Synchronizing changes...");
// Get all changes since the last call. The synchronization cookie is stored in the _SynchronizationState field.
// Only the the ids are requested. Additional properties should be fetched via GetItem calls.
var changes = _ExchangeService.SyncFolderItems(folderId, PropertySet.FirstClassProperties, null, 512,
SyncFolderItemsScope.NormalItems, _SynchronizationState);
// Update the synchronization cookie
_SynchronizationState = changes.SyncState;
// Process all changes
foreach (var itemChange in changes)
{
// This example just prints the ChangeType and ItemId to the console
// LOB application would apply business rules to each item.
Console.WriteLine("ChangeType = {0}", itemChange.ChangeType);
Console.WriteLine("Subject = {0}", itemChange.Item.Subject);
}
// If more changes are available, issue additional SyncFolderItems requests.
moreChangesAvailable = changes.MoreChangesAvailable;
} while (moreChangesAvailable);
}
The _SynchronizationState field is like a Cookie that contains some informations about your last sync process . So next time the thread will synchronize all the items since the last sync .
Hope it helps
I have an instance of the following code that executes correctly in Debug or as a standalone Windows application:
TcpListener tcpListener = new TcpListener(IPAddress.Any, 4554);
tcpListener.Start();
while (true)
{
try
{
using (Socket socket = tcpListener.AcceptSocket())
{
// Code here is reached in Debug or as a Console Application
// but not as a Windows Service
}
}
catch (SocketException se)
{
// This is never reached
}
catch (Exception ex)
{
// This is never reached
}
finally
{
// This is never reached in the Windows Service
}
}
However, when I install it as a Windows Service, it crashes on tcpListener.AcceptSocket(), and logs the following to the Event Viewer:
An unhandled exception ('System.Net.Sockets.SocketException') occurred in MyService.exe [768]. Just-In-Time debugging this exception failed with the following error: The operation attempted is not supported.
Even trying to catch the exception I am unable to log anything more. Stepping through code in Debug accomplishes nothing because the code successfully blocks the application and waits for a client connection.
Is there a way to implement this for a Windows Service?
usr's advice (and this answer) led me to a bug in the code. The ServiceBase class contained the following:
protected override void OnStart(string[] args)
{
_worker = new Thread(ExecuteService);
_worker.Start();
}
private void ExecuteService()
{
for (;;)
{
if (_stop.WaitOne(1000))
{
new TcpServer().StartTcpServer();
return;
}
}
}
The correct implementation was to remove the for loop, which was re-instantiating the listener. Here is the final code:
protected override void OnStart(string[] args)
{
_worker = new Thread(ExecuteService);
_worker.Start();
}
private static void ExecuteService()
{
new TcpServer().StartTcpServer();
}
I have just started learning WCF. Currently i am working on a project where i am "self hosting" server on console application and the client is a WPF application.
COntracts
[ServiceContract]
public interface IDemoValue
{
[OperationContract]
double IncrementByHundred(double val);
}
Server
class Program
{
static void Main(string[] args)
{
using(ServiceHost host=new ServiceHost(typeof(WcfServiceDemos.DemoValue)))
{
host.Open();
Console.WriteLine("Host is running at {0}", DateTime.Now.ToString());
Thread.Sleep(2000);
}
}
}
</pre></code>
As from the code is clear that i am trying to Host WcfSericesDemos.DemoValue class.
CLIENT
//Event to start server (on button click)
private void Button_Click(object sender, RoutedEventArgs e)
{
object val1 = regKey.GetValue("SERVER");
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.FileName = val1.ToString();
try
{
using (Process proc = Process.Start(startInfo))
{
double inputValue = Convert.ToDouble(Input.Text);
//Here IncrementByHundred(inputValue) is a method from DemoValue which iam trying to expose through WCF
OutPut.Content = server.IncrementByHundred(inputValue);
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Now my problem is Server is closing before the IncrementByHundred() method is Invoked.
So bottom line ,i want to stop the server from client side after IncrementByHundred() has finished its task.
FYI: I have tried working Console.Readline() in the server,that does the job by server is still running ,but i want to close the server once IncrementByHundred() method has done its job.
Thanks in advance
I have a Windows service that exposes a WCF service.
I also have an application that talks to the WCF service and sends commands and receives data back.
All this works fine when I run the application from Visual Studio.
However, when I install the application and run it, the application cannot communicate with the service.
Nor can the batch files that the application runs to Stop and Start the service.
I've tried using netsh to 'reserve' the URI but I don't really know what I'm doing :-)
Can you point me in the right direction?
Windows Server code WCF Service code (abridged):
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "WCF_Service" in both code and config file together.
[ServiceContract]
public class InternetGauge_IO
{
[OperationContract]
public void Pause()
{
RunningState.paused = true;
}
[OperationContract]
public void Continue()
{
RunningState.paused = false;
}
[OperationContract]
public bool GetRunningState()
{
return RunningState.paused;
}
....
Windows Server code WCF Create endpoint code:
private void InitializeConsoleComms()
{
try
{
//Prepare comms with the Console application
Type serviceType = typeof(InternetGauge_IO);
host = new ServiceHost(serviceType, new Uri[] { new Uri("http://localhost:8080/") });
// Add behavior for our MEX endpoint
ServiceMetadataBehavior behavior = new ServiceMetadataBehavior();
behavior.HttpGetEnabled = true;
host.Description.Behaviors.Add(behavior);
// Create basicHttpBinding endpoint at http://localhost:8080/RJB.InternetGauge/
host.AddServiceEndpoint(serviceType, new BasicHttpBinding(), "RJB.InternetGauge");
// Add MEX endpoint at http://localhost:8080/MEX/
host.AddServiceEndpoint(typeof(IMetadataExchange), new BasicHttpBinding(), "MEX");
host.Open();
logger.LogEvent("Console comms ready", "Internet Gauge", 4, 1);
}
catch (Exception e)
{
logger.LogEvent("Failed to open Console comms", "Internet Gauge", 1, 1);
logger.LogEvent("Exception : " + e.InnerException + " Stack Trace: " + e.StackTrace + " Message: " + e.Message, "RJB.InternetGauge.WindowsService.Main", 1, 1);
}
}
The application just uses the generated proxy and methods e.g.
private bool GetRunningState()
{
try
{
InternetGauge_IOClient client = new InternetGauge_IOClient();
isRunning = true;
return(client.GetRunningState());
}
catch (Exception)
{
trayIcon.Text = "Internet Gauge Windows Service does not appear to be running.";
trayIcon.Icon = RJB.InternetGauge.Console.Properties.Resources.ServiceStopped;
isPaused = true;
isRunning = false;
return isPaused;
}
}
The netsh command I tried
netsh http add urlacl url=http://+:8080/InternetGauge_IO user=PC-01\richard
Any ideas?
Thanks
Richard
It is because I am a twit.
Didn't copy the app.config over during the installation program.
All works fine now.