C#, Lotus Interop: Getting Message Information - c#

I'm using Interop.Domino.dll to retrieve E-mails from a Lotus "Database" (Term used loosely). I'm having some difficulty in retrieving certain fields and wonder how to do this properly. I've been using NotesDocument.GetFirstItem to retrieve Subject, From and Body.
My issues in this regard are thus:
How do I retrieve Reply-To address? Is there a list of "Items" to get somewhere? I can't find it.
How do I retrieve friendly names for From and Reply-To addresses?
When I retrieve Body this way, it's formatted wierdly with square bracket sets ([]) interspersed randomly across the message body, and parts of the text aren't where I expect them.
Related code:
string
ActualSubject = nDoc.GetFirstItem("Subject").Text,
ActualFrom = nDoc.GetFirstItem("From").Text,
ActualBody = nDoc.GetFirstItem("Body").Text;

Hah, got it!
Object[] ni = (Object[])nDoc.Items;
string names_values = "";
for (int x = 0; x < ni.Length; x++)
{
NotesItem item = (NotesItem)ni[x];
if (!string.IsNullOrEmpty(item.Name)) names_values += x.ToString() + ": " + item.Name + "\t\t" + item.Text + "\r\n";
}
This returned a list of indices, names, and values:
0: Received from example.com ([192.168.0.1]) by host.example.com (Lotus Domino Release 6.5.4 HF182) with ESMTP id 2008111917343129-205078 ; Wed, 19 Nov 2008 17:34:31 -0500
1: Received from example.com ([192.168.0.2]) by host2.example.com (Lotus Domino Release 6.5.4 HF182) with ESMTP id 2008111917343129-205078 ; Wed, 19 Nov 2008 17:34:31 -0500
2: X_PGRTRKID 130057945714t
3: X_PGRSRC IE
4: ReplyTo "example" <name#email.example.com>
5: Principal "example" <customerservice#email.example.com>
6: From "IE130057945714t"<service#test.email.example.com>
7: SendTo me#example.com
8: Subject (Message subject redacted)
9: PostedDate 11/19/2008 03:34:15 PM
10: MIME_Version 1.0
11: $Mailer SMTP DirectMail
12: $MIMETrack Itemize by SMTP Server on xxxPT02-CORP/example(Release 6.5.4 HF182|May 31, 2005) at 11/19/2008 05:34:31 PM;Serialize by Router on xxxPT02-CORP/example(Release 6.5.4 HF182|May 31, 2005) at 11/19/2008 05:34:32 PM;Serialize complete at 11/19/2008 05:34:32 PM;MIME-CD by Router on xxxPT02-CORP/example(Release 6.5.4 HF182|May 31, 2005) at 11/19/2008 05:34:32 PM;MIME-CD complete at 11/19/2008 05:34:32 PM;Itemize by Router on camp-db-05/example(Release 7.0.2 HF76|November 03, 2006) at 11/19/2008 05:34:32 PM;MIME-CD by Notes Client on MyName/Guest/example(Release 6.5.6|March 06, 2007) at 11/20/2008 12:46:25 PM;MIME-CD complete at 11/20/2008 12:46:25 PM
13: Form Memo
14: $UpdatedBy ;CN=xxxPT02-CORP/O=example
15: $ExportHeadersConverted 1
16: $MessageID <redacted#LocalDomain>
17: RouteServers CN=xxxPT02-CORP/O=example;CN=camp-db-05/O=example
18: RouteTimes 11/19/2008 03:34:31 PM-11/19/2008 03:34:32 PM;11/19/2008 03:34:32 PM-11/19/2008 03:34:32 PM
19: $Orig 958F2E4E4B666AB585257506007C02A7
20: Categories
21: $Revisions
22: DeliveredDate 11/19/2008 03:34:32 PM
23: Body []exampleexample
Now, who can tell me why the Body keeps getting messed up?

