Automatically Stop Windows Service at Uninstall - windows-services

When my service is installed I have a handler that starts the service after it has been installed.
private void InitializeComponent()
{
...
this.VDMServiceInstaller.AfterInstall += ServiceInstaller_AfterInstall;
}
private void ServiceInstaller_AfterInstall(object sender, InstallEventArgs e)
{
ServiceController sc = new ServiceController("MyService");
sc.Start();
}
I want to stop the service before it is uninstalled so I added an additional handler to InitializeComponent().
this.ServiceInstaller.BeforeUninstall += ServiceInstaller_BeforeUninstall;
and added the function:
private void ServiceInstaller_BeforeUninstall(object sender, InstallEventArgs e)
{
try
{
ServiceController sc = new ServiceController("MyService");
if (sc.CanStop)
{
sc.Stop();
sc.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped);
}
}
catch (Exception exception)
{}
}
But the service doesn't stop before uninstall. Am I using the ServiceController.Stop() function improperly?

Would something like below help you:
protected override void OnBeforeUninstall(IDictionary savedState)
{
ServiceController controller = new ServiceController("ServiceName");
try
{
if(controller.Status == ServiceControllerStatus.Running | controller.Status == ServiceControllerStatus.Paused)
{
controller.stop();
}
controller.WaitForStatus(ServiceControllerStatus.Stopped, new TimeSpan(0,0,0,15));
controller.Close();
}
catch(Exception ex)
{
EventLog log = new EventLog();
log.WriteEntry("Service failed to stop");
}
finally
{
base.OnBeforeUninstall(savedState);
}
}

This is the window I tried to prevent:
I have tested all the overrides available, and none of them are executed before the dialog box prompting to close the applications appear.
Not even the class constructor is early enough.
My conclusion is that, as the installer projects are, you cannot stop the service via code, before the dialog box.
Since there are no other ways to have code executed in the project, I don't see any way to accomplish this.
I really really wish it was different, since I badly need this myself, but there just isn't any "hook" available in the installer project, that enters early enough to solve the problem.
My best suggestion, is to make two installers.
One that acts as a wrapper for the second, and on install just starts the second installer as normal.
But on uninstall, it stops the service first, then uninstalls the second.
But this is too much of a hack for my liking, so I have not explored this further.

I wanted to do something similar, and ended up using this code in my installer project to handle when the BeforeUninstall event was triggered:
private void SessionLoginMonitorInstaller_BeforeUninstall(object sender, InstallEventArgs e)
{
try
{
using (ServiceController sv = new ServiceController(SessionLoginMonitorInstaller.ServiceName))
{
if(sv.Status != ServiceControllerStatus.Stopped)
{
sv.Stop();
sv.WaitForStatus(ServiceControllerStatus.Stopped);
}
}
}
catch(Exception ex)
{
EventLog.WriteEntry("Logon Monitor Service", ex.Message, EventLogEntryType.Warning);
}
}
The custom actions section of the project also had an action to uninstall the primary output of my Windows Service project. This worked for me and has given me a clean uninstall every time I've tested it.

Related

Alert shows empty message if called from task

Task<Void> task = new Task<Void>() {
public Void call() {
try {
// my task code
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
};
task.setOnSucceeded(event -> {
Platform.runLater(new Runnable() {
#Override
public void run() {
Alert alert = new Alert(AlertType.INFORMATION, "task success", ButtonType.OK);
alert.showAndWait();
}
});
});
In my above code i am trying to display alert message from success part of task.
I have deployed the application in a remote machine and accessing the same using remote desktop connection.
when i keep my remote desktop connection window minimised i get the alert message empty. (Yes i see the message when RDC window is open)
when i focus on parent container(stage) it refreshes and shows the correct message or just alt + tab few times also works. Tried various solutions to set modality, init stage, some vm args etc nothing seems to work.
any idea why this problem is? I understand task is a seperate thread and hence i have used platform.runlater? Have i done anything wrong? any alternative solutions?
Task runs on new thread as its performing a heavy operation.

CodenameOne Connection Request hangs when repeated

I have the following Codename One code for accessing a network resource. It is almost an exact copy of the Codename One tutorial for this use case.
public void executeRequest(){
String url = "http://www.random.net";
InfiniteProgress prog = new InfiniteProgress();
final Dialog dlg = prog.showInifiniteBlocking();
ConnectionRequest r = new ConnectionRequest() {
#Override
protected void postResponse() {
//handle changes to my form
}
#Override
protected void readResponse(InputStream input)
throws IOException {
//handle parsing data
}
#Override
protected void handleIOException(IOException err) {
super.handleIOException(err);
}
};
r.setUrl(url);
r.setPost(false);
r.addArgument("arg", "2");
r.setDuplicateSupported(true);
r.setDisposeOnCompletion(dlg);
NetworkManager.getInstance().addToQueue(r);
}
The first time I run it - no problem. If I try to "refresh" my data by calling the same method over again, the app will hang up with the InfiniteProgress dialog spinning forever. Its almost like the first network request is not ever really completing, and then the second one kind of conflicts. Any ideas what I'm doing wrong?
By default duplicate requests to the exact same URL are disabled, try invoking setDuplicatesSuppotred(true) on the connection request.
For future reference, what fixed this for me was to use
NetworkManager.getInstance().addToQueueAndWait(r);
instead. That cleared up most of my problems.
I stucked with the same problem and none of solutions worked. However, I did it this way:
final NetworkManager nm = NetworkManager.getInstance();
nm.setTimeout(3000);
then
protected void postResponse() {
...
nm.shutdown();
}
and call was made as
nm.addToQueueAndWait(request);
Maybe the fact that NetworkManager was made final did the job, but I put "shutdown" just for sure. It worked for me

Uncaught exception no application instance

i am working on UI-application that handles multiple entry point approach.
I am referring the link and try for make a demo.
Here is the code :-
public class DemoApp extends UiApplication implements RealtimeClockListener
{
private static DemoApp dmMain ;
private static final long dm_APP_ID = 0x6ef4b845de59ecf9L;
private static DemoApp getDemoApp()
{
if(dmMain == null)
{
RuntimeStore dmAppStore = RuntimeStore.getRuntimeStore();
dmMain = (DemoApp)dmAppStore.get(dm_APP_ID);
}
return dmMain;
}
private static void setDemoApp(DemoApp demoAppMain)
{
RuntimeStore dmAppStore = RuntimeStore.getRuntimeStore();
dmAppStore.remove(dm_APP_ID);
dmAppStore.put(dm_APP_ID, demoAppMain);
}
public static void main(String[] args)
{
Log.d(" Application argument "+args);
if( args.length > 0 && args[ 0 ].equals( "Demo_Alternate" ) )
{
Log.d("Running Demo_Alternate #### Running Demo_Alternate #### Running Demo_Alternate");
dmMain = new DemoApp();
dmMain.enterEventDispatcher();
setDemoApp(dmMain);
}
else
{
Log.d("Running Demo #### Running Demo #### Running Demo #### Running Demo");
getDemoApp().initializeMain();
}
}
public DemoApp()
{
this.addRealtimeClockListener(this);
}
private void initializeMain()
{
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run()
{
try
{
pushScreen(new DemoMainScreen());
} catch (Exception e)
{
Log.e(e.toString());
}
}
});
}
public void clockUpdated()
{
showMessage("DemoAppClock Updated");
Log.d("DemoAppClock Updated #### DemoAppClock Updated #### DemoAppClock Updated");
}
private void showMessage(String message)
{
synchronized (Application.getEventLock())
{
Dialog dlg = new Dialog(Dialog.D_OK, message, Dialog.OK, null, Manager.FIELD_HCENTER);
Ui.getUiEngine().pushGlobalScreen(dlg, 1, UiEngine.GLOBAL_QUEUE);
}
}
}
:- I have created an alternate entry point named Demo_Alternate , that runs at start up.
:- If the application has separate entry points, that means a separate process the link
Now my questions are :-
While running the code, I am getting "Uncaught exception : no application instance".
I just want to make one application instance - don't want separate processes.
Can we use (Application) Singleton approach for alternate entry-points?
Only looked briefly at this code, but see an obvious problem here:
dmMain.enterEventDispatcher();
setDemoApp(dmMain);
enterEventDispatcher never returns, so you never put your Application instance in RuntimeStore.
I suggest you review the following KB article, you might find its approach to accessing a RuntimeStore maintained object easier to use. Or not.
Singleton using RuntimeStore
Update
If this solution does not work, please update your original post with the corrected code.
I certainly agree with Peter, that calling setDemoApp(dmMain) after enterEventDispatcher() means it doesn't get called.
That said, I think you have a more basic misunderstanding here.
Using alternate entry points will create multiple processes. See here for more.
But, you say that you don't want separate processes. Can you tell us why not?
Separate BlackBerry processes that are designed to work together can still share data, using the RuntimeStore, for example.
Maybe you could tell us more about what your "Demo" and "Demo Alternate" are supposed to do.

Custom Check in policy in TFS?

We have some xml files in the our project and whenever we check-in these xml files into TFS, We have make sure before checking-in that we have added those xml files to proprietary application.
Now the new employees more often forget to add files into proprietary application before check-in and this is getting serious...
We want kinda confirmation dialog (a reminder) asking the developers if they have added the xml files into the app. If yes then check-in otherwise keep it checkedout...
Please suggest if such thing is possible and any relevant code or links will be really appreciated.
It's not appropriate to raise UI in a custom check-in policy - the lifecycle of a check-in policy is very short, and they will be evaluated frequently and not necessarily in a UI context or on the UI thread.
Can you determine programmatically whether the appropriate XML files are being checked in? If so, you could create a custom check-in policy that fails if the XML files are not pended for add.
Gated Check-in may be the best solution to this problem: does the build fail if these XML files do not exist - or would unit tests fail if these files are missing? If so, this is a perfect candidate for Gated Check-in, which will prevent these check-ins from occurring.
I would create a custom build template that checks for these xml files. Make it a gated check-in and you've got your solution.
The Evaluate method is supposed to be quick and should not show UI, but there is an event on the policy that triggers when the user interacts with the policy called Activate, this is a good moment to show UI and communicate with the policy. You could do something like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace JesseHouwing.CheckinPolicies
{
using System.Windows.Forms;
using Microsoft.TeamFoundation.Client.Reporting;
using Microsoft.TeamFoundation.VersionControl.Client;
[Serializable]
public class ConfirmPolicy :PolicyBase
{
private AffectedTeamProjectsEventHandler _affectedTeamProjectsEventHandler;
private EventHandler _checkedPendingChangesEventHandler;
public ConfirmPolicy()
{
}
public void StatusChanged()
{
_userconfirmed = false;
OnPolicyStateChanged(Evaluate());
}
public override void Initialize(IPendingCheckin pendingCheckin)
{
_affectedTeamProjectsEventHandler = (sender, e) => StatusChanged();
_checkedPendingChangesEventHandler = (sender, e) => StatusChanged();
base.Initialize(pendingCheckin);
_userconfirmed = false;
pendingCheckin.PendingChanges.AffectedTeamProjectsChanged += _affectedTeamProjectsEventHandler;
pendingCheckin.PendingChanges.CheckedPendingChangesChanged += _checkedPendingChangesEventHandler;
}
protected override void OnPolicyStateChanged(PolicyFailure[] failures)
{
_userconfirmed = false;
base.OnPolicyStateChanged(Evaluate());
}
public override void Activate(PolicyFailure failure)
{
if (MessageBox.Show("Confirm the policy?", "Policy Check", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
_userconfirmed = true;
base.OnPolicyStateChanged(Evaluate());
}
}
public override PolicyFailure[] Evaluate()
{
if (_userconfirmed == true)
{
return new PolicyFailure[0];
}
else
{
return new PolicyFailure[]{new PolicyFailure("User must confirm", this)};
}
}
public override string Description
{
get { throw new NotImplementedException(); }
}
public override bool Edit(IPolicyEditArgs policyEditArgs)
{
return true;
}
public override string Type
{
get
{
return "User Confirm";
}
}
public override string TypeDescription
{
get
{
return "User Confirm";
}
}
public override void Dispose()
{
this.PendingCheckin.PendingChanges.AffectedTeamProjectsChanged -= _affectedTeamProjectsEventHandler;
this.PendingCheckin.PendingChanges.CheckedPendingChangesChanged -= _checkedPendingChangesEventHandler;
base.Dispose();
}
}
}
I haven't tested this exact code yet, it might need some tweaking, but this is the general thing to do. Right now it triggers on a change in the files being checked in, but you can subscribe to any of the other events as well (work item changes) or trigger your own evaluation of the project each time Evaluate is called.
Or you can just trigger the confirm once per checkin cycle. it's all up to you. You could even do a "Click to Dismiss" and skip the Messagebox altogether. Just set _userConfirmed=true and fire the PolicyStateChanged event.

C#: Excel 2007 Addin, How to Hook Windows Activate and Deactivate Events

I am writing an Excel 2007 Addin. using VS2008 and .net 3.5, C#.
I catched Microsoft.Office.Interop.Excel.Application's WindowActivate and WindowDeActivate events.
It was surprised to know that WindowActivate and Deactivate only triggers when i switch between two Excel Windows. if i switch to notepad, i expect Deactivate to be triggered, but its not happening. same way from notepad if i switch to excel window, i expect Activate to be triggered but its not happening. It looks like the behaviour indicates windows are MDI-Child windows.
Now what i want to do is get HWnd of Excel's Mainwindow and hook Window Activate and Deactivates using dllimport features.
Can anyone guide to me on this.
Regards
I solved similar problem when writing Excel addin. No dll import is needed. I solved this issue using System.Windows.Forms.NativeWindow class.
At first, I made my own class inherited from NativeWindow class and declared two events Activated and Deactivate in it and finaly overrided WndProc() method to rise these events when message WM_ACTIVATE is passed to the WndProc method. According to "Message" parameter WParm is Excel window activated or deactivated.
public class ExcelWindow: NativeWindow
{
public const int WM_ACTIVATED = 0x0006;
public ExcelWindow():base(){}
//events
public event EventHandler Activated;
public event EventHandler Deactivate;
//catching windows messages
protected override void WndProc(ref Message m)
{
if (m.Msg== WM_ACTIVATED)
{
if (m.WParam.ToInt32() == 1)
{
//raise activated event
if (Activated!=null)
{
Activated(this, new EventArgs());
}
}
else if (m.WParam.ToInt32() == 0)
{
//raise deactivated event
if (Deactivate!=null)
{
Deactivate(this, new EventArgs());
}
}
}
base.WndProc(ref m);
}
}
Then I made in my addin class field "ExcelWindow myExcelWindow" and added following code to OnConnection method of my addin:
ExcelWindow myExcelWindow;
void Extensibility.IDTExtensibility2.OnConnection(object application, Extensibility.ext_ConnectMode ConnectMode, object AddInInst, ref Array custom)
{
excel = application as Excel.Application;
myExcelWindow = new ExcelWindow();
myExcelWindow.AssignHandle(new IntPtr(excel.Hwnd));
myExcelWindow.Activated += new EventHandler(myExcelWindow_Activated);
myExcelWindow.Deactivate += new EventHandler(myExcelWindow_Deactivate);
//addin code here
}
void myExcelWindow_Activated(object sender, EventArgs e)
{
//do some stuff here
}
void myExcelWindow_Deactivate(object sender, EventArgs e)
{
//do some stuff here
}
I hope this will help you.
Finally I found one solution..that works only Activate/Deactivate.
This is not the perfect way to do it. But I did not find any good alternative.
This method uses polling. I have to call following function in each 10 ms interval to check focus in/out.
public static bool ApplicationIsActivated()
{
var activatedHandle = GetForegroundWindow();
if (activatedHandle == IntPtr.Zero)
{
return false; // No window is currently activated
}
var procId = Process.GetCurrentProcess().Id;
int activeProcId;
GetWindowThreadProcessId(activatedHandle, out activeProcId);
return activeProcId == procId;
}

Resources