Lync API: How to send instant message to contact by email address? - c#

I have the email address of a Lync user and want to send him an instant message.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Conversation;
namespace Build_Server_Lync_Notifier
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: bsln.exe <uri> <message>");
return;
}
LyncClient client = Microsoft.Lync.Model.LyncClient.GetClient();
Contact contact = client.ContactManager.GetContactByUri(args[0]);
Conversation conversation = client.ConversationManager.AddConversation();
conversation.AddParticipant(contact);
Dictionary<InstantMessageContentType, String> messages = new Dictionary<InstantMessageContentType, String>();
messages.Add(InstantMessageContentType.PlainText, args[1]);
InstantMessageModality m = (InstantMessageModality) conversation.Modalities[ModalityTypes.InstantMessage];
m.BeginSendMessage(messages, null, messages);
//Console.Read();
}
}
}
Screenshot
Link to large screenshot: http://i.imgur.com/LMHEF.png
As you can see in this screenshot, my program doesn't really seem to work, even though I'm able to manually search up the contact and send an instant message manually.
I also tried using ContactManager.BeginSearch() instead of ContactManager.GetContactByUri(), but got the same result (you can see in the screenshot): http://pastie.org/private/o9joyzvux4mkhzsjw1pioa

Ok, so I got it working now. Got it in a working state, although I need to do some serious refactoring.
Program.cs
using System;
namespace Build_Server_Lync_Notifier
{
class Program
{
static void Main(string[] args)
{
if (args.Length != 2)
{
Console.WriteLine("Usage: bsln.exe <uri> <message>");
return;
}
LyncManager lm = new LyncManager(args[0], args[1]);
while (!lm.Done)
{
System.Threading.Thread.Sleep(500);
}
}
}
}
LyncManager.cs
using Microsoft.Lync.Model;
using Microsoft.Lync.Model.Conversation;
using System;
using System.Collections.Generic;
namespace Build_Server_Lync_Notifier
{
class LyncManager
{
private string _uri;
private string _message;
private LyncClient _client;
private Conversation _conversation;
private bool _done = false;
public bool Done
{
get { return _done; }
}
public LyncManager(string arg0, string arg1)
{
_uri = arg0;
_message = arg1;
_client = Microsoft.Lync.Model.LyncClient.GetClient();
_client.ContactManager.BeginSearch(
_uri,
SearchProviders.GlobalAddressList,
SearchFields.EmailAddresses,
SearchOptions.ContactsOnly,
2,
BeginSearchCallback,
new object[] { _client.ContactManager, _uri }
);
}
private void BeginSearchCallback(IAsyncResult r)
{
object[] asyncState = (object[]) r.AsyncState;
ContactManager cm = (ContactManager) asyncState[0];
try
{
SearchResults results = cm.EndSearch(r);
if (results.AllResults.Count == 0)
{
Console.WriteLine("No results.");
}
else if (results.AllResults.Count == 1)
{
ContactSubscription srs = cm.CreateSubscription();
Contact contact = results.Contacts[0];
srs.AddContact(contact);
ContactInformationType[] contactInformationTypes = { ContactInformationType.Availability, ContactInformationType.ActivityId };
srs.Subscribe(ContactSubscriptionRefreshRate.High, contactInformationTypes);
_conversation = _client.ConversationManager.AddConversation();
_conversation.AddParticipant(contact);
Dictionary<InstantMessageContentType, String> messages = new Dictionary<InstantMessageContentType, String>();
messages.Add(InstantMessageContentType.PlainText, _message);
InstantMessageModality m = (InstantMessageModality)_conversation.Modalities[ModalityTypes.InstantMessage];
m.BeginSendMessage(messages, BeginSendMessageCallback, messages);
}
else
{
Console.WriteLine("More than one result.");
}
}
catch (SearchException se)
{
Console.WriteLine("Search failed: " + se.Reason.ToString());
}
_client.ContactManager.EndSearch(r);
}
private void BeginSendMessageCallback(IAsyncResult r)
{
_conversation.End();
_done = true;
}
}
}

Try Below Code its working Fine For me
protected void Page_Load(object sender, EventArgs e)
{
SendLyncMessage();
}
private static void SendLyncMessage()
{
string[] targetContactUris = {"sip:xxxx#domain.com"};
LyncClient client = LyncClient.GetClient();
Conversation conv = client.ConversationManager.AddConversation();
foreach (string target in targetContactUris)
{
conv.AddParticipant(client.ContactManager.GetContactByUri(target));
}
InstantMessageModality m = conv.Modalities[ModalityTypes.InstantMessage] as InstantMessageModality;
m.BeginSendMessage("Test Message", null, null);
}

Related

WMI Invalid Query in C# but works in wbemtest utility

I am trying to create a WQLEventQuery to run in a C# applet that triggers whenever a new folder is created within a specified folder. I have used WMI before and I am familiar with how it works. I successfully created the same type of eventquery for when a new file is added to a specific folder. The weird part is that I get an exception when running the applet in debugging, but if I take the same query and run it from the 'wbemtest' utility built into windows, no 'invalid query' is thrown when I remove the Within clause. However, if I do not set the WithinInterval property on the WQLEventQuery object in C# code, a different exception is thrown related to the polling interval being required. Here are some Code snippets for context:
FolderMonitor.cs
using System;
using System.Configuration;
using System.Management;
using MyProject.core.interfaces;
namespace MyProject.monitor.WmiEventMonitors
{
public class FolderMonitor : IWQLMonitor
{
private const string _eventClassName = "__InstanceCreationEvent";
private const string _isaType = "Win32_SubDirectory";
private readonly IEventListenerManager _eListenerManager;
private readonly IFileProcessService _fileProcessService;
public WqlEventQuery Query { get; }
public string Path { get; }
public FolderMonitor(string path, IEventListenerManager eListenerManager, IFileProcessService fileProcessService)
{
_eListenerManager = eListenerManager;
_fileProcessService = fileProcessService;
if (string.IsNullOrEmpty(path))
path = GetConfiguredDirectory();
Path = path;
var queryParamPath = path.Replace(#"\", #"\\");
//Query = new WqlEventQuery();
//Query.QueryString = $#"Select * From {_eventClassName} Within 1 Where TargetInstance Isa '{_isaType}' And TargetInstance.GroupComponent = 'Win32_Directory.Name={queryParamPath}'";
Query = new WqlEventQuery
{
EventClassName = _eventClassName,
Condition = $"TargetInstance isa '{_isaType}' And TargetInstance.GroupComponent = 'Win32_Directory.Name={queryParamPath}'"
WithinInterval = new TimeSpan(0,5,0)
};
}
public void HandleEvent(object sender, EventArrivedEventArgs e)
{
// when a new subfolder is created:
// 1) Log it somewhere?
// 2) Create a new WMI listener for that subfolder to detect file creation
string newDirPath = null;
try
{
foreach (PropertyData pd in e.NewEvent.Properties)
{
if (pd.Name != "TargetInstance") continue;
ManagementBaseObject mbo;
if ((mbo = pd.Value as ManagementBaseObject) != null)
{
using (mbo)
{
var newSubDir = mbo.Properties["PartComponent"];
var newDir = newSubDir.Value as ManagementBaseObject;
newDirPath = $"{newDir.Properties["Drive"].Value}{newDir.Properties["Path"].Value}";
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
throw;
}
if (!string.IsNullOrEmpty(newDirPath))
{
var newFileMonitorEvent = new FileMonitor(newDirPath, _fileProcessService);
_eListenerManager.Add(newFileMonitorEvent);
}
}
private static string GetConfiguredDirectory()
{
return ConfigurationManager.AppSettings["Directory"].Trim();
}
}
}
My event registering class
using System;
using System.Management;
using MyProject.monitor.WmiEventMonitors;
namespace MyProject.monitor
{
public interface IFileMonitorEventRegistrar
{
ManagementEventWatcher RegisterEventListener(IWQLMonitor newMonitorCandidate);
bool UnregisterEventListener(ManagementEventWatcher listener);
}
public class FileMonitorEventRegistrar : IFileMonitorEventRegistrar
{
public ManagementEventWatcher RegisterEventListener(IWQLMonitor newMonitorCandidate)
{
var scope = WmiUtility.GetConnectionScope();
ManagementEventWatcher watcher = null;
try
{
watcher = new ManagementEventWatcher(scope, newMonitorCandidate.Query);
watcher.EventArrived += new EventArrivedEventHandler(newMonitorCandidate.HandleEvent);
watcher.Start();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
throw;
}
return watcher;
}
public bool UnregisterEventListener(ManagementEventWatcher listener)
{
listener.Stop();
listener.Dispose();
return true;
}
}
}
my WMI Utility class
using System;
using System.Management;
namespace MyProject.monitor
{
public static class WmiUtility
{
private static ManagementScope _connectionScope;
private static ConnectionOptions _connectionOptions;
public static ManagementScope GetConnectionScope()
{
EstablishConnection(null, null, null, Environment.MachineName);
return _connectionScope;
}
private static ConnectionOptions SetConnectionOptions()
{
return new ConnectionOptions
{
Impersonation = ImpersonationLevel.Impersonate,
Authentication = AuthenticationLevel.Default,
EnablePrivileges = true
};
}
private static ManagementScope SetConnectionScope(string machineName, ConnectionOptions options)
{
ManagementScope connectScope = new ManagementScope();
connectScope.Path = new ManagementPath(#"\\" + machineName + #"\root\CIMV2");
connectScope.Options = options;
try
{
connectScope.Connect();
}
catch (ManagementException e)
{
Console.WriteLine(e.Message);
Console.WriteLine(e.StackTrace);
throw;
}
return connectScope;
}
private static void EstablishConnection(string userName, string password, string domain, string machineName)
{
_connectionOptions = SetConnectionOptions();
if (domain != null || userName != null)
{
_connectionOptions.Username = domain + "\\" + userName;
_connectionOptions.Password = password;
}
_connectionScope = SetConnectionScope(machineName, _connectionOptions);
}
}
}
my EventQuery Manager class
using System;
using System.Collections.Generic;
using System.Management;
using MyProejct.monitor.WmiEventMonitors;
namespace MyProject.monitor
{
public interface IEventListenerManager : IDisposable
{
IDictionary<string, ManagementEventWatcher> RegisteredEvents { get; }
bool Add(IWQLMonitor eListener);
bool Remove(string monitoredPath);
}
public class EventListenerManager : IEventListenerManager
{
private bool _disposed;
private readonly IFileMonitorEventRegistrar _eventRegistrar;
public IDictionary<string, ManagementEventWatcher> RegisteredEvents { get; }
public EventListenerManager(IFileMonitorEventRegistrar eventRegistrar)
{
_eventRegistrar = eventRegistrar;
RegisteredEvents = new Dictionary<string, ManagementEventWatcher>();
}
public bool Add(IWQLMonitor eListener)
{
RegisteredEvents.Add(eListener.Path, _eventRegistrar.RegisterEventListener(eListener));
return true;
}
public bool Remove(string monitoredPath)
{
if (RegisteredEvents.ContainsKey(monitoredPath))
{
_eventRegistrar.UnregisterEventListener(RegisteredEvents[monitoredPath]);
return RegisteredEvents.Remove(monitoredPath);
}
return true;
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
foreach (var item in RegisteredEvents)
{
Remove(item.Key);
}
}
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
}
the orchestrator class
using System;
using System.Configuration;
using System.IO;
using System.Linq;
using MyProejct.monitor.WmiEventMonitors;
using MyProject.core.interfaces;
namespace MyProject.monitor
{
public interface IFileMonitorService : IDisposable
{
void Initialize();
}
public class FileMonitorService : IFileMonitorService
{
private bool _disposed;
private readonly IEventListenerManager _eventListenerManager;
private readonly IFileMonitorEventRegistrar _eventRegistrar;
private readonly IFileProcessService _fileProcessService;
private string _parentDirectory;
public FileMonitorService(IFileMonitorEventRegistrar eventRegistrar, IFileProcessService fileProcessService)
{
_eventRegistrar = eventRegistrar;
_fileProcessService = fileProcessService;
_eventListenerManager = new EventListenerManager(_eventRegistrar);
}
public void Initialize()
{
if (string.IsNullOrEmpty(_parentDirectory))
_parentDirectory = ConfigurationManager.AppSettings["SFTPDirectory"].Trim();
if (!_eventListenerManager.RegisteredEvents.Any())
{
GenerateFileEventListeners();
GenerateParentFolderListener();
}
}
public void GenerateFileEventListeners()
{
if (!Directory.Exists(_parentDirectory))
return;
var foldersToMonitor = Directory.EnumerateDirectories(_parentDirectory);
foreach (var folderPath in foldersToMonitor)
{
// Create a listener
var fileMonitor = new FileMonitor(folderPath, _fileProcessService);
_eventListenerManager.Add(fileMonitor);
}
}
public void GenerateParentFolderListener()
{
var folderMonitor = new FolderMonitor(_parentDirectory, _eventListenerManager, _fileProcessService);
_eventListenerManager.Add(folderMonitor);
}
public virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_eventListenerManager.Dispose();
_parentDirectory = null;
}
_disposed = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
}
So the query string is essentially
"select * from __InstanceCreationEvent within 1 where TargetInstance isa 'Win32_SubDirectory' And TargetInstance.GroupComponent = 'Win32_Directory.Name=C:\\MonitoredDocs'"
If take that query string and remove the within clause, wbemtest accepts it as a valid WMI query. When the within clause is present, it says it is an invalid query. I am using an answer from this article. Any help to figure out how to get this WQL Event Query to work would be appreciated.
So I read through the article that I posted above with a more focused attention, and found an alternate query that actually works. The query string looks like this:
Select * From __InstanceCreationEvent Within 1 Where TargetInstance Isa 'Win32_Directory' And TargetInstance.Drive = 'C:' And TargetInstance.Path = '\\path\\to\\monitored\\directory\\'
*One detail that can be confusing is that that the path value has to contain the trailing "\\"
in terms of code, my modified FolderMonitor.cs class looks like this: (changes marked with *!*!*)
public class FolderMonitor : IWQLMonitor
{
private const string _eventClassName = "__InstanceCreationEvent";
*!*!*private const string _isaType = "Win32_Directory";*!*!*
private readonly IEventListenerManager _eListenerManager;
private readonly IFileProcessService _fileProcessService;
public WqlEventQuery Query { get; }
public string Path { get; }
public FolderMonitor(string path, IEventListenerManager eListenerManager, IFileProcessService fileProcessService)
{
_eListenerManager = eListenerManager;
_fileProcessService = fileProcessService;
if (string.IsNullOrEmpty(path))
path = GetConfiguredDirectory();
Path = path;
*!*!*var drive = Path.Substring(0, 2);*!*!*
*!*!*var queryPath = Path.Substring(2) + #"\";*!*!*
var queryParamPath = queryPath.Replace(#"\", #"\\");
Query = new WqlEventQuery
{
EventClassName = _eventClassName,
*!*!*Condition = $"TargetInstance Isa '{_isaType}' And TargetInstance.Drive = '{drive}' And TargetInstance.Path = '{queryParamPath}'",*!*!*
WithinInterval = new TimeSpan(0,0,1)
};
}
}

Use Rhino Mock to report the function that was called

I have a failing testcase that depends on an external module.
I want to use Rhino Mock to generate a report on called functions.
I created a minimal example that illustrates my problem:
using NUnit.Framework;
using Rhino.Mocks;
using System;
namespace StackOverflow_namespace
{
public interface IUsefulService
{
object HiddenAmongManyCalls();
}
public class ThirdPartyBase
{
private int a = 42;
public ThirdPartyBase(IUsefulService service)
{
object liveFastDieYoung = service.HiddenAmongManyCalls();
liveFastDieYoung.Equals(a);
}
}
public class MyParty : ThirdPartyBase
{
public MyParty(IUsefulService service) : base(service)
{
}
}
[TestFixture]
class StackOverflow
{
[Test]
public void Hypothetical()
{
IUsefulService service = MockRepository.GenerateMock<IUsefulService>();
try
{
var party = new MyParty(service);
}
catch(Exception e)
{
string[] calls = MagicallyGetTheCallsThatWereMadeToTheMock();
foreach(var call in calls)
{
//with my visual studio testrunner for nunit 3 I can investigate stored console output
Console.WriteLine(call);
}
Assert.Fail("Excpexted no exception but was '" + e.GetType().Name + "': " + e.Message);
}
}
private string[] MagicallyGetTheCallsThatWereMadeToTheMock()
{
return new[]
{
"This is where I am lost, I do not know how to get the calls from the repository."
};
}
}
}
I tried to find something online without success.
Do Rhino Mocks record all calls and can I access that list?
Edit:
An attempt to verify Expectations did not work since I am looking for calls I did not expect.
I could build a list of calls using GetArgumentsForCallsMadeOn. I can reflect on the Interface. I started on a method for that but I currently fail to see how I can convert a MethodInfo to an Action<T>.
private IEnumerable<string> GetCallsList<Interface>(Interface rhinomock)
{
Type interfaceType = typeof(Interface);
List<MethodInfo> interfaceMethodInfos = new List<MethodInfo>();
List<string> returnInfos = new List<string>();
StringBuilder callbuilder = new StringBuilder();
foreach (var property in interfaceType.GetProperties())
{
interfaceMethodInfos.Add(property.GetGetMethod());
interfaceMethodInfos.Add(property.GetSetMethod());
}
foreach (var method in interfaceType.GetMethods())
{
interfaceMethodInfos.Add(method);
}
foreach (var methodinfo in interfaceMethodInfos)
{
Action<Interface> magic = null; //convert methodinfo into action - still missing
var calls = rhinomock.GetArgumentsForCallsMadeOn(magic); //magic is currently null, here be crash
foreach (var call in calls)
{
bool more = false;
callbuilder.Clear().Append(interfaceType.Name).Append('.').Append(methodinfo.Name).Append('(');
foreach (var parameter in call)
{
if (more){ callbuilder.Append(", "); }
if (null == parameter) { callbuilder.Append("<null>"); }
else { callbuilder.Append(parameter.ToString()); }
more = true;
}
callbuilder.Append(')');
string callInfo = callbuilder.ToString();
returnInfos.Add(callInfo);
}
}
return returnInfos;
}
I was able to use reflection to get the output I wanted.
Here is the minimal example where the test fails and the output contains all method calls.
using NUnit.Framework;
using Rhino.Mocks;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace StackOverflow_namespace
{
public interface IUsefulService
{
object HiddenAmongManyCalls();
string TestCall2(string arg1, int arg2);
string FULLACCESS { get; set; }
string READONLY { get; }
}
public class ThirdPartyBase
{
private int a = 42;
public ThirdPartyBase(IUsefulService service)
{
service.TestCall2("callA", 1);
service.TestCall2("callB", 1);
object liveFastDieYoung = service.HiddenAmongManyCalls();
service.TestCall2("callA", 2);
service.TestCall2("callB", 2);
var a = service.FULLACCESS;
var b = service.READONLY;
service.FULLACCESS = "some";
liveFastDieYoung.Equals(a);
}
}
public class MyParty : ThirdPartyBase
{
public MyParty(IUsefulService service) : base(service)
{
}
}
[TestFixture]
class StackOverflow
{
[Test]
public void Hypothetical()
{
IUsefulService service = MockRepository.GenerateMock<IUsefulService>();
try
{
var party = new MyParty(service);
}
catch (Exception e)
{
var calls = GetCallsList(service);
foreach (var call in calls)
{
//with my visual studio testrunner for nunit 3 I can investigate stored console output
Console.WriteLine(call);
}
Assert.Fail("Excpexted no exception but was '" + e.GetType().Name + "': " + e.Message);
}
}
private IEnumerable<string> GetCallsList<Interface>(Interface rhinomock)
{
Type interfaceType = typeof(Interface);
List<MethodInfo> interfaceMethodInfos = new List<MethodInfo>();
List<string> returnInfos = new List<string>();
StringBuilder callbuilder = new StringBuilder();
foreach (var property in interfaceType.GetProperties())
{
AddMethodInfoIfValid(interfaceMethodInfos, property.GetGetMethod());
AddMethodInfoIfValid(interfaceMethodInfos, property.GetSetMethod());
}
foreach (var method in interfaceType.GetMethods())
{
AddMethodInfoIfValid(interfaceMethodInfos, method);
}
foreach (var methodinfo in interfaceMethodInfos)
{
int paramcount = methodinfo.GetParameters().Length;
object[] args = new object[paramcount];
Action<Interface> lambdacall = (i) => methodinfo.Invoke(i, args);
var calls = rhinomock.GetArgumentsForCallsMadeOn(lambdacall);
foreach (var call in calls)
{
bool more = false;
callbuilder.Clear().Append(interfaceType.Name).Append('.').Append(methodinfo.Name).Append('(');
foreach (var parameter in call)
{
if (more) { callbuilder.Append(", "); }
if (null == parameter) { callbuilder.Append("<null>"); }
else {
callbuilder
.Append('(').Append(parameter.GetType().Name).Append(")'")
.Append(parameter.ToString()).Append("'");
}
more = true;
}
callbuilder.Append(')');
string callInfo = callbuilder.ToString();
returnInfos.Add(callInfo);
}
}
return returnInfos;
}
private static void AddMethodInfoIfValid(List<MethodInfo> interfaceMethodInfos, MethodInfo methodinfo)
{
if (null != methodinfo)
{
interfaceMethodInfos.Add(methodinfo);
}
}
}
}

Transmit xml serialized objects thru named pipe (without WCF)

i want to send specific objects thru a simple named pipe. I think the receiver does not recognize the cut between two sent objects. In the result, i get an xml serialization error. Here is my code:
Server process:
using System;
using System.IO;
using System.IO.Pipes;
using System.Threading;
using System.Xml.Serialization;
namespace NamedPipe
{
class ProgramServer
{
static void Main(string[] args)
{
NamedPipeServerStream server;
server = new NamedPipeServerStream("PipesOfPiece");
server.WaitForConnection();
StreamReader reader = new StreamReader(server);
StreamWriter writer = new StreamWriter(server);
Console.WriteLine("Start loop. ");
Thread.Sleep(1000);
while (true)
{
XmlSerializer receiver = new XmlSerializer(typeof(PayLoad));
object testobj = receiver.Deserialize(reader);
Console.WriteLine("Testobject: " + ((PayLoad)(testobj)).name + ((PayLoad)(testobj)).count);
}
}
}
}
Client process:
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Pipes;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
namespace NamedPipe
{
class ProgramClient
{
static void Main(string[] args)
{
//Client
var client = new NamedPipeClientStream("PipesOfPiece");
client.Connect();
StreamReader reader = new StreamReader(client);
while (true)
{
StreamWriter writer = new StreamWriter(client);
PayLoad test = new PayLoad
()
{
name = "Test",
count = 42
};
XmlSerializer sendSerializer = new XmlSerializer(typeof(PayLoad));
sendSerializer.Serialize(writer, test);
}
}
}
}
I have tried recently using NamedPipes without WCF. You can look into this code which might give you some idea. Here, Client is enabled with Callback functionality so server can callback the client.
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
const string PIPE_NAME = "testPipeName33";
const string OBJECT_NAME = "test";
const string CALLBACK_PIPE_NAME = "testPipeName34";
const string CALLBACK_OBJECT_NAME = "testclient";
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
if ((args.Length == 0 || args[0] == "s"))
{
try
{
IPCRegistration.RegisterServer(PIPE_NAME,OBJECT_NAME);
}
catch (RemotingException)
{
remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject),PIPE_NAME,OBJECT_NAME);
remoteObject.OnNewProcessStarted("test");
Application.Exit();
return;
}
MessageBox.Show("Server:" + Process.GetCurrentProcess().Id);
Process.Start(Application.ExecutablePath, "c");
Application.Run(new Form1("Server"));
}
else
{
IsClient = true;
remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject), PIPE_NAME, OBJECT_NAME);
IPCRegistration.RegisterServer(CALLBACK_PIPE_NAME, CALLBACK_OBJECT_NAME); // Here Client will listen on this channel.
remoteObject.SetOnNewProcessStarted(OnNewProcessStarted,Process.GetCurrentProcess().Id.ToString());
MessageBox.Show("Client:" + Process.GetCurrentProcess().Id);
Application.Run(new Form1("Client"));
}
}
static RemoteObject remoteObject;
static bool IsClient = false;
static bool OnNewProcessStarted(string commandLine)
{
MessageBox.Show("saved:"+commandLine+" Currrent:"+Process.GetCurrentProcess().Id);
MessageBox.Show("Is Client : " + IsClient);//problem here, IsClient should be true
return true;
}
}
public delegate bool OnNewProcessStartedDelegate(string text);
internal class RemoteObject : MarshalByRefObject
{
public OnNewProcessStartedDelegate OnNewProcessStartedHandler;
public string value;
public bool isCallBack = false;
const string PIPE_NAME = "testPipeName33";
const string OBJECT_NAME = "test";
const string CALLBACK_PIPE_NAME = "testPipeName34";
const string CALLBACK_OBJECT_NAME = "testclient";
RemoteObject remoteObject;
public bool OnNewProcessStarted(string commandLine)
{
if (!isCallBack)
{
remoteObject.isCallBack = true;
return remoteObject.OnNewProcessStarted(commandLine);
}
if (OnNewProcessStartedHandler != null)
return OnNewProcessStartedHandler(value);
return false;
}
public void SetOnNewProcessStarted(OnNewProcessStartedDelegate onNewProcessStarted,string value)
{
this.value = value;
OnNewProcessStartedHandler = onNewProcessStarted;
if (!isCallBack)
{
remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject), CALLBACK_PIPE_NAME, CALLBACK_OBJECT_NAME);
remoteObject.isCallBack = true;
remoteObject.SetOnNewProcessStarted(onNewProcessStarted, Process.GetCurrentProcess().Id.ToString());
}
}
public override object InitializeLifetimeService()
{
return null;
}
}
internal class IPCRegistration
{
public static RemoteObject RegisterClient(Type remoteObject,string PIPE_NAME,string OBJECT_NAME)
{
IpcClientChannel chan = new IpcClientChannel();
ChannelServices.RegisterChannel(chan, false);
RemoteObject remoteObjectInstance = (RemoteObject)Activator.GetObject(remoteObject,
string.Format("ipc://{0}/{1}", PIPE_NAME, OBJECT_NAME));
return remoteObjectInstance;
}
public static void RegisterServer(string pipeName, string objectName)
{
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IpcServerChannel chan = new IpcServerChannel("", pipeName, serverProvider);
ChannelServices.RegisterChannel(chan, false);
RemotingServices.Marshal(new RemoteObject(), objectName);
}
}

not able to fetch links from pagination using watin dll

Hi i am collecting urls using watin framework. i want to traverse all the pages and collect the link and save it in one text file.I dont know how to add the pagination function.here is my code.
using System.Text;
using System.Threading.Tasks;
using WatiN.Core;
namespace magicbricks
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
IE ie = new IE();
ie.GoTo("http://www.99acres.com/property-in-chennai-ffid?search_type=QS&search_location=HP&lstAcn=HP_R&src=CLUSTER&isvoicesearch=N&keyword_suggest=chennai%20%28all%29%3B&fullSelectedSuggestions=chennai%20%28all%29&strEntityMap=W3sidHlwZSI6ImNpdHkifSx7IjEiOlsiY2hlbm5haSAoYWxsKSIsIkNJVFlfMzIsIFBSRUZFUkVOQ0VfUywgUkVTQ09NX1IiXX1d&texttypedtillsuggestion=chennai&refine_results=Y&Refine_Localities=Refine%20Localities&action=%2Fdo%2Fquicksearch%2Fsearch&suggestion=CITY_32%2C%20PREFERENCE_S%2C%20RESCOM_R");
foreach (var currLink in ie.Links)
{
if (currLink.Url.Contains("b"))
{
Console.WriteLine(currLink.Url);
}
}
Console.ReadLine();
}
}
}
any help will be appreciated.
Here is working solution for that. I changed a bit your code.
using System;
using WatiN.Core;
namespace magicbricks
{
static class Class1
{
private static WatiN.Core.Link _nextPageElement;
private static string _firstPartOfAddress = "";
private static string _lastPartOfAddress = "";
private static int _maxPageCounter = 0;
[STAThread]
static void Main(string[] args)
{
IE ie = SetUpBrowser();
EnterFirstWebpage(ie);
ie.WaitForComplete();
LookFoAllLinks(ie);
for (int i = 2; i < _maxPageCounter; i++)
{
Console.WriteLine("----------------------------Next Page {0}---------------------------", i);
Console.WriteLine(AssembleNextPageWebAddress(i));
EnterNextWebpageUrl(ie,AssembleNextPageWebAddress(i));
LookFoAllLinks(ie);
}
Console.ReadKey();
}
private static IE SetUpBrowser()
{
IE ie = new IE();
return ie;
}
private static void EnterFirstWebpage(IE ie)
{
ie.GoTo("http://www.99acres.com/property-in-chennai-ffid?search_type=QS&search_location=HP&lstAcn=HP_R&src=CLUSTER&isvoicesearch=N&keyword_suggest=chennai%20%28all%29%3B&fullSelectedSuggestions=chennai%20%28all%29&strEntityMap=W3sidHlwZSI6ImNpdHkifSx7IjEiOlsiY2hlbm5haSAoYWxsKSIsIkNJVFlfMzIsIFBSRUZFUkVOQ0VfUywgUkVTQ09NX1IiXX1d&texttypedtillsuggestion=chennai&refine_results=Y&Refine_Localities=Refine%20Localities&action=%2Fdo%2Fquicksearch%2Fsearch&suggestion=CITY_32%2C%20PREFERENCE_S%2C%20RESCOM_R");
}
private static void EnterNextWebpageUrl(IE ie,string url)
{
ie.GoTo(url);
ie.WaitForComplete();
}
private static void LookFoAllLinks(IE ie)
{
int currentpageCounter = 0;
var tmpUrl = string.Empty;
const string nextPageUrl = "http://www.99acres.com/property-in-chennai-ffid-page-";
foreach (var currLink in ie.Links)
{
if (currLink.Url.Contains("b"))
{
Console.WriteLine(currLink.Url);
try
{
if (currLink.Name.Contains("nextbutton"))
{
_nextPageElement = currLink;
}
}
catch (Exception ex)
{
}
try
{
if (currLink.GetAttributeValue("name").Contains("page"))
{
_firstPartOfAddress = currLink.Url.Substring(0, nextPageUrl.Length);
tmpUrl = currLink.Url.Remove(0,nextPageUrl.Length);
_lastPartOfAddress = tmpUrl.Substring(tmpUrl.IndexOf("?"));
tmpUrl = tmpUrl.Substring(0,tmpUrl.IndexOf("?"));
int.TryParse(tmpUrl, out currentpageCounter);
if (currentpageCounter > _maxPageCounter)
{
_maxPageCounter = currentpageCounter;
currentpageCounter = 0;
}
}
}
catch (Exception)
{
}
}
}
}
private static string AssembleNextPageWebAddress(int pageNumber)
{
return _firstPartOfAddress + pageNumber + _lastPartOfAddress;
}
}
}
Some explanation :
variable _maxPageCounter contains max numbers of pages to lookfor links.
We are getting this here :
if (currLink.GetAttributeValue("name").Contains("page"))
{
_firstPartOfAddress = currLink.Url.Substring(0, nextPageUrl.Length);
tmpUrl = currLink.Url.Remove(0,nextPageUrl.Length);
_lastPartOfAddress = tmpUrl.Substring(tmpUrl.IndexOf("?"));
tmpUrl = tmpUrl.Substring(0,tmpUrl.IndexOf("?"));
int.TryParse(tmpUrl, out currentpageCounter);
if (currentpageCounter > _maxPageCounter)
{
_maxPageCounter = currentpageCounter;
currentpageCounter = 0;
}
}
Later we are just looping through pages, by create next address.
private static string AssembleNextPageWebAddress(int pageNumber)
{
return _firstPartOfAddress + pageNumber + _lastPartOfAddress;
}
We could use here as well next button, and click it in loop.
I hope it was helpful.

Why does this code throw an automapping exception?

I'm making an internal user inactivity monitor for work, and I'm using a windows form in conjunction with a topshelf service to do this, the code will write to a RabbitMQ Server and the service will consume the messages and forward them to a database, my code as it stands is throwing an exception with the following error;
Missing type map configuration or unsupported mapping.
Mapping types:
LogData -> DbLogData
AccessEye.LogData -> AccessEye.DbLogData
this is the code for my service
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using NLog;
using IWshRuntimeLibrary;
using Topshelf;
using System.Data.Odbc;
using EasyNetQ;
using RabbitMQ;
using EasyNetQ.Topology;
using System.Threading.Tasks;
using System.Windows.Forms;
using AccessEye;
using System.ComponentModel;
namespace LogService
{
public class WindowsServiceHost : ServiceControl, ServiceShutdown
{
public static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public static void WriteLogDataToDb(LogData data)
{
using (var db = new LogService.UserActivityDataContext())
{
DbLogData logData = AutoMapper.Mapper.Map<LogData, DbLogData>(data);
int t = (int)data.EventType;
EventType eventType = db.EventTypes.FirstOrDefault(r => r.Id == t);
if (eventType == null)
{
eventType = db.EventTypes.Add(new EventType
{
Event = GetEnumDescriptionAttributeValue(data.EventType),
Id = (int)data.EventType
});
db.SaveChanges();
}
logData.EventTypeId = eventType.Id;
db.LogEvents.Add(logData);
db.SaveChanges();
}
}
public static string GetEnumDescriptionAttributeValue(Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
public bool Start(HostControl hostControl)
{
Program.bus = RabbitHutch.CreateBus("host=*****;virtualHost=*****;username=***;password=***").Advanced;
//var bus = RabbitHutch.CreateBus("host=*******;virtualHost=******;username=****;password=******").Advanced;
var queue = Queue.Declare(true, false, true, null);
var exchange = Exchange.DeclareFanout("UserActivityFanout", true, false, null);
var exchangeTopic = Exchange.DeclareTopic("UserActivity", true, false, null);
queue.BindTo(exchange, "#");
exchange.BindTo(exchangeTopic, "#");
Program.bus.Subscribe<AccessEye.LogData>(queue, (msg, messageRecInfo) => Task.Factory.StartNew(() =>
{
var data2 = LogDataFactory.CollectData();
data2.EventType = AccessEye.UserStateEvents.Logon;
WriteLogDataToDb(data2);
//AppForm.WriteLogDataToDb(data);
//Console.WriteLine(msg.Body.UserName + " -- " + msg.Body.ComputerName + " -- " + msg.Body.EventType + " -- " + msg.Body.TeamviewerId);
}));
return true;
}
public bool Stop(HostControl hostControl)
{
Logger.Trace("STOP");
Program.bus.Dispose();
return true;
}
public void Shutdown(HostControl hostControl)
{
Logger.Trace("SHUTDOWN");
Program.bus.Dispose();
}
}
}
and for the form
using System;
using System.IO;
using System.Windows.Forms;
using System.ComponentModel;
using AccessEye;
using System.Linq;
using EasyNetQ;
using EasyNetQ.Topology;
using Microsoft.Win32;
using MySql.Data.MySqlClient;
using NLog;
using ProtoBuf;
using System.Threading;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Runtime.InteropServices;
using System.Reflection;
namespace LogProgram
{
public partial class AppForm : Form
{
public static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private Screensaver watcher;
public Inactivity inactivity;
IAdvancedBus bus;
IExchange exchange;
public AppForm()
{
InitializeComponent();
ConfigureForm();
// todo: should be in setting
int pollingInterval = 5000;
inactivity = new Inactivity(pollingInterval);
inactivity.Inactive += inactivity_Inactive;
inactivity.Active += inactivity_Active;
inactivity.InactivityThresholdMs = 5 * 1000; // todo: should be in setting
inactivity.Start();
watcher = new Screensaver(pollingInterval);
watcher.ScreensaverOff += watcher_ScreensaverOff;
watcher.ScreensaverOn += watcher_ScreensaverOn;
watcher.Start();
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
SystemEvents.SessionSwitch += SystemEvents_SessionSwitch;
LogManager.ThrowExceptions = true;
// todo: connection string should be in setting
bus = RabbitHutch.CreateBus("host=as01.access.local;virtualHost=DEV-Reece;username=reece;password=reece").Advanced;
exchange = Exchange.DeclareTopic("UserActivity", true, false, null);
var fanout = Exchange.DeclareFanout("FanoutExchange", true, false, null);
fanout.BindTo(exchange, new[] { "#" });
}
public void ConfigureForm()
{
this.Hide();
TrayDisplayer.Visible = false;
}
public static void WriteLogDataToDb(LogData data)
{
using (var db = new LogService.UserActivityDataContext())
{
DbLogData logData = AutoMapper.Mapper.Map<LogData, DbLogData>(data);
int t = (int)data.EventType;
EventType eventType = db.EventTypes.FirstOrDefault(r => r.Id == t);
if (eventType == null)
{
eventType = db.EventTypes.Add(new EventType
{
Event = GetEnumDescriptionAttributeValue(data.EventType),
Id = (int)data.EventType
});
db.SaveChanges();
}
logData.EventTypeId = eventType.Id;
db.LogEvents.Add(logData);
db.SaveChanges();
}
}
public static string GetEnumDescriptionAttributeValue(Enum value)
{
var fieldInfo = value.GetType().GetField(value.ToString());
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
return attributes.Length > 0 ? attributes[0].Description : value.ToString();
}
private void AppForm_Load(object sender, EventArgs e)
{
}
void watcher_ScreensaverOn(object sender, EventArgs e)
{
var data = LogDataFactory.CollectData();
data.EventType = AccessEye.UserStateEvents.ScreensaverOn;
PublishLogData(data);
}
void watcher_ScreensaverOff(object sender, EventArgs e)
{
var data = LogDataFactory.CollectData();
data.EventType = AccessEye.UserStateEvents.ScreensaverOff;
PublishLogData(data);
}
void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
{
var data = LogDataFactory.CollectData();
switch (e.Reason)
{
case SessionSwitchReason.SessionLock:
data.EventType = UserStateEvents.Lock;
break;
case SessionSwitchReason.SessionUnlock:
data.EventType = UserStateEvents.Unlock;
break;
}
PublishLogData(data);
}
public void PublishLogData(AccessEye.LogData LogData)
{
WriteLogDataToDb(LogData);
if (!bus.IsConnected) return;
try
{
using (var publishChannel = bus.OpenPublishChannel())
{
publishChannel.Publish(exchange, LogData.EventType.ToString(), new Message<LogData>(LogData));
}
}
catch (EasyNetQException)
{
//todo: handle
}
}
public static byte[] Serialize<T>(T instance)
{
using (var stream = new MemoryStream())
{
Serializer.Serialize(stream, instance);
return stream.ToArray();
}
}
private static T DeSerialize<T>(byte[] data)
{
using (var stream = new MemoryStream(data))
{
return Serializer.Deserialize<T>(stream);
}
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
bus.Dispose();
}
public void inactivity_Active(object sender, EventArgs e)
{
inactivity.Stop();
var data = LogDataFactory.CollectData();
data.EventType = UserStateEvents.Active;
PublishLogData(data);
inactivity.Start();
}
public void inactivity_Inactive(object sender, EventArgs e)
{
inactivity.Stop();
var data = LogDataFactory.CollectData();
data.EventType = UserStateEvents.Inactive;
PublishLogData(data);
inactivity.Start();
}
public void SystemEvents_SessionEnding(object sender, EventArgs e)
{
var data = LogDataFactory.CollectData();
data.EventType = UserStateEvents.Logoff;
PublishLogData(data);
Logger.Trace("Logged off");
}
}
}
LogData Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ProtoBuf;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace AccessEye
{
public class DbLogData : LogData
{
[Key]
public int Id { get; set; }
public int? EventTypeId { get; set; }
[ForeignKey("EventTypeId")]
public virtual EventType EventTypeTest { get; set; }
}
}
Don't you need to create a map before you can use one;
AutoMapper.Mapper.CreateMap<LogData, DbLogData>();

Categories