The Body item is a NotesRichTextItem, not a regular NotesItem. They are a different type of object in the Lotus Notes world (and often the source of much developer frustration!)
I don't have much experience with using COM to connect to Domino, and I know there are differences in what you have access to, but the Domino Designer Help should give you lots of information the classes, such as NotesRichTextItem.
Perhaps the method "GetFormattedText" would work better for you than accessing the item's Text property.
Here's an example of the method (taken from Domino Designer Help)
Dim doc As NotesDocument
Dim rtitem As Variant
Dim plainText As String
Dim fileNum As Integer
'...set value of doc...
Set rtitem = doc.GetFirstItem( "Body" )
If ( rtitem.Type = RICHTEXT ) Then
plainText = rtitem.GetFormattedText( False, 0 )
End If
' get a file number for the file
fileNum = Freefile
' open the file for writing
Open "c:\plane.txt" For Output As fileNum
' write the formatted text to the file
Print #fileNum, plainText
' close the file
Close #fileNum

It may not work depending on how your environment is set up, but the easiest way to deal with mail in domino is to leave them as MIME and get at the values via the NotesMIMEEntity and NotesMIMEHeader. This will only work if the mail came in from the web rather than native Notes and the environment has been set up to store mail in MIME format.
Otherwise you need to access the body as a NotesRichTextItem. From that item you need to get a NotesRichTextNavigator that will allow you move around the rich text structure if you need to.
If you think the struture should be relatively simple try calling NotesRichTextItem.GetFormattedText(). If that still isn't working then you're going to need to work out what is happeing by playing with an example doument and seeing what the structure looks like to the NotesRichTextNavigator.

Related

How to get sorted Values from HTML Table in C#?

Hello fellow Programmers.
I now spend a whole Day reading Threads to solve this Problem.
I am Parsing HTML from an automatic generated schedule, the same schedule programm was discussed 6 years ago on this thread: Parsing complex HTML tables
But this java / javascript solutions wont work for me. Also the mentioned Programs arent working anymore, I think they released a new Version of the Software. This is the Example I am trying to Parse: https://www.ostfalia.de/cms/de/b/studium/stundenplaene/download/ss19_b_stdgrp_ai_6.html
I need the Parsed Data in the right sequence because I want to generate an iCalendar file with it, or pass/send the data into an self written schedule App
I am using the HTML Agility Pack and Im already sucessful with parsing what I need but I cant get it in the right order its complete split because the HAP displays by row like any other parser. Im so desperate I was close to just count the emtpy trs to estimate when a new row begins but this doesnt work because the program has sometimes more sometimes less empty lines. Does somebody of you has an idea?
This is my Code to get the infos I need:
WebClient client = new WebClient();
string html = client.DownloadString("https://www.ostfalia.de/cms/de/b/studium/stundenplaene/download/ss19_b_stdgrp_ai_6.html");
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(html);
var erg = doc.DocumentNode.SelectNodes("//td[#class='v']");
for (int i = 0; i < erg.Count; i++)
{
txt_check.Text = (erg[i].InnerText);
list_check.Items.Add(erg[i].InnerText);
}
"class v" is the event and "class t" is the time in this example its just class v
I get:
The output of class='v' looks like:
10:30 - 12:00 UhrAI 6.1 Komponentenbasierte SoftwareentwicklungB. RogallaB 109
13:00 - 14:30 UhrAI WPF-12 CCNA 2 Cisco Routing & SwitchingChr. HollmannA 201
13:00 - 14:30 UhrAI WPF Inst. u. Betrieb einer Datenb. a. B. OracleD. HeringA
14:45 - 16:15 UhrAI WPF Mathematik III für InformatikerT. WaldeerB 27 114
14:45 - 16:15 UhrAI WPF-18 AutomatisierungstechnikF. DziembowskiA 107
The output of class='t' looks like:
"Di, 05.03.2019"
"Mi, 06.03.2019"
"Do, 07.03.2019"
"Fr, 08.03.2019"
"Sa, 09.03.2019"
I hope someone has an idea how I can Sort and Match the informations in an Dictionary or List to get it in an ICS.
The Output should be like:
"MI, 06.03.2019 , 8:45 - 10:15 ,AI 6.1 Komponentenbasierte Softwareentwicklung B. Rogalla B109 , 10:30 - 12:00 AI 6.1 Komponentenbasierte Softwareentwicklung B. Rogalla B109"
...
So I can bring it in the ICS Format or DATE/TIME for an Calendar App or something.
Pastbin for the whole HTML:
https://pastebin.com/hHbJTujN
Some Pictures of the Output:
https://drive.google.com/open?id=16Y_hISdVEvzlrS6LCmBMcwAarGhz__t0

