I have a problem when I call LyncClient.Get() from a Windows Service project, knowing that it works well if I test on a console application.
var lyncClient = LyncClient.GetClient();
Dictionary<PublishableContactInformationType, object> statusData =
new Dictionary<PublishableContactInformationType, object>
{
{PublishableContactInformationType.LocationName, _position},
{PublishableContactInformationType.Availability, ContactAvailability.Busy}
};
The exception I get is:
Microsoft.Lync.Model.ClientNotFoundException: The host process is not running
at Microsoft.Lync.Model.LyncClient.EnsureOI ()
to Microsoft.Lync.Model.LyncClient.GetClient (Boolean sideBySideLync)
When doing research I read that in Windows service, we cannot get the Lync client by calling GetClient() because the service process and Lync process are in different sessions, that's why I'm trying to work with UCMA or UCWA but I do not understand how it works!
What I am trying to do in my application is to change the position of the skype user from a service. As it is not possible to do it with Lync Client SDK, I have to work with UCWA SDK but I can't find an example that i can follow him, A suggestion !
You are not talking about UCMA, you are talking about the Lync Client SDK.
You can think of the SDK's as such:
Lync Client SDK
This SDK allows you to remote control the standard "Lync Client". You can use this SDK to automate the Lync Client for a user to do whatever you can to do OR to extend the functionality of the Lync Client (kind-of limited). To use this SDK the Lync Client must be running in the user you wish to automate / extend. You can't really run it in a windows service context.
Also all Lync Client applications "share" the one Lync Client "session".
There is an option to run the Lync Client SDK in a "side by side" mode, but that mode is very very limited (i.e. no UI) and in most cases is not that useful.
UCMA
This SDK is a SIP endpoint SDK. It allows you to create and use two main type types of SIP endpoints:
User Endpoints
Trusted Application Endpoints
With sip endpoints you can do almost everything that a Lync Client SDK can do when automating the Lync Client (i.e. make calls, answer calls, set presence, subscribe to presence changes, etc, etc). There are some limitations, no video call support. Makes it harder to handle some situations.
UCMA allows you to create "trusted applications" that allow you to create sip endpoints used to extend S4B infrastructure. "trusted applications" / "trusted application endpoints" are "trusted" within S4B and are allowed to do things that you can't normally do with a simple UCMA application e.g. IVR
So it depends on what you are trying to do depends on what SDK you should use.
UCMA applications can be used in windows service applications.
UCWA is a web SDK version of UCMA (kind-of). The UCWA is a lot more limited than the UCMA SDK but UCWA works for Skype for Business Online whereas the UCMA doesn't directly work with Skype for Business Online. You can get UCMA working with Skype for Business Online using federation but that requires on-premise S4B setup federated to Skype for Business Online which is a lot of work.
Update:
To answer the comment question, location is part of the "presence". So what you need to do to set the location is to set the current presence with a location. For UCWA, see this MSDN link on setting the presence. Following the example, change which link you use to the "location" href and post something like:
{"location":"my new location"}
Why do you do it using a service? You could do it with a small console application that would be running in the background and invisible, and started at session startup.
This way you wouldn't need to know the user's login/password, you only need to poll in your code to wait for the Skype for Business client to be started (which I assume would be shortly after the session start)
Here is an example of what I mean :
class Program
{
[DllImport("user32.dll")]
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("Kernel32")]
private static extern IntPtr GetConsoleWindow();
const int SW_HIDE = 0;
static void Main(string[] args)
{
// Let's hide the console window first ...
IntPtr hwnd;
hwnd = GetConsoleWindow();
ShowWindow(hwnd, SW_HIDE);
// I recommend you start a separate thread from here, I removed it for the sake of simplicity
Boolean clientConnected = false;
while (!clientConnected)
{
try
{
LyncClient lyncClient = LyncClient.GetClient();
clientConnected = true;
// Do your stuff here...
}
catch (ClientNotFoundException ex)
{
// Client not found : the client is probably not running...
// There is nothing to do besides wait and expect to have the user starting his client...
clientConnected = false; // not needed, just to highlight the fact that we are not connected yet
}
// Don't forget to make your application sleep/do nothing on regular intervals to avoid taking 100% CPU time while you are polling
}
}
Of course users could manually kill the application by looking at their Task Manager, but most end users don't do that.
Related
We are building a presence system for our Xamarin.Forms app that utilizes Firebase as it's backend.
Early in development we took the decision to use a wrapper library for the Realtime Database REST API (https://github.com/step-up-labs/firebase-database-dotnet) instead of using the native libraries for IOS & Android.
So far it has saved a great deal of time but now we are running into problems implementing a onDisconnect like system.
I have been digging in the Android and JS firebase libraries on github and found that the client libraries send a specific action parameter shown below. They seem to pass the constant "o" to indicate a onDisconnect push.
private static final String REQUEST_ACTION_ONDISCONNECT_PUT = "o";
...
#Override
public void onDisconnectPut(List<String> path, Object data, RequestResultCallback onComplete) {
this.hasOnDisconnects = true;
if (canSendWrites()) {
sendOnDisconnect(REQUEST_ACTION_ONDISCONNECT_PUT, path, data, onComplete);
} else {
onDisconnectRequestQueue.add(
new OutstandingDisconnect(REQUEST_ACTION_ONDISCONNECT_PUT, path, data, onComplete));
}
doIdleCheck();
}
Is there any way you can send this action parameter with the Firebase Realtime Database REST api?
Thank you for your time.
Cheers
The native Firebase Realtime Database SDKs for iOS, Android and Web use a persistent Web Socket to keep an open connection between each client and the server. The server uses this Web Socket to detect when the client disconnects, and when that happens it will execute any onDisconnect handlers that the client may have attached.
The Firebase Realtime Database's REST API is connectionless, as it uses regular HTTP(S) calls for the traffic between the client and server. There is no way to attach onDisconnect handlers through the REST API.
An app I'm designing uses the VpnService, along with the VpnService.Builder, classes to generate a VPN in order to block traffic from specific apps. According to the documentation over at developer.android.com, all apps should be allowed through the VPN until Builder.AddAllowedApplication or Builder.AddDisallowedApplication is called.
When my VPN service starts up, for some reason, all apps are being disallowed which is strange. As soon as I disconnect from the VPN, all apps become available again. I need to to allow all, unless otherwise specified (which is what the documentation says should be happening). I start the VPN by calling the following:
private string _sTag = typeof(VpnService).Name;
private VpnServiceBinder _objBinder;
private ParcelFileDescriptor _objVpnInterface = null;
private PendingIntent _objPendingIntent = null;
...
if (_objVpnInterface == null)
{
Builder objVpnBuilder = new Builder(this);
objVpnBuilder.AddAddress("10.0.0.2", 32);
objVpnBuilder.AddRoute("0.0.0.0", 0);
// Form the interface
_objVpnInterface = objVpnBuilder.SetSession("Squelch").SetConfigureIntent(_objPendingIntent).Establish();
// Disallow instagram as a test
objVpnBuilder.AddDisallowedApplication("com.instagram.android");
// Set flag
_bVpnIsRunning = true;
}
So in the above instance, instagram should be the only blocked app, but all traffic appears to be blocked (can't use the chrome app, facebook, etc). Is there something I am missing in regards to this? Should I be specifying something before/after establishing the interface? Any help or direction would be greatly appreciated!
Note: In case it matters, I am targeting android 6.0 and higher. I can provide more source if required.
addDisallowedApplication:
By default, all applications are allowed access, except for those denied through this method. Denied applications will use networking as if the VPN wasn't running.
AddDisallowedApplication excludes the application from your VPNService and allows it to continue to use the "non-VPN" networking stack.
addAllowedApplication:
Adds an application that's allowed to access the VPN connection
Note: You can use an allowed or disallowed list, but not both at the same time.
So lets say we want to "block" any Chrome package from accessing the normal networking stack and redirect any Chrome apps from accessing the network via our "blocking" VPN, we can add all Chrome app package names to our VPNService implementation.
Note: there are 4(?) different Chrome apps, alpha, beta, etc.... so lets just block any package that has the name chrome in it, not really ideal, but for an example it works.
using (var pm = Application.Context.PackageManager)
{
var packageList = pm.GetInstalledPackages(0);
foreach (var package in packageList)
{
if (package.PackageName.Contains("chrome"))
{
Log.Debug(TAG, package.PackageName);
builder.AddAllowedApplication(package.PackageName);
}
}
}
After you .Establish() the VPN connection, all Chrome applications networking will be redirected to your VPNService and thus blocked.
I'm working on an intranet website.
All users should get desktop popups from the webserver whenever something new is posted on the website.
I was looking to make my own windows service that would subscribe to the server ( Making use of something like SignalR ) and then this service would show a simple popup notifying the user whenever the server sends out a message.
But instead of building this myself i was wondering if something like this isn't already out there. I've been looking around a bit but couldn't find anything.
I'm mainly a web developer and have never built a windows service or C# desktop application so i would prefer using some existing code.
Does anyone know of such a thing ?
For building a Windows Service try Top Shelf: http://docs.topshelf-project.com/en/latest/
In general it is easy as one, two, three...
public class TownCrier
{
readonly Timer _timer;
public TownCrier()
{
_timer = new Timer(1000) {AutoReset = true};
_timer.Elapsed += (sender, eventArgs) => Console.WriteLine("It is {0} and all is well", DateTime.Now);
}
public void Start() { _timer.Start(); }
public void Stop() { _timer.Stop(); }
}
public class Program
{
public static void Main()
{
HostFactory.Run(x =>
{
x.Service<TownCrier>(s =>
{
s.ConstructUsing(name=> new TownCrier());
s.WhenStarted(tc => tc.Start());
s.WhenStopped(tc => tc.Stop());
});
x.RunAsLocalSystem();
x.SetDescription("Sample Topshelf Host");
x.SetDisplayName("Stuff");
x.SetServiceName("Stuff");
});
}
}
I'm working on an intranet website. All users should get desktop
popups from the webserver whenever something new is posted on the
website.
using timer is not a good technique over here as updates are not guaranteed in particular interval or session .but you can take that as an option based on the need.
I was looking to make my own windows service that would subscribe to
the server ( Making use of something like SignalR ) and then this
service would show a simple popup notifying the user whenever the
server sends out a message.
Yes exactly like a chat application that would frequently have messages and users get a pop up.ASP.NET SignalR is a library for ASP.NET developers that simplifies the process of adding real-time web functionality to applications. Real-time web functionality is the ability to have server code push content to connected clients instantly as it becomes available, rather than having the server wait for a client to request new data.
But instead of building this myself i was wondering if something like
this isn't already out there. I've been looking around a bit but
couldn't find anything.
References for SignalR Link1,Link2,Link3
I'm mainly a web developer and have never built a windows service or
C# desktop application so i would prefer using some existing code.
Making C# desktop or windows service is not a big deal as you already are a programmer.Some existing codes for updations pop up is here.
for the signalr Server side, I would suggest you use a C# winform.
for the client side, you can use JavaScript inside any html file to 'receive' the message from the signalr Server, then you can popup an alert message or whatever you want, however, in this case you have to make sure the users are browsing that html file in a browser, otherwise the message won't be received.
there's no ready code since signalr support different types of servers as well as different types of clients, I believe you need to write your own code. Actually Signalr is quite easy to use, write your own code may be faster than using the others.
This question: SignalR Chat App in WinForm With Remote Clients looks like it might point you inthe right direction. Specifically this article:
https://damienbod.wordpress.com/2013/11/01/signalr-messaging-with-console-server-and-client-web-client-wpf-client/
you could probably use DesktopToast: https://github.com/emoacht/DesktopToast
or Growl: http://www.growlforwindows.com/
I have successfully compiled and run Windows Service with WCF. With installutil, the Windows Service is successfully getting installed and started. I think I am at the end of my development and just need to invoke/call the method DoJobs() inside WCF. I don't need any user interaction and so I don't have any Windows forms or anything. I just want to invoke/call my WCF function programmatically just after serviceHost.Open();
The base address in app.config file is
http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/
I am deploying my WCF from Windows service with the following code.
// Create a ServiceHost for the CalculatorService type and provide the base address.
serviceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
// Open the ServiceHostBase to create listeners and start listening for messages.
serviceHost.Open();
I have also added the service reference and created the below proxy, but not sure of its use.
WcfServiceLibrary1.WCFServiceRef.Service1Client
I have searched tutorials, the examples show how to invoke the WCF function on button_click event of any form after running Windows service. I just want to do that programmatically on start-up of Windows Service.
EDIT: The code inside my DoJobs() fetches the active tab url of firefox with DDE Client, which throws exception when done only in a Windows Service project but runs successfully when done in WCF project. Please see this for reference.
So I made a C#.Net solution with WCF called from a Windows Service and then I called DoJobs() inside Windows Service as shown below.
WcfServiceLibrary1.WCFServiceRef.Service1Client wcfObj = null;
...
protected override void OnStart(string[] args)
{
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(WcfServiceLibrary1.Service1));
serviceHost.Open();
if (wcfObj == null)
{
wcfObj = new WcfServiceLibrary1.WCFServiceRef.Service1Client();
wcfObj.DoJobs();
}
}
But, it makes the call happen at the windows service layer, and is throwing the same DdeClient exceptions.
Can the base address url help any way to programmatically invoke DoJobs() in Web-Service? OR there are some other solutions.
Any help is highly appreciated.
Thanks.
This is my aggregated answer from my various comments I made to your post and to Noctis's answer (specifically that we did not know you were using DDE in the OP):
You can't use Dynamic Data Exchange (DDE) in a Windows Service because the latter does not have a message pump. Also DDE requires a Window handle to be passed as a parameter to DDE functions. You can use DDE in programs which do have a message pump does as a WinForms app. See this article for more information
Once your GUI app is running you can either minimize it to a Sys Tray icon or hide the app completely so the user is unaware. Regardless of its visible nature you should have no problem utilising DDE since it will have a message pump.
Now it may be the case you could add a message pump to a Windows Service but I wouldn't recommend it because it falls into the category of because you can do a thing, does not mean you should do a thing. A topic for another time. It's very similar to a recent SO question about how to display a WinForm in a console app - by default you can't and if you managed to you end up with an odd hybrid with much re-inventing of wheels. Not to mention its an ugly hack.
In summary, my best advice is to proceed with a GUI app.
Assuming you have :
// I'm assuming this is your proxy?
var proxy = WcfServiceLibrary1.WCFServiceRef.Service1Client;
// All you need to do is :
proxy.DoJobs() ;
Having seen your update and Micky`s answers, I'm just wondering why you're using DDE. Not sure what your requirements look like, but you can always use your MSMQ to send messages and queue things.
I was tasked with building an application that would check email using MAPI. I made use of a wrapper class coded in cpp, which is accessed from c#. I realize that combining managed and unmanaged code is not necessarily the best path, but it was what I could get to work.
After getting it working, I was asked to make the application a service, so it could be run when the system was not logged in.
The client requires us to use MAPI, and is using Outlook 2007, but I would like it to be compatible with both x86 and x64 architecture. A separate program running on several workstations will be allowed to send mail using a single email address. The service will monitor this account, watching for new email from Exchange saying a message could not be delivered. When this happens, it will make a note in the database for future correction.
My understanding of how Extended MAPI works is that it uses the profile of the person logged in to access the Exchange Server. My question is whether the Exchange Server can be accessed through MAPI when nobody is logged into the system? If this is not possible, does OOM allow for access to a specific email account (or profile) when no user is logged in? Would one method be better than the other when predominantly using c#?
Below is a brief sample of how the wrapper class logs in. I added the second method, but never did get it to log in to a profile other than that of the current user's.
BOOL CMAPIEx::Login(LPCTSTR szProfileName, BOOL bInitAsService)
{
DWORD dwFlags=MAPI_EXTENDED | MAPI_USE_DEFAULT | MAPI_NEW_SESSION;
if(bInitAsService) dwFlags|=MAPI_EXPLICIT_PROFILE | MAPI_NT_SERVICE;
return (MAPILogonEx(NULL, (LPTSTR)szProfileName, NULL, dwFlags, &m_pSession)==S_OK);
}
BOOL CMAPIEx::Login(LPCTSTR szProfileName, LPCTSTR szProfilePassword, BOOL bInitAsService)
{
DWORD dwFlags=MAPI_EXTENDED | MAPI_EXPLICIT_PROFILE | MAPI_NEW_SESSION;
if(bInitAsService)
dwFlags|= MAPI_NT_SERVICE;
return (MAPILogonEx(NULL, (LPTSTR)szProfileName, (LPTSTR)szProfilePassword, dwFlags, &m_pSession)==S_OK);
}
Thank you for any suggestions.
You can dynamically create a temporary profile with the MSEMS service and configure it.
See http://support.microsoft.com/kb/306962?wa=wsignin1.0 and scroll to "Use the MAPI IProfAdmin interface"
Make sure the service runs under the identity of the mailbox owner.