I have created a Windows Service for the very first time. It is not working. The files OnStart.txt and OnStop.txt are created but nothing else happens. I don't believe MSProcess runs. How do I go about troubleshooting?
namespace MailScan_Service
{
public partial class svMaster : ServiceBase
{
private Timer myTimer = new Timer();
public svMaster()
{
InitializeComponent();
}
ServiceController sc = new ServiceController("MailScan Service");
protected override void OnStart(string[] args)
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStart.txt");
myTimer.Start();
}
protected override void OnStop()
{
if (myTimer.Enabled == true)
myTimer.Stop();
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStop.txt");
}
private void myTimer_Elapsed(object sender, ElapsedEventArgs e)
{
if (!sc.Status.Equals(ServiceControllerStatus.StopPending))
{
MSSettings msSet = new MSSettings();
msSet.Load();
myTimer.Interval = msSet.ScanTimer * 60000;
MSProcess.Start();
msSet.Dispose();
}
}
}
Yet this simulator works just fine!
namespace MailScanSettings
{
public partial class FormSimService : Form
{
public FormSimService()
{
InitializeComponent();
}
private void btnGo_Click(object sender, EventArgs e)
{
tbStatus.Clear();
tbStatus.Text += "Running";
this.BackColor = Color.Green;
timer1.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true)
timer1.Stop();
this.BackColor = Color.Red;
tbStatus.Clear();
tbStatus.Text += "Stopped";
}
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
MSSettings msSet = new MSSettings();
msSet.Load();
timer1.Interval = msSet.ScanTimer * 60000;
MSProcess.Start();
msSet.Dispose();
}
}
}
I used to have to debug a lot of Windows Services and have done the same log file pot shot approach. It's painful and frustrating for sure.
Ultimately I found a tip somewhere, which is that for debugging purposes, you can drop this line:
System.Diagnostics.Debugger.Launch()
in the beginning of your OnStart method. It will pop a dialog and ask which debugger you want to attach. Since you'll already have the solution loaded in Visual Studio, just choose it and it will hit your breakpoints.
It can be tedious as well, but more productive. You end up in a productivity loop of having to stop the service, uninstall, patch the code, build, reinstall, start, debug...
Related
So i have 2 forms, one is called "musica" and its playing a music (this form is invisible) and the other is called "Form1" and gives the option to stop and start the music with radio buttons.
The problem is that the radio buttons are working, but the video continues even if i click on "radionButton2" and if i use the "stop()" function on "musica_load" the music stops so i don't think the problem is from there either.
What is my mistake here?
Form1 code:
musica mus = new musica();
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
mus.play();
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (radioButton2.Checked == true)
{
mus.stop();
}
}
musica code:
public void play()
{
axWindowsMediaPlayer1.Ctlcontrols.play();
}
public void stop()
{
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
// Form1.cs
musica mus;
public Form1()
{
InitializeComponent();
mus = new musica();
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (radioButton1.Checked == true)
{
mus.Play(); ;
}
}
private void radioButton2_CheckedChanged(object sender, EventArgs e)
{
if (radioButton2.Checked == true)
{
mus.Stop();
}
}
//Musica.cs
public musica()
{
InitializeComponent();
}
public void Play()
{
MessageBox.Show("Play");
}
public void Stop()
{
MessageBox.Show("Stop");
}
This works fine there must be some problem with the Play and Stop methods.
Answer: The problem was that i was opennig both forms simultaneously at the start of the program and for some reason they can't work between each other, if i open the musica.cs in Form1_load everything works!
I created a Service in C#. I needed a GUI for configuration of the Service so I added a WinForms project to my solution. My plans was to create the Form in the Service and show it in the OnStart() Method of the Service. However, it won't show. The WriteEntry() Methods of the EventLog are all firing, so my code definitely is processed. Anybody know what I'm doing wrong here?
public partial class UrlWatcherService : ServiceBase
{
private UrlWatcherForm _urlwatcherform;
private EventLog _eventLog;
private string _eventLogName = "UrlWatcherEventLog";
private string _eventLogSource = "UrlWatcherSource";
public UrlWatcherService()
{
InitializeComponent();
LoadVariables();
}
public void OnDebug()
{
OnStart(null);
}
private void LoadVariables()
{
_urlwatcherform = new UrlWatcherForm();
_eventLog = new EventLog();
CanPauseAndContinue = true;
if (!EventLog.SourceExists(_eventLogSource))
EventLog.CreateEventSource(_eventLogSource, _eventLogName);
_eventLog.Source = _eventLogSource;
_eventLog.Log = _eventLogName;
_eventLog.WriteEntry("Url Watcher Log Created", EventLogEntryType.Information);
}
protected override void OnStart(string[] args)
{
_eventLog.WriteEntry("Url Watcher Service Started", EventLogEntryType.Information);
_urlwatcherform.Show();
_eventLog.WriteEntry("Url Watcher Form Created", EventLogEntryType.Information);
}
protected override void OnPause()
{
base.OnPause();
_eventLog.WriteEntry("Url Watcher Service Paused", EventLogEntryType.Information);
}
protected override void OnContinue()
{
base.OnContinue();
_eventLog.WriteEntry("Url Watcher Log Continued", EventLogEntryType.Information);
}
protected override void OnStop()
{
_eventLog.WriteEntry("Url Watcher Service Stopped", EventLogEntryType.Information);
}
}
public partial class UrlWatcherForm : Form
{
public UrlWatcherForm()
{
InitializeComponent();
}
private void btnAdd_Click(object sender, EventArgs e)
{
}
private void UrlWatcherGui_Resize(object sender, EventArgs e)
{
if (FormWindowState.Minimized == WindowState)
Hide();
}
private void UrlWatcherGui_FormClosing(object sender, FormClosingEventArgs e)
{
Hide();
e.Cancel = true;
}
private void urlWatcherNofiyIcon_MouseDoubleClick(object sender, MouseEventArgs e)
{
Show();
}
}
EDIT: To clarify, if I debug it like below, the Form shows. I can put the thread to sleep but that won't let me interact with the Form anymore. But the Form definitely shows, it's just in an unresponsive state.
static void Main()
{
#if DEBUG
UrlWatcherService service = new UrlWatcherService();
service.OnDebug();
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new UrlWatcherService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
OK due to Steve's hint, I split the projects up. I use a merged module as per this MSDN article, and instead of referencing the GUI in the Service project, I separated them so I can put both their project outputs in the merged module. I then add the merged module to my installer and now I have the service running after install and the ability to call the form from my start menu. It's not what I originally wanted, but a very plausible alternative.
Thanks for Steve for the hint.
I have the problem with changing the timer Interval in backgroundworker's DoWork event. While changing the Interval by clicking the Button, Timer stops and doesn't start again.
Does anyone know how to solve this problem?
Simple code:
public Form1()
{
InitializeComponent();
timerTest.Tick += new EventHandler(timerTest_Tick);
timerTest.Interval = 1000;
timerTest.Start();
}
private void buttonTest_Click(object sender, EventArgs e)
{
push = true;
}
private void timerTest_Tick(object sender, EventArgs e)
{
ticks++;
labelTest.Text = ticks.ToString();
if(running == false)
{
running = true;
backgroundWorkerTest.RunWorkerAsync();
}
}
public void activate()
{
timerTest.Stop();
timerTest.Interval = 4000;
timerTest.Start();
}
private void DoWork(object sender, DoWorkEventArgs e)
{
while(running)
{
if(push == true)
{
activate();
}
}
}
private void Completed(object sender, RunWorkerCompletedEventArgs e)
{
running = false;
}
}
}
You never set push to false.
Therefore, the following code:
while(running)
{
if(push == true)
{
activate();
}
}
will continuously call activate() in a tight loop. activate() stops the timer and then restarts it, and the time between calls to it will be far less than the timer interval. Therefore, the timer will never be left long enough to fire.
In any case, why don't you call activate() directly from buttonTest_Click()?
I can see this was asked a long time ago, but for the reference:
When it comes to timers or threadings in general (remember timer is system.threading) in combination with background workers (tasks) Never ever try to change a thread proerties randomly without knowing what the worker is doing.
It is always a good practice when assigning the DoWork handler to prepare the background worker Progress and Complete handlers as well.
At each cycle, report the progress or the completion, this would give you the chance to do your checks and modify another thread properties if needed.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
while (!worker.CancellationPending)
{
// do task 1 as per the timer1 interval
// do task 2 as per such and such .....
// if I call ChangeInterval here I'll be fiddling with another thread when
// this is still in progress
// that a full loop, Progress will be reported now
}
}
private void backgroundWorker1_ProgressChanged(object sender,ProgressChangedEventArgs e)
{
// Now as the Do work is not in progress
// do something
// check if the user wanted to change the interval ?
// if yes then
ChangeInterval(6000);
// here the progress reporting is done so it will go back to DoWork with the
// NewInterval Value in place and the timer enabled
}
private void ChangeInterval(int NewInterval)
{
timer1.Enabled =false;
timer1.Interval = NewInterval;
timer1.Enabled = true;
}
Try invoke your activate method with the UI Thread's Dispatcher. (Assuming Win Forms?)
this.Invoke(new Action(activate));
Reason is that your timer is a UI control and you're updating the Interval on a separate thread. This will throw a Cross-Thread exception.
Why don't you see the exception? When the DoWork method in your BackgroundWorker throws an exception, it will be propogated to the Completed method. So you should always look at e.Error to see if an exception occurred.
private void Completed(object sender, RunWorkerCompletedEventArgs e)
{
if(e.Error != null)
{
// Oh no something went wrong...
}
running = false;
}
It took me a while, but I found out what was wrong. I'll post you a working code, just in case someone will have the same problem.
public partial class Form1 : Form
{
public int ticks = 0;
public bool running = false;
public bool push = false;
public Form1()
{
InitializeComponent();
timerTest.Tick += new EventHandler(timerTest_Tick);
timerTest.Interval = 1000;
timerTest.Start();
}
private void buttonTest_Click(object sender, EventArgs e)
{
push = true;
}
private void timerTest_Tick(object sender, EventArgs e)
{
ticks++;
labelTest.Text = ticks.ToString();
if(running == false)
{
running = true;
backgroundWorkerTest.RunWorkerAsync();
}
}
public void activate()
{
ZmienIntervalNaAwaryjny = true;
}
public bool ZmienIntervalNaAwaryjny = false;
private void DoWork(object sender, DoWorkEventArgs e)
{
if(push == true)
{
activate();
}
}
private void Completed(object sender, RunWorkerCompletedEventArgs e)
{
if(ZmienIntervalNaAwaryjny == true)
{
timerTest.Stop();
timerTest.Interval = 12000;
timerTest.Start();
}
ZmienIntervalNaAwaryjny = false;
running = false;
}
}
i am getting this exception "The function evaluation was disabled because of an out of memory exception" from this line of code.
this.pbErrorSign.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
I have actually added a background image and many other images like to warning image and picture boxes instead of buttons to make attractive GUI. Program was running fine some time ago and now its giving me this.... help plz
following code is from designer.
this.pbErrorSign.BackColor = System.Drawing.Color.Transparent;
this.pbErrorSign.BackgroundImage = global::SAMS.Properties.Resources.ErrorSign3;
this.pbErrorSign.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.pbErrorSign.Location = new System.Drawing.Point(69, 121);
this.pbErrorSign.Name = "pbErrorSign";
this.pbErrorSign.Size = new System.Drawing.Size(30, 30);
this.pbErrorSign.TabIndex = 1;
this.pbErrorSign.TabStop = false;
following is the code of form named as errorDialogForm
public partial class ErrorDialogForm : Form
{
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
this.Capture = true;
}
public ErrorDialogForm()
{
InitializeComponent();
}
public string LabelText
{
get
{
return this.lblError.Text;
}
set
{
this.lblError.Text = value;
}
}
private void pbOkButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void pbOkButton_MouseEnter(object sender, EventArgs e)
{
this.pbOkButton.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.purpleOkButton));
}
private void pbOkButton_MouseLeave(object sender, EventArgs e)
{
this.pbOkButton.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.blueOkButton));
}
private void ErrorDialogForm_Enter(object sender, EventArgs e)
{
this.Close();
}
private void ErrorDialogForm_Deactivate(object sender, EventArgs e)
{
this.Close();
}
private void ErrorDialogForm_FormClosing(object sender, FormClosingEventArgs e)
{
this.Hide();
this.Parent = null;
e.Cancel = true;
}
}
The function evaluation was disabled because of an out of memory exception
That's a debugger notification, it is simply telling you that it isn't going to show you anything because the program crashed with OOM. Very high odds that the debugger will crash as well when that happens. The real problem is the OOM exception you got that caused the debugger to stop the program.
this.pbOkButton.BackgroundImage = Properties.Resources.purpleOkButton;
That's the statement that caused the crash. You do this in events that fire very frequently as you move the mouse around. What is not so obvious is that this statement creates a new Bitmap object. The old ones are not being disposed. That makes the memory usage of your program rapidly climb with low odds that the garbage collector can do anything about it because you don't allocate any other objects. The OOM kaboom is pretty inevitable.
The proper fix is to create these bitmaps only once:
private Image purpleOk;
private Image blueOk;
public ErrorDialogForm()
{
InitializeComponent();
purpleOk = Properties.Resources.purpleOkButton;
blueOk = Properties.Resources.blueOkButton;
pbOkButton.BackgroundImage = blueOk;
}
private void pbOkButton_MouseEnter(object sender, EventArgs e)
{
this.pbOkButton.BackgroundImage = purpleOk;
}
private void pbOkButton_MouseLeave(object sender, EventArgs e)
{
this.pbOkButton.BackgroundImage = blueOk;
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
purpleOk.Dispose();
blueOk.Dispose();
base.OnFormClosed(e);
}
I have a singletone form that can be opened from a ribbon button or that will check every minute whether it should be open after passing a few conditional checks.
When opening the form from the ribbon button, it works correctly every time.
When opening on the timer, the form does not get rendered correctly, any place a control should be is just displayed as a white rectangle. Screenshots below.
ThisAddIn.cs
using Timer = System.Timers.Timer;
public partial class ThisAddIn
{
private Timer ticker;
private void ThisAddIn_Startup(object sender, System.EventArgs e) {
ticker = new Timer(5 * 60 * 1000);
ticker.AutoReset = true;
ticker.Elapsed += new System.Timers.ElapsedEventHandler(checkForOverdue);
ticker.Start();
}
private void checkForOverdue(object sender, System.Timers.ElapsedEventArgs e)
{
bool overdue = false;
foreach (Reminder reminder in reminders)
{
DateTime now = DateTime.Now;
if (reminder.time <= now)
{
overdue = true;
break;
}
}
if (overdue)
{
RemindersList form = RemindersList.CreateInstance();
if (form != null)
{
form.Show();
}
}
}
}
Ribbon.cs
public partial class Ribbon
{
private void reminderListButton_Click(object sender, RibbonControlEventArgs e)
{
RemindersList form = RemindersList.CreateInstance();
if (form != null)
{
form.Show();
}
}
}
RemindersList.cs
public partial class RemindersList : Form
{
private static RemindersList _singleton;
private RemindersList()
{
InitializeComponent();
this.FormClosed += new FormClosedEventHandler(f_formClosed);
}
private static void f_formClosed(object sender, FormClosedEventArgs e)
{
_singleton = null;
}
public static RemindersList CreateInstance(List<Reminder> rs)
{
if (_singleton == null)
{
_singleton = new RemindersList(rs);
_singleton.Activate();
// Flash in taskbar if not active window
FlashWindow.Flash(_singleton);
return _singleton;
}
else
{
return null;
}
}
}
EDIT - SOLUTION
Per sa_ddam213's answer, I changed out the System.Timers.Timer for a Windows.Forms.Timer and it's now working just how I wanted.
Code changes:
ThisAddIn.cs
using Timer = System.Windows.Forms.Timer;
public partial class ThisAddIn {
private void ThisAddIn_Startup(object sender, System.EventArgs e) {
ticker = new Timer();
ticker.Interval = 5 * 60 * 1000;
ticker.Tick += new EventHandler(checkForOverdue);
ticker.Start();
}
// Also needed to change the checkForOverdue prototype as follows:
private void checkForOverdue(object sender, EventArgs e)
}
You can't touch UI controls/elements with any other thread than the UI thread, in your case the System.Timer is running on another thread and the window will never open
Try switching to a Windows.Forms.Timer
Or invoke the call back to the UI thread.
private void checkForOverdue(object sender, System.Timers.ElapsedEventArgs e)
{
base.Invoke(new Action(() =>
{
/// all your code here
}));
}
I suspect that the timer event handler is not launched on the UI thread, which could cause all sorts of problems. I would check that first and ensure that the UI stuff is actually done on the UI thread.