OpenPoup.NET - find email, subject and date from forwarded message - C#

I am using OpenPoup.NET to read email from Gmail. I want to identify original sender, receiver, date and subject of forwarded message. My email looks like,
----------------------Email Body starts-----------------------------------
FYI, read below email to get idea of button.
Chirag Developer XYZ Limited
From: Rat Chanra [mailto:rat#chanra.com] Sent: Friday, June 5, 2015
9:48 PM To: Chirag Subject: FW: Copy Product Button
Hi Rat,
I have included a .png of the copy product button. Attached also is an
.eps of updated buttons if we feel like updating all the buttons!
Let's chat,
Ali Designer
----------------------Email Body Ends-----------------------------------
I want to find From, Date, Sublect and To of original message, which is in this case,
From = rat#chanra.com
Date = Friday, June 5, 2015 9:48 PM
To = Chirag
Subject = FW: Copy Product Button
Can I do this using OpenPopUp.net?
Do I have to parse email body using RegEx and fetch above detail. If yes, what is best way for that? I am using C#
You can use the following to match:
From:\s+[^[]+\s+\[mailto:([^\]]+)\]\s+Sent:\s+(\w+,\s+\w+\s+\d+,\s+\d{4}\s+[\d:]+\s+[aApP]M)\s+To:\s+(\w+)\s+Subject:\s+(.*)
And extract From as $1, Date as $2, To as $3 and Subject as $4.
See DEMO

Changing proxy settings for PPPoE DSL connections via the registry

One of my softwares need to change system proxies on Windows. Changing the HTTP proxy for LAN connections behind a router is easy, but I cannot find any information on how to change proxies for dialup or direct DSL (i.e. PPPoE) connections.
This is bad because a significant fraction of my clients are in China. In China, many people do not have more than one computer, and thus find a router wasteful. They simply connect their ADSL modem to their ethernet port and use PPPoE. Yes, this sucks for security and everything (one reason why botnets roam so freely in China) but it is reality and my software needs to work.
I also need code that gives me the list of all network connections. Just having code as in my related question that requires one to know the connection to edit would not work.
I also prefer something that would work by using the reg command. Simple C++ or C# code using the Windows API is also useful, but note that I'm using Racket, a language with a rather cumbersome FFI, which means that it would be best to minimize use of the Windows C API.
Assuming you are unable to use Windows native API calls, I’ll put my bit by providing a solution that only would require calls to Windows commands (reg) and array/strings manipulation, something that the "Racket" language must implement for sure.
This is not the cleanest way but given the requirements it should be a feasible solution for you.
Well, as you perhaps have noticed, the proxy configuration for the different connections is stored under the key: HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections
Under that key there’s a value that stores the DefaultConnectionSettings and another value that stores the SavedLegacySettings (both of type REG_BINARY). In addition to the two mentioned values there’s a value per each system connection (also of type REG_BINARY) that stores the connection configuration including the proxy settings. The name of the values equals the connection names.
Fortunately some guy have reverse engineered the structure of the BINARY data stored in those values.
Byte number zero always has a 3C or 46 - I couldn't find more information about this byte.The next three bytes are zeros.
Byte number 4 is a counter used by the 'Internet Options' property sheet (Internet explorer->Tools->Internet Options...). As you manually
change the internet setting (such as LAN settings in the Connections
tab), this counter increments.Its not very useful byte.But it MUST
have a value. I keep it zero always. The next three bytes are zeros
(Bytes 5 to 7).
Byte number 8 can take different values as per your settings. The value is :
09 when only 'Automatically detect settings' is enabled
03 when only 'Use a proxy server for your LAN' is enabled
0B when both are enabled
05 when only 'Use automatic configuration script' is enabled
0D when 'Automatically detect settings' and 'Use automatic configuration script' are enabled
07 when 'Use a proxy server for your LAN' and 'Use automatic configuration script' are enabled
0F when all the three are enabled.
01 when none of them are enabled. The next three bytes are zeros (Bytes 9 to B).
Byte number C (12 in decimal) contains the length of the proxy server address.For example a proxy server '127.0.0.1:80' has length 12
(length includes the dots and the colon).The next three bytes are
zeros (Bytes D to F).
Byte 10 (or 16 in decimal) contains the proxy server address - like '127.0.0.1:80' (where 80 is obviously the port number)
The byte immediatley after the address contians the length of additional information.The next three bytes are zeros. For example if
the 'Bypass proxy server for local addresses' is ticked, then this
byte is 07,the next three bytes are zeros and then comes a string i.e.
'' ( indicates that you are bypassing the proxy
server.Now since has 7 characters, the length is 07!). You
will have to experiment on your own for finding more about this. If
you dont have any additional info then the length is 0 and no
information is added.
The byte immediately after the additional info, is the length of the automatic configuration script address (If you dont have a script
address then you dont need to add anything,skip this step and goto
step 8).The next three bytes are zeros,then comes the address.
Finally, 32 zeros are appended.(I dont know why! Presumably to fill the binary blob, perhaps it is expected to be a certain length by
something, don't you wish windows had some source?)
Complete info can be found here.
With this info I think you can manage to obtain the values in. Just do reg query "HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Connections", properly parse the output and use reg again to write back the modifications.
I hope this helps.
You may use this c# code to change proxy server for VPN connections:
// host looks like "127.0.0.1:8080"
public static void EnableVPNProxy(string host)
{
RegistryKey RegKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections", true);
foreach (var name in RegKey.GetValueNames())
{
try
{
byte[] server = Encoding.ASCII.GetBytes(host);
byte[] current = (byte[])RegKey.GetValue(name);
byte[] data = new byte[100];
data[0] = current[0];
data[1] = data[2] = data[3] = data[4] = data[5] = data[6] = data[7] = 0;
data[8] = 3;
data[9] = data[10] = data[11] = 0;
data[12] = Convert.ToByte(server.Length);
data[13] = data[14] = data[15] = 0;
int i = 16;
foreach (var b in server)
{
data[i] = b;
i++;
}
for (var x = 0; x < 40; x++)
{
data[i] = 0;
i++;
}
RegKey.SetValue(name, data);
}
catch (Exception ex) { }
}
}
And enable proxy
EnableVPNProxy("127.0.0.1:8080");

Sphinx + xmlpipes2 + Mysql Connector. Problems with cyrillic

I have a problem configuring sphinx+mysql on my machine (Windows 7).
I use sphinx 2.0.6 and MySQL connector 6.5.5 to get to sphinx from C# code. Everything works fine when I try to search a words in English ("madrid" for ex.). But when I send a query from C# code which contains a cyrillic word (that had to be indexed) I receive no results. Here is what I see in the "query.log" file:
[Tue Mar 26 16:35:12.642 2013] 0.000 sec [ext2/0/ext 0 (0,10)] [airportIndex] ????
Latin words looks normal:
[Tue Mar 26 16:35:06.195 2013] 0.000 sec [ext2/0/ext 0 (0,10)] [airportIndex] *mosc*
The charset_table seems to be correct in config:
charset_type = utf-8
charset_table = 0..9, A..Z->a..z, _, a..z, \
U+410..U+42F->U+430..U+44F, U+430..U+44F, U+0401->U+0435, U+0451->U+0435
I just don't know what to do. I've googled for solution the whole day I tried many different solutions, but none of them helped me. Maybe anyone could help me here? Please...
Found it. It was a connector bug (or feature, I'm not sure). It was trying to get the server datetime offset, and failed because sphinx does not have this function. I've just commented this code line (inside MySql.Data.dll) and it started working correctly.

Unable to transfer files from Windows to Linux via Bluetooth using 32feet.Net C# library

First linux service listening process is started using the following command:
obexpushd –B[00:15:83:3D:0A:57]:9 –d –o /home/myfolder
On windows the following code is used to perform the obex transfer:
InTheHand.Net.BluetoothAddress address = peerDevice.DeviceAddress;
System.Uri uri = new Uri("obex://" + address.ToString() + "/" + srcfile.Name);
request = new ObexWebRequest(uri);
startcopy = DateTime.Now;
request.ReadFile(file); // this performs the file read from the hard drive
try
{
response = (ObexWebResponse)request.GetResponse(); // here file should be pushed to the listening service
}
catch (System.InvalidOperationException ex)
{
if (response != null) {
response.Close();
}
return;
}
Devices see each other and their obex services are visible as well.
Transfer seems to be successful, but no data is actually transferred.
The code works between windows and windows without a problem.
Obexpushd process ouput shows:
obexpushd 0.10.2 Copyright (C) 2006-2010 Hendrik Sattler
This software comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions.
Listening on bluetooth/[00:15:83:3D:0A:57]:9
OBEX_EV_ACCEPTHINT, OBEX_CMD_CONNECT
0: Connection from "bluetooth/[00:09:DD:50:94:0B]:9"
0: OBEX_EV_REQHINT, OBEX_CMD_CONNECT
0: OBEX_EV_REQ, OBEX_CMD_CONNECT
0: Sending response code 0
0: OBEX_EV_REQDONE, OBEX_CMD_CONNECT
0: OBEX_EV_REQHINT, OBEX_CMD_PUT
0.1: OBEX_EV_REQCHECK, OBEX_CMD_PUT
0.1: OBEX_EV_REQDONE, OBEX_CMD_PUT
0.1: OBEX_EV_REQHINT, OBEX_CMD_DISCONNECT
0.1: Sending response code 100
0.1: OBEX_EV_REQ, OBEX_CMD_DISCONNECT
0.1: OBEX_EV_REQDONE, OBEX_CMD_DISCONNECT
I have also tried to disable Authentication in C# code but that did not help.
Does any one have idea how to nail this problem down or where to even start looking?
Ok so it seems that no one is much interested in this topic. :) Fortunately I have found the solution myself.
However, it involved a lot of analysis (of both obex transfer protocol and 32feet library) and a bit of luck.
The difference between Linux obexpushd implementation lies in its interpretation of OBEX transfer packets.
I found the OBEX specification on page: OBEX specification.
After debugging the internals of the 23feet obex transfer I found where the code sends the OBEX PUT command used to send file to the receiver. Obex specification gives the following example for PUT inititialization packet:
PUT Command | length of packet | Name header | Length of Name header | name of object | Length header | Length of object | Object Body chunk header | Length of Body header | bytes of body
The 32feet library sends the first packet without the Body Header which causes error in obexpushd Linux command.
Not shure if it is error in 32feet library, obexpushd or if the OBEX specification is not precise enough, but adding the Body header to the first packet solved the problem. From my experiments it turns out that at least 2 first bytes of the objectt must be sent in the first packet. Moreover, adding the header does not crash anything else and Windows<->Windows transfer still works very well.

Categories