Cyberiafreak

"Fortunate are those who take the first steps.” ― Paulo Coelho

Debugview.exe as rescue tool

DebugView is a developer friendly tool helps you to monitor debug output messages from local or nw system – from managed/unmanaged code. Recently I was debugging managed COM dll created in C# consumed in office application. I wanted a tool to debug end to end, Let say, your Office files VBA macro calls .NET COM dll for processing some complex logic and then returns the value to your macro.

In dev environment, we usually attach VS to the application and debug them, in VBA using debug.print statements. Assume that, you don’t have VS at your production server or customer machine where you wanted to debug them badly. Here is where debugview comes for rescue.

To write, debug statements from managed code, use Diagnostic having Debug.writeline. For VBA, use OutputDebugString. For other languages – use as here.

C#:- System.Diagnostics.Debug.WriteLine("This is from .NET before word instance.");

VBA:- Private Declare Sub OutputDebugString Lib "kernel32" Alias "OutputDebugStringA" (ByVal lpOutputString As String)
Private Sub DebugPrint(dbgOutput As String)
OutputDebugString dbgOutput
End Sub
Sub test()
DebugPrint ("Test message for the debugger")
End Sub

Note: Make sue you run as “Admin”.

debug1

debug

Advertisements

March 22, 2015 Posted by | .NET General, Office | , , , | Leave a comment

Languages features in C# 6 and VB 14

https://roslyn.codeplex.com/wikipage?title=Language%20feature%20status

Feature Example C# VB
Auto-property initializers public int X { get; set; } = x; Added Exists
Getter-only auto-properties public int Y { get; } = y; Added Added
Ctor assignment to getter-only autoprops Y = 15 Added Added
Parameterless struct ctors Structure S : Sub New() : End Sub : End Structure Added Added
Using static members using System.Console; … Write(4); Added Exists
Dictionary initializer new JObject { [“x”] = 3, [“y”] = 7 } Added No
Await in catch/finally try … catch { await … } finally { await … } Added No
Exception filters catch(E e) if (e.Count > 5) { … } Added Exists
Partial modules Partial Module M1 N/A Added
Partial interfaces Partial Interface I1 Exists Added
Multiline string literals “Hello<newline>World” Exists Added
Year-first date literals Dim d = #2014-04-03# N/A Added
Line continuation comments Dim addrs = From c in Customers ‘ comment N/A Added
TypeOf IsNot If TypeOf x IsNot Customer Then … N/A Added
Expression-bodied members public double Dist => Sqrt(X * X + Y * Y); Added No
Null propagation customer?.Orders?[5]?.$price Added Added
String interpolation $”{p.First} {p.Last} is {p.Age} years old.” Added* Planned
nameof operator string s = nameof(Console.Write); Added* Planned
#pragma #Disable Warning BC40008 Added Added
Smart name resolution N/A Added
ReadWrite props can implement ReadOnly Exists Added
#region inside methods Exists Added
Overloads inferred from Overrides N/A Added
CObj in attributes Exists Added
CRef and parameter name Exists Added
Extension Add in collection initializers Added Exists
Improved overload resolution Added N/A

December 13, 2014 Posted by | Uncategorized | , | Leave a comment

How to create your first Office Com Addin

1) Create a C# class library project

2) Add Extensibility reference to the project
 namespace ClassLibrary1
 {
 public class Class1 : Extensibility.IDTExtensibility2

3) Implement the interface method and place a messagebox OnStartupComplete to test
4) From Project properties > Build > "Register for COM interop"
5) From Project properties > Application > Assembly information > "Make assembly COM Visible
6) Compile - VS should automatically build and register the COM to the registry
7) This would create something like this,
 Windows Registry Editor Version 5.00
   [HKEY_CLASSES_ROOT\ClassLibrary1.Class1\CLSID]
 @="{0D39F056-DF63-3860-9E79-B57F6358FD4D}"
8) Now, create the below registry file "a.reg" save and run to create this entry under HCU
For Excel, create under Excel and accordingly for other product
 Windows Registry Editor Version 5.00
 [HKEY_CURRENT_USER\Software\Microsoft\Office\Excel\Addins\ClassLibrary1.Class1]
 "LoadBehavior"=dword:00000003
Copy "{0D39F056-DF63-3860-9E79-B57F6358FD4D}" and search under HKEY_CLASS_ROOT\CLSID
Windows Registry Editor Version 5.00
 [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0D39F056-DF63-3860-9E79-B57F6358FD4D}]
 @="ClassLibrary1.Class1"
 [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0D39F056-DF63-3860-9E79-B57F6358FD4D}\Implemented Categories]
 [HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0D39F056-DF63-3860-9E79-B57F6358FD4D}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0D39F056-DF63-3860-9E79-B57F6358FD4D}\InprocServer32] @="mscoree.dll"
 "ThreadingModel"="Both"
 "Class"="ClassLibrary1.Class1"
 "Assembly"="ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
 "RuntimeVersion"="v4.0.30319"
 "CodeBase"="file:///c:/users/maheshk/documents/visual studio 2013/Projects/ClassLibrary1/ClassLibrary1/bin/Debug/ClassLibrary1.dll"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0D39F056-DF63-3860-9E79-B57F6358FD4D}\InprocServer32\1.0.0.0]
 "Class"="ClassLibrary1.Class1"
 "Assembly"="ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
 "RuntimeVersion"="v4.0.30319"
 "CodeBase"="file:///c:/users/maheshk/documents/visual studio 2013/Projects/ClassLibrary1/ClassLibrary1/bin/Debug/ClassLibrary1.dll"
[HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{0D39F056-DF63-3860-9E79-B57F6358FD4D}\ProgId]
@="ClassLibrary1.Class1"
9) Now launch, Excel should see the message box on load - means this add-in loaded because of load behavior set as "3" - load at start. ( at the step #8 )

10)You can check this, by Excel > File > Options > Addins > Active Application Addin: ClassLibrary1.Class, location: mscoree.dll, COM Add-in

11) Register: 
"%WINDIR%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /codebase ComAddin\bin\Debug\ComAddin.dll
"%WINDIR%\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" /unregister ComAddin\bin\Debug\ComAddin.dll

Note: You may get access denied if you did not run as VS in Admin mode. 

Refer - http://support.microsoft.com/kb/302901
Download my sample - http://1drv.ms/1GzJP1N 
Download C++ sample - http://1drv.ms/1GzK4tH

November 8, 2014 Posted by | .NET General, Office, Outlook | , | Leave a comment

How to use EWS API for reading SMIME email message

What is SMIME – http://technet.microsoft.com/en-us/library/aa995740(v=exchg.65).aspx 

class Program
{
static ExchangeService exService;

static void Main(string[] args)
{
try
{
exService = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
exService.UseDefaultCredentials = true;
exService.AutodiscoverUrl(“user@Contoso.com”, RedirectionCallback);

Console.WriteLine(“Connected(Autodiscovered EWS Endpoint)- ” + exService.Url);

//find the trace log dumped in debug\log.txt
exService.TraceEnabled = true;
exService.TraceListener = new TraceListener();
exService.TraceEnablePrettyPrinting = true;

Console.WriteLine(“Getting inbox items..”);
byte[] data = GetInboxMailItems();

if (data == null)
{
Console.WriteLine(“No Mails retreived “);
Console.ReadKey();
return;
}
//
byte[] resultObject= DecryptToFile(data);

if(resultObject==null)
{
Console.WriteLine(“No object retrieved from Decrypt. somthing wrong in this method”);

}
else
{
string uniqueFname = Path.GetRandomFileName()+”.eml”;
Console.WriteLine(@”Decrypted EML file dumped here — c:\temp\” + uniqueFname);

//Find the decrypted file here
//Load this file in Outlook for testing.
File.WriteAllBytes(@”c:\temp\” + uniqueFname, resultObject);
}

//write the decrypted content to a file – mail item .eml
Console.WriteLine(“Press any key to exit..”);
Console.ReadKey();
}
catch (Exception ex)
{
Console.WriteLine(“Error while initializing..” + ex.ToString());
}
}

/// <summary>
///
/// </summary>
private static byte[] GetInboxMailItems()
{
byte[] data = null;

//Get inbox unread mails (have a mail ready for decrypt which is signed & decrypt)
Folder inbox = Folder.Bind(exService, WellKnownFolderName.Inbox);
SearchFilter sf = new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false));

ItemView view = new ItemView(1);

FindItemsResults<Item> findResults = exService.FindItems(WellKnownFolderName.Inbox, sf, view);

//Have atleast 1 unread ‘encrypted,signed’ mail for this testing
if (findResults.TotalCount == 0)
{
return data;
Console.WriteLine(“No Mails retreived”);
}

//Loop through the items and do whatever is required.
foreach (Item item in findResults)
{
//Load the mail item
PropertySet ps = new PropertySet(BasePropertySet.FirstClassProperties, ItemSchema.Attachments);
item.Load(ps);

foreach (Microsoft.Exchange.WebServices.Data.Attachment attach in item.Attachments)
{
// find the encrypted mails attachment- in general body and any mail content for encrypted mail would be bundled as smime.p7m file in mailstore
if (attach.Name == “smime.p7m”)
{
Console.WriteLine(“Process smime.p7m file”);
FileAttachment fileAttachment = (FileAttachment)attach;
MemoryStream stream = new MemoryStream();
fileAttachment.Load(stream);
StreamReader stReader = new StreamReader(stream);
stream.Seek(0, SeekOrigin.Begin);
data = stream.GetBuffer();

return data;
}
}
}
return data;
}

/// <summary>
///
/// </summary>
/// <param name=”data”></param>
private static byte[] DecryptToFile(byte[] data)
{
byte[] resultObject = null;

try
{
EnvelopedCms envelopObj = new EnvelopedCms();
envelopObj.Decode(data);

Console.WriteLine(“Encryption Algorithm: Name={0}”, envelopObj.ContentEncryptionAlgorithm.Oid.FriendlyName);
Console.WriteLine(“Key length={0}”, envelopObj.ContentEncryptionAlgorithm.KeyLength);
Console.WriteLine(“Recipients ({0})”, envelopObj.RecipientInfos.Count);

foreach (RecipientInfo r in envelopObj.RecipientInfos)
{
Console.WriteLine(” Encrypted key={0}”, BitConverter.ToString(r.EncryptedKey));
Console.WriteLine(” Encryption alg={0}”, r.KeyEncryptionAlgorithm.Oid.FriendlyName);

if (r.RecipientIdentifier.Type == SubjectIdentifierType.IssuerAndSerialNumber)
{
X509IssuerSerial xi = (X509IssuerSerial)r.RecipientIdentifier.Value;
Console.WriteLine(” Issuer={0}”, xi.IssuerName);
Console.WriteLine(” SerialNumber={0}”, xi.SerialNumber);
}
else
{
Console.WriteLine(” SubjectKeyInfo={0}”, r.RecipientIdentifier.Value);
}
}

Console.WriteLine(“Certificates ({0})”, envelopObj.Certificates.Count);

foreach (X509Certificate2 cert in envelopObj.Certificates)
{
Console.WriteLine(“Subject={0}”, cert.SubjectName);
}

Console.WriteLine(“Unprotected Attributes ({0})”, envelopObj.UnprotectedAttributes.Count);

foreach (CryptographicAttributeObject obj in envelopObj.UnprotectedAttributes)
{
Console.WriteLine(obj.Oid.FriendlyName);
}

envelopObj.Decrypt();
Console.WriteLine(“Success. Decrypted… !!”);
resultObject = envelopObj.ContentInfo.Content;

return resultObject; ;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
return resultObject;
}

/// <summary>
///
/// </summary>
/// <param name=”url”></param>
/// <returns></returns>
static bool RedirectionCallback(string url)
{
// Return true if the URL is an HTTPS URL.
return url.ToLower().StartsWith(“https://&#8221;);
}
}

/// <summary>
///
/// </summary>
public class TraceListener : ITraceListener
{
#region ITraceListener Members

public void Trace(string traceType, string traceMessage)
{
CreateXMLTextFile(traceType + ” — ” + traceMessage.ToString());
}

#endregion

private void CreateXMLTextFile(string traceContent)
{
string strPath = System.AppDomain.CurrentDomain.BaseDirectory;
strPath = strPath + “\\Log.txt”;
System.IO.FileStream fs;
if (System.IO.File.Exists(strPath) == false)
{
fs = System.IO.File.Create(strPath);
}
else
{
fs = System.IO.File.OpenWrite(strPath);
}

fs.Close();

// Create an instance of StreamWriter to write text to a file.
System.IO.StreamWriter sw = System.IO.File.AppendText(strPath);
sw.WriteLine(System.DateTime.Now.ToString() + “: ” + traceContent);
sw.Close();

}
}

April 15, 2014 Posted by | Uncategorized | , , | 13 Comments

How to convert Hex to Base64 in C#

Base64 is a group of similar binary-to-text encoding schemes that represent binary data in an ASCII string format by translating it into a radix-64 representation. The term Base64 originates from a specific MIME content transfer encoding.

Base64 encoding schemes are commonly used when there is a need to encode binary data that needs to be stored and transferred over media that is designed to deal with textual data. This is to ensure that the data remains intact without modification during transport. Base64 is commonly used in a number of applications including email via MIME, and storing complex data in XML.

//Convert Hex to Base64
static void Main(string[] args)
{
string hexstr = “040000008200E00074C5B7101A82E0080000000622029301EB4592B71528F44A48D7”;
byte[] data = ConvertFromStringToHex(hexstr);
string base64 = Convert.ToBase64String(data);

Console.WriteLine(base64);
}

public static byte[] ConvertFromStringToHex(string inputHex)
{
inputHex = inputHex.Replace(“-“, “”);

byte[] resultantArray = new byte[inputHex.Length / 2];
for (int i = 0; i < resultantArray.Length; i++)
{
resultantArray[i] = Convert.ToByte(inputHex.Substring(i * 2, 2), 16);
}
return resultantArray;
}

April 15, 2014 Posted by | Uncategorized | | Leave a comment

   

%d bloggers like this: