I'm playing with Microsoft's UWP AppServiceBridgeSample (here).
It is working well, but I would like to get rid of the console window of the BackgroundProcess application. The reason for this is that my BackgroundProcess starts another Win32 desktop application and works only as a mediator, so I don't want to disturb users with a console window. (Yes, it can be minimized, but I would rather not show it at all).
I have tried to hide it using the API mentioned here, but with no luck, the console window is still visible. Neither did switching the project's output type from Console Application to Windows Application.work.
Another thing I have tried was to create other BackgroundProcess project as a Windows application. It runs fine until I call AppServiceConnection.OpenAsync(), which causes the BackgroundProcess application to exitstrong text, thus the connection to UWA is not available.
static async void ThreadProc()
{
try
{
AppServiceConnection connection = new AppServiceConnection();
connection.AppServiceName = "CommunicationService";
connection.PackageFamilyName = Windows.ApplicationModel.Package.Current.Id.FamilyName;
connection.RequestReceived += Connection_RequestReceived;
AppServiceConnectionStatus status = await connection.OpenAsync();
//status check etc. ...
}
catch(Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
It seems that opening the AppService connection is only possible from a console app.
So here are my two questions:
Is it, by any chance, even possible to hide the background process' console window?
Can I use the background process as a Windows application, without AppServiceConnection failing during OpenAsync calls?
Re 1: Go into the project settings and change the output type from Console to Windows app. Also make sure the Main() function doesn't exit until you are done with the background process. Here is a better sample that shows this with a Windows Application:
https://stefanwick.com/2017/05/26/uwp-calling-office-interop-apis/
Re 2: AppServiceConnection works the same way from a windowed application as well. Make sure you add the right reference to the Windows.winmd to be able to build. If you have trouble with that, please post a specific question with details of the problem you are seeing
Related
We are currently working on a project in UWP where we have to start an external application to modify some documents.
We looked into the Windows.System.Launcher API but it seems that we need more than what it can offer us.
As we launched the application from a file, we use the LaunchFileAsync method, based on the example given by the MSDN :
async void DefaultLaunch()
{
// Path to the file in the app package to launch
string imageFile = #"images\test.png";
var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(imageFile);
if (file != null)
{
// Launch the retrieved file
var success = await Windows.System.Launcher.LaunchFileAsync(file);
if (success)
{
// File launched
}
else
{
// File launch failed
}
}
else
{
// Could not find file
}
}
So far, the example suit us well but we also need to be warned when the user is done with the file. The best would be to be able to give the launcher a callback method.
We haven't found anything like that yet in the documentation. Is this even possible ? Do we need to use another solution ?
TL;DR : Is there a solution to open another application from a UWP app and wait for it to return a result object ?
If the external app is also a UWP app then Launcher.LaunchUriForResultsAsync is designed for this. It will launch the target app then wait for the app to call back with the results.
See Launch an app for results for a full walkthrough of how this works.
If the target app isn't a UWP app then you can implement the same thing yourself: both apps declare a protocol. The client launches the server with the server's protocol. When the server's done it notifies the caller by launching the client's protocol.
You might also want to look into App Services which allow a UWP server app to expose a REST-like service to clients on the local system.
The app process isolation model means you can't do this from a UWP app. As you just want to know when an arbitrary program has finished you could write this in traditional .net/win32 and include that in your UWP app via the desktop bridge.
link app with windows process so that when user terminated or end the process it says used by another process and also need to insert it into system file like shutdown file using c sharp so that my app never end or terminates
i tried that material but not usefull
this.ShowInTaskbar = false;
I also tried that code in click:
WindowsImpersonationContext ctx = null;
if (!WindowsIdentity.GetCurrent().IsSystem)
{
ctx = WindowsIdentity.Impersonate(System.IntPtr.Zero);
}
string thisuser = WindowsIdentity.GetCurrent().Name;
But have a look at image it is still present in process, what I want is that my process never stops.
what I want is that my process never stops.
To ensure that your process is always running and is started when Windows boots it's easiest to create a windows service instead. It will probably still show up somewhere in task manager and could be killed manually by the user. But windows will try to keep it running.
How to create a service:
https://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx
And if you need other programs to communicate with your service I find it easy to use a WCF service instead.
https://msdn.microsoft.com/en-us/library/bb386386.aspx
I have a windows service called MainService, which is used to monitor SubServices. The SubServices are actually some console applications and started by the MainService via Process.Start() method. Example code:
var subServiceProcess = Process.Start(subService.ServicePath);
The SubServices work perfectly until one of them needs to start another desktop application like the MainService does. Example code:
var desktopApplicationProcess = Process.Start(desktopApplicationPath);
The desktopApplicationProcess is created and we can see it in the taskmanager. However, its GUI doesn't show.
I've tried to run the sub service manually, and then the desktop runs correctly. So, I guess this is caused by that the sub service is started by the MainService.
Can anybody give me some sugguestion?
Thanks a lot~
Have you allowed the Service to interact with the desktop?
I created a winform (monitoring) application using VS 2005 (c#), and now, I have a problem when this application crashes for some reason, I have to be sure that it will be restarted automatically.
How can I resolve this? (maybe by using windows services application?)
Thanks
Yes, a creating a Windows Service would work as you can set it to automatically restart if it crashes but a better way would be to prevent it crashing in the first place! Is there a specific reason it crashes?
With good error handling and reporting you can write it so that it simply reports any errors that occur and carries on, which IMHO would be the best route to go
Consider this:
http://msdn.microsoft.com/en-us/library/cc303699.aspx
[DllImport("kernel32.dll")]
public static extern int RegisterApplicationRestart(
[MarshalAs(UnmanagedType.BStr)] string commandLineArgs,
int flags);
Minimum supported server
Windows Server 2008
http://msdn.microsoft.com/en-us/library/aa373347(VS.85).aspx
Creating a Windows service is a very good idea for any long-running background process for many reasons, however re-starting a crashed application is not one of them!
You should work out why the application is crashing and prevent it from happening.
By all means, also convert your application to a Windows service - you will see many benefits, however the correct way to solve your problem is to fix the application crash in the first place.
For*strong text* a watcher app.
You should create a timer on the windows service and code something like this in the timer tick event:
Process[] procs = Process.GetProcessesByName("you app name");
if (procs.Length == 0)
Process.Start("your app filename");
if you really cant do anything about the crash problem i would recommend a try-catch instead of a watcher. (Dont forget to re-throw handled major exceptions)
[STAThread]
static void Main()
{
try
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
catch(Exception ex)
{
//log the exception here
Application.Restart();
}
}
Since you say that you use a Windows Forms application you cannot use a Windows Service for that, since a Windows Service is not allowed to have a GUI.
What I would do it that I would create an invisible "watchdog" application which monitors the process and automatically restarts it when it crashes.
Thanks you all, the solution I choose is : in the main program I add an exception events (UnhandledExceptionEventHandler & ThreadExceptionEventHandler see above) in these events I restart the program (also putting log & email to trace errors). And for the reboot problem I add registry key in [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run] with my application path to be sure that my application will be restarted after the windows reboot ;)
You can put a try catch block around the code that is most likely causing the crash. Then write the exception message to a log file. You can also set a debug point in the catch block to see other details like call stack, etc.
currently I’m creating 2 applications (app A and B) for Windows Mobile 5.0 and using Compact Framework 2.0. App A is the main application and B is the sub application.
Below is the flow:
Start app A.
App A will start app B.
App B will do some process.
App B will kill app A.
App B will patch/upgrade app A. (ala update manager)
App B will restart app A.
App B will exit.
Now I’m stuck in killing app A. I did tried using OpenNETCF ProcessEntry Kill() function. When calling Kill(), it made the device crash.
I did tried using the SendMessage(hWnd, WM_CLOSE, 0, 0) funct where WM_CLOSE will have the ProcessEntry.ProcessID value and I didn’t assigned any value to hWnd variable. But it didn’t terminate app A. Did I assign the wrong value?
I also did tried using
Process.GetProcessById(processEntry.ProcessID).CloseMainWindow()
, but failed as GetProcessById only accepts int32 value. Note that processEntry.ProcessID value is larger than int32 value and GetProcessByName() is not supported in Compact Framework.
Could you help me in killing app A through app B?
Thanks.
You may try native code, using the TerminateProcess function:
processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, Pid);
success = TerminateProcess(processHandle, 0);
The above code is from a Task Manager at Code Project.
However if you are writing the code for both the applications, it will be better if you designed a communication mechanism between the two applications. In this way you will send a message from app B to app A and app A will kill itself.
Stormenet, I hardcoded the application's name. Then I generate an object to get all the available process using OpenNETCF.ToolHelp.ProcessEntry[ ] = ProcessEntry.GetProcesses();
then in a foreach loop, if the ProcessEntry object eg: processEntry.ExeFile matches with the "applicationName", i shall use processEntry.Kill().
I think you can get the OpenNETCF.ToolHelp dll from the OpenNETCF site.
Note that if the application you are trying to kill is holding open ports or other system resources then it might hang on exiting. Ensure everything is effectively disposed when the form closes.
This can be acheived by putting stuff in the:
public void Dispose(bool disposing)
{
}
block of code in the designer of your main form, or if you've chosen a less Windows Form centric architecture then just run your dispose calls following Application.Run(new YourForm()) and it will execute after the application has closed.
If you're feeling really lazy then just setup some destructors (otherwise known as finalizers ~) but be careful about navigating through relationships between managed objects at "destruct" time if you do this as there is no guarantee as to which order objects will be destroyed.
ctacke, I think app A crashes due to some of the running threads are not closed properly or still running at the background as app A will run multiple threads during app B executing the Kill( ) function.
If I use the SendMessage(hWnd, WM_CLOSE, 0, 0) function, it will not crash the device (which is a good thing)... it only closes the form. (app A contains multiple forms eg: frmLogin and frmMainMenu). hmmm maybe I need to point hWnd to the right form...
Now I'm taking a different route.
After downloading the patch and put it in a temp folder, I'll do a soft reset using OpenNETCF.WindowsCE.PowerManagement.SoftReset().
App B will be launched upon startup, then it will scan the temp folder and replace app A with the new version.