473,727 Members | 2,033 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

problem with outlook express in c# [quite long]

Hi,

I'am new to this group so I would like to say "Hello" everyone
and here is my problem:

I'm writing a simple application (code is at the end of this message) witch
would list all mails from a directory from Outlook Express. I have:
- OE 6.0
- .NET Framework 1.1
- interface definition language for OE 6.0 - msoeapi.idl
- registered inetcomm.dll

When I try to get properties of messages something throws an error: "Object
reference not set to an instance of an object." (but only processing
particular messages - not all).

Here's a piece of code that reads properties of messages:

IStoreFolder isf = null;

HENUMSTORE hEnum = new HENUMSTORE();

MESSAGEPROPS pProps = new MESSAGEPROPS();

int wynik = 0;

try

{

ist.OpenFolder (90877, 0, out isf);

FOLDERPROPS p = new FOLDERPROPS();

p.cbSize = (System.UInt32) System.Runtime. InteropServices .Marshal.SizeOf (p);

isf.GetFolderPr ops(0, ref p);

MessageBox.Show (p.szName);

textBox1.Clear( );

pProps.cbSize =
(System.UInt32) System.Runtime. InteropServices .Marshal.SizeOf (pProps);
isf.GetFirstMes sage(0, 0, MESSAGEID_FIRST , ref pProps, ref hEnum);

for (int i = 0; i < p.cMessage; i++)

{

wynik = isf.GetNextMess age (hEnum, 0, ref pProps);

textBox1.Append Text(pProps.psz Subject + "(" + pProps.dwMessag eId + ")" +
"\r\n\r\n") ;

isf.FreeMessage Props(ref pProps);

}
}

catch (Exception ex)

{

MessageBox.Show ("Nie udalo sie pobrac maili z katalogu: "+ex.Messag e+ "\n"+
ex.StackTrace);

}

}

which is enclosed within a procedure, before of course I initialize
apropriate environment:

string classKey = "{E70C92A9-4BFD-11d1-8A95-00C04FB951F3}";

Type objType = Type.GetTypeFro mCLSID(new Guid(classKey)) ;

ist = (IStoreNamespac e) Activator.Creat eInstance(objTy pe);
ist.Initialize( 0, 0);

When I try to do some brute force (enclose section that reads properties
within try-catch and igonre errors) whole program hangs up (no response) -
some investigation shows that after ignoring first first error (Object
reference not set to an instance of an object.") program during reading
properties of the next message thorws an exception:
System.Executio nEngineExceptio n - which as I read in msdn is very, very bad.

When I switched to fast reading (setting MSGPROPS_FAST instead of 0) in
functions going through an enumeration (getFirstMessag e i getNextMessage) ,
everything is fine (means all mails have been read), but using
getMessageProps after that ends up with the same exceptions as I mentioned
above. So I thought it is a problem in a construction of structure storing
properties of message which I had to map in c#, but after running a program
in a debugger I saw that the whole structure is filled correctly (all
entries within a structure has right values) and I started to do many
different things with that structure (including declaring every pointer (I
didn't need) as System.UInt32), with no effect - always the same
exceptions - but only with particular messages. I also tried to compare
messages cousing exceptions with those that are read correctly, but I
couldn't find any tip.

I have code in C++, operating through the same inferfaces (from
msoeapi.idl), which works fine - so interfaces works - the last think I'm
thinking about is an error within an .net framework, and before posting it
do microsoft I want to try everything. So far I haven't tried .net framework
2.0 - I want to know why it's not workinkg with 1.1

I'm running out of ideas, maybe somebody has any suggestions ? - would be
thankful.

PS. sorry for my poor english and that messages in messagebox are in polish
Slawomir Nasiadka

Code
using System;

using System.Drawing;

using System.Collecti ons;

using System.Componen tModel;

using System.Windows. Forms;

using System.Data;

using System.Runtime. InteropServices ;

namespace outlook_express _03

{

/// <summary>

/// Summary description for Form1.

/// </summary>

///

[StructLayout(La youtKind.Sequen tial)]

public struct HENUMSTORE

{

public System.UInt32 unused;

}

[StructLayout(La youtKind.Sequen tial, Pack=1)]

public struct FOLDERPROPS /*: ValueType*/

{

public System.UInt32 cbSize;

public System.UInt32 dwFolderId;

public System.Int32 cSubFolders;

public SPECIALFOLDER sfType;

public System.UInt32 cUnread;

public System.UInt32 cMessage;

[MarshalAs(Unman agedType.ByValT Str, SizeConst=256)] public String szName;

}

public enum SPECIALFOLDER : int

{

FOLDER_NOTSPECI AL = -1,

FOLDER_INBOX = FOLDER_NOTSPECI AL + 1,

FOLDER_OUTBOX = FOLDER_INBOX + 1,

FOLDER_SENT = FOLDER_OUTBOX + 1,

FOLDER_DELETED = FOLDER_SENT + 1,

FOLDER_DRAFT = FOLDER_DELETED + 1,

FOLDER_MAX = FOLDER_DRAFT + 1

}

public enum IMSGPRIORITY : int

{

IMSG_PRI_NORMAL = 2,

IMSG_PRI_LOW = 1,

IMSG_PRI_HIGH = 3

}

[ComImport,

Guid("E70C92AA-4BFD-11d1-8A95-00C04FB951F3"),

InterfaceType(C omInterfaceType .InterfaceIsIUn known)

]

public interface IStoreNamespace

{

int Initialize([In] int a, [In] int b);

int GetDirectory([Out(), MarshalAs(Unman agedType.LPStr)]
System.Text.Str ingBuilder pszPath, [In] System.Int32 cchMaxPath);

int OpenSpecialFold er (SPECIALFOLDER sfType, System.UInt32 dwReserved,
[MarshalAs(Unman agedType.Interf ace)] out IStoreFolder ppFolder);

int OpenFolder(Syst em.UInt32 storeFolderID, System.UInt32 dwReserved,
[MarshalAs(Unman agedType.Interf ace)] out IStoreFolder ppFolder);

int CreateFolder (System.UInt32 storeFolderID, System.String pszName,
System.UInt32 dwReserved, out System.UInt32 pdwFolderID);

int RenameFolder ([In] System.UInt32 storeFolderID, [In] System.UInt32
Reserved, [In] System.String NewName);

int MoveFolder (int param1, int param2, int param3);

int DeleteFolder (int param1, int param2);

int GetFolderProps (System.UInt32 storeFolderID, System.UInt32 dwReserved,
ref FOLDERPROPS props);

int CopyMoveMessage s (int p1, int p2, int p3, int p4, int p5, int p6);

int RegisterNotific ation (int p1, int p2);

int UnregisterNotif ication (int p1, int p2);

int CompactAll (int p1);

int GetFirstSubFold er(System.UInt3 2 storeFolderID, ref FOLDERPROPS props,
ref HENUMSTORE phEnum);

int GetNextSubFolde r (HENUMSTORE hEnum, ref FOLDERPROPS props);

int GetSubFolderClo se (HENUMSTORE hEnum);

}

[StructLayout(La youtKind.Sequen tial)]

public struct FILETIME/* : System.ValueTyp e */

{

public System.UInt32 dwHighDateTime;

public System.UInt32 dwLowDateTime;

}

[StructLayout(La youtKind.Sequen tial)]

public struct MESSAGEPROPS

{

public System.UInt32 cbSize;

public System.UInt32 dwReserved;

public System.UInt32 dwMessageId;

public System.UInt32 dwLanguage;

public System.UInt32 dwState;

public System.UInt32 cbMessage;

public /*IMSGPRIORITY*/System.UInt32 priority;

public FILETIME ftRecived;

public FILETIME ftSent;

public System.String pszSubject;

public System.String pszDisplayTo;

public System.String pszDisplayFrom;

public System.String pszNormalSubjec t;

public System.UInt32 dwFlags;

[MarshalAs(Unman agedType.IUnkno wn)]

public IStream pstmOffsetTable ;

}

[ComImport,

Guid("E70C92AC-4BFD-11d1-8A95-00C04FB951F3"),

InterfaceType(C omInterfaceType .InterfaceIsIUn known)

]

public interface IStoreFolder

{

int GetFolderProps (System.UInt32 dwReserved, ref FOLDERPROPS pProps);

int GetMessageProps (System.UInt32 dwMessageId, System.UInt32 dwFlags, ref
MESSAGEPROPS pProps);

int FreeMessageProp s(ref MESSAGEPROPS pProps);

int DeleteMessages( int param1, System.UInt32 dwReserved, int param2);

int SetLanguage(Sys tem.UInt32 dwLanguage, System.UInt32 dwReserved, int
param1);

int MarkMessagesAsR ead(int param1, System.UInt32 dwReserved, int param2);

int SetFlags(int param1, System.UInt32 dwState, System.UInt32 dwStatemask,
int param4);

int OpenMessage(Sys tem.UInt32 dwMessageId, int param1, int param2);

int SaveMessage(int param1, int param2, System.UInt32 dwMsgFlags,int
param3);

int BatchLock(Syste m.UInt32 dwReserved, int param1);

int BatchFlush(Syst em.UInt32 dwReserved,int param1);

int BatchUnlock(Sys tem.UInt32 dwReserved, int param1);

int CreateStream(in t param1, System.UInt32 dwReserved, int param2, int
param3);

int CommitStream(in t param1, System.UInt32 dwFlags, System.UInt32
dwMsgFlags, int param2, int param3, int param4);

int RegisterNotific ation(System.UI nt32 dwReserved, int param1);

int UnregisterNotif ication(System. UInt32 dwReserved, int param1);

int Compact(System. UInt32 dwReserved);

int GetFirstMessage (System.UInt32 dwFlags, System.UInt32 dwMsgFlags,
System.UInt32 dwMsgIdFirst, ref MESSAGEPROPS pProps, ref HENUMSTORE phEnum);

int GetNextMessage( HENUMSTORE hEnum, System.UInt32 dwFlags, ref MESSAGEPROPS
pProps); // When function returns S_OK, contains message properties

int GetMessageClose (HENUMSTORE hEnum);

}

[ComImport,

Guid("0C733A30-2A1C-11CE-ADE5-00AA0044773D"),

InterfaceType(C omInterfaceType .InterfaceIsIUn known)

]

public interface ISequentialStre am

{

int RemoteRead ( System.Byte pv , System.UInt32 cb , System.UInt32
pcbRead );

int RemoteWrite ( System.Byte pv , System.UInt32 cb , System.UInt32
pcbWritten );

}

[ComImport,

Guid("0000000C-0000-0000-C000-000000000046"),

InterfaceType(C omInterfaceType .InterfaceIsIUn known)

]

public interface IStream /*: ISequentialStre am*/

{

void Read([Out, MarshalAs(Unman agedType.LPArra y, SizeParamIndex= 1)] byte[]
pv, int cb, IntPtr pcbRead);

void Write([MarshalAs(Unman agedType.LPArra y, SizeParamIndex= 1)] byte[] pv,
int cb, IntPtr pcbWritten);

void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition );

void SetSize(long libNewSize);

void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten);

void Commit(int grfCommitFlags) ;

void Revert();

void LockRegion(long libOffset, long cb, int dwLockType);

void UnlockRegion(lo ng libOffset, long cb, int dwLockType);

void Stat(out STATSTG pstatstg, int grfStatFlag);

void Clone(out IStream ppstm);

}

public class Form1 : System.Windows. Forms.Form

{

private System.Windows. Forms.Button button1;

/// <summary>

/// Required designer variable.

/// </summary>

private System.Componen tModel.Containe r components = null;

private System.Windows. Forms.Button button5;

private System.Windows. Forms.TextBox textBox1;

private System.Windows. Forms.Button button7;

private IStoreNamespace ist;

const uint MESSAGEID_FIRST = 0xffffffff;

public Form1()

{

//

// Required for Windows Form Designer support

//

InitializeCompo nent();

//

// TODO: Add any constructor code after InitializeCompo nent call

//

}

/// <summary>

/// Clean up any resources being used.

/// </summary>

protected override void Dispose( bool disposing )

{

if( disposing )

{

if (components != null)

{

components.Disp ose();

}

}

base.Dispose( disposing );

}

#region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

private void InitializeCompo nent()

{

this.button1 = new System.Windows. Forms.Button();

this.button5 = new System.Windows. Forms.Button();

this.textBox1 = new System.Windows. Forms.TextBox() ;

this.button7 = new System.Windows. Forms.Button();

this.SuspendLay out();

//

// button1

//

this.button1.Lo cation = new System.Drawing. Point(24, 24);

this.button1.Na me = "button1";

this.button1.Si ze = new System.Drawing. Size(104, 23);

this.button1.Ta bIndex = 0;

this.button1.Te xt = "inicjuj namespace";

this.button1.Cl ick += new System.EventHan dler(this.butto n1_Click);

//

// button5

//

this.button5.Lo cation = new System.Drawing. Point(24, 152);

this.button5.Na me = "button5";

this.button5.Si ze = new System.Drawing. Size(152, 23);

this.button5.Ta bIndex = 4;

this.button5.Te xt = "pobierz wlasciwosci folderu";

this.button5.Cl ick += new System.EventHan dler(this.butto n5_Click);

//

// textBox1

//

this.textBox1.L ocation = new System.Drawing. Point(248, 16);

this.textBox1.M ultiline = true;

this.textBox1.N ame = "textBox1";

this.textBox1.S crollBars = System.Windows. Forms.ScrollBar s.Vertical;

this.textBox1.S ize = new System.Drawing. Size(304, 232);

this.textBox1.T abIndex = 5;

this.textBox1.T ext = "textBox1";

//

// button7

//

this.button7.Lo cation = new System.Drawing. Point(144, 88);

this.button7.Na me = "button7";

this.button7.Si ze = new System.Drawing. Size(96, 23);

this.button7.Ta bIndex = 7;

this.button7.Te xt = "maile z 6";

this.button7.Cl ick += new System.EventHan dler(this.butto n7_Click);

//

// Form1

//

this.AutoScaleB aseSize = new System.Drawing. Size(5, 13);

this.ClientSize = new System.Drawing. Size(576, 266);

this.Controls.A dd(this.button7 );

this.Controls.A dd(this.textBox 1);

this.Controls.A dd(this.button5 );

this.Controls.A dd(this.button1 );

this.Name = "Form1";

this.Text = "Form1";

this.Load += new System.EventHan dler(this.Form1 _Load);

this.ResumeLayo ut(false);

}

#endregion

/// <summary>

/// The main entry point for the application.

/// </summary>

[STAThread]

static void Main()

{

Application.Run (new Form1());

}

private void Form1_Load(obje ct sender, System.EventArg s e)

{
}

private void button1_Click(o bject sender, System.EventArg s e)

{

string classKey = "{E70C92A9-4BFD-11d1-8A95-00C04FB951F3}";

Type objType = Type.GetTypeFro mCLSID(new Guid(classKey)) ;

ist = (IStoreNamespac e) Activator.Creat eInstance(objTy pe);
ist.Initialize( 0, 0);

}

private void button5_Click(o bject sender, System.EventArg s e)

{

try

{

FOLDERPROPS p = new FOLDERPROPS();

p.cbSize = (System.UInt32) System.Runtime. InteropServices .Marshal.SizeOf (p);

ist.GetFolderPr ops(1, 0, ref p);

textBox1.Clear( );

textBox1.Append Text("Nazwa katalogu: "+p.szName+"\r\ n");

textBox1.Append Text("Numer katalogu: "+p.dwFolderId+ "\r\n");

textBox1.Append Text("Typ katalogu: "+p.sfType+"\r\ n");

textBox1.Append Text("Ilosc wiadomosci w tym folderze: "+p.cMessage+"\ r\n");

textBox1.Append Text("Ilosc wiadomosci nieprzeczytanyc h: "+p.cUnread+"\r \n");

textBox1.Append Text("Liczba podkatalogow: "+p.cSubFolders +"\r\n");

FOLDERPROPS p1 = new FOLDERPROPS();

HENUMSTORE hEnum = new HENUMSTORE();

p1.cbSize =
(System.UInt32) System.Runtime. InteropServices .Marshal.SizeOf (p1);

ist.GetFirstSub Folder(p.dwFold erId, ref p1, ref hEnum);

for (int i = 0; i < p.cSubFolders; i++)

{

textBox1.Append Text("\t"+p1.sz Name+" ("+p1.dwFolderI d+")"+"\r\n") ;

ist.GetNextSubF older(hEnum, ref p1);

}

ist.GetSubFolde rClose (hEnum);

}

catch (Exception ex)

{

MessageBox.Show ("Nie udalo sie pobrac wlasciwosci folderu: "+ex.Messag e+
"\n"+ ex.StackTrace);

}

}

private void button7_Click(o bject sender, System.EventArg s e)

{

IStoreFolder isf = null;

HENUMSTORE hEnum = new HENUMSTORE();

MESSAGEPROPS pProps = new MESSAGEPROPS();

int wynik = 0;

try

{

ist.OpenFolder (90877, 0, out isf); //90877 is a number of folder from which
mails will be listed (button5 lists all folders under the top folder with
their numbers)

FOLDERPROPS p = new FOLDERPROPS();

p.cbSize = (System.UInt32) System.Runtime. InteropServices .Marshal.SizeOf (p);

isf.GetFolderPr ops(0, ref p);

MessageBox.Show (p.szName);

textBox1.Clear( );

pProps.cbSize =
(System.UInt32) System.Runtime. InteropServices .Marshal.SizeOf (pProps);
isf.GetFirstMes sage(0, 0, MESSAGEID_FIRST , ref pProps, ref hEnum);

for (int i = 0; i < p.cMessage; i++)

{

wynik = isf.GetNextMess age (hEnum, 0, ref pProps);

textBox1.Append Text(pProps.psz Subject + "(" + pProps.dwMessag eId + ")" +
"\r\n\r\n") ;

isf.FreeMessage Props(ref pProps);

}
}

catch (Exception ex)

{

MessageBox.Show ("Nie udalo sie pobrac maili z katalogu: "+ex.Messag e+ "\n"+
ex.StackTrace);

}

}

}

}

and a simple mail causes an exception:

subject: bleble

content: This is a message that couses an exception.
Apr 11 '06 #1
0 2205

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
5780
by: Scott D. Barrish | last post by:
I know I can create a form using MAPISession and MAPIMessage objects and have practically the same functionallity as Outlook Express. The question I have is, is there a way to open up an Outlook Express "New Message" window from within VB 6.0?
13
9126
by: ~ Le Naja ~ | last post by:
Hello evrybody, First, I hope you will understand my English because I come from Belgium ! :-) Here is what I want to know if you have the kindess to help me ! :-) I use the code above to mail with outlook express ... x = Shell("C:\Program Files\Outlook Express\msimn.exe /mailurl:mailto:destinationAdress@name.be?subject=Hello&Body=mytext") But I don't find the way to put te adress of the sender, because if I don't put the adress of the...
5
2069
by: M. Laymon | last post by:
I just installed Python 2.3.3 under Windows XP professional. After I did, my wife tried to access her email using Outlook Express and got the error messages: Your server has unexpectedly terminated the connection. Possible causes for this include server problems, network problems, or a long period of inactivity. Account: 'incoming.verizon.net', Server: 'outgoing.verizon.net', Protocol: SMTP, Port: 25, Secure(SSL): No, Error Number:...
14
2145
by: Lee Mundie | last post by:
Hi, wonder if anyone can help me with this - This was originally a simple search routine returning results back to itself! Trying to be smart I tried to combine a no. items per page so I could limited items displayed... Okay problem! everything seems to be okay except it is returning no results, when I know it should the SQL string appears to be okay and if I remove the search criteria handlers then it kinda works but still not right!
12
4730
by: Arno R | last post by:
Hi all, This is a repost of a message posted at october 6. The answer I got was about MapiMessages.AttachmentIndex. I think I need the MSMAPI32.OCX to use this. (I don't have this file on my PC) My newsaccount wasn't working anymore until yesterday, so I'll try again. Question is: I know it is possible to send email with Access, but can one also automate the attachments?
0
1451
by: Ronny Sigo | last post by:
Hello all, I think I solved the problems I spoke off in my previous posts. I now use Outlook Express as the default email prog and no warnings pop up :):):):) Yiihaaa!!!! The only problem I still have is that message appears on screen on Outlook Express ... and I still have to click the send button. Does anybody know the setting to avoid this, thus sending the message right away, without displaying it ... Here is the code I use :
10
6865
by: greenb | last post by:
Our asp.net web app uses a .NET component (DLL) in the bin directory to call several stored procedures back to back to perform updates. They don't return any data. Sometimes the total execution time can take 2-3 minutes, but even though I have set the executionTimeout in web.config to a high number of seconds (2400), the request will still time out after 90 seconds. The user sees a Request timed out error. The app logs a ThreadAborted...
1
10423
by: handokowidjaja | last post by:
Hi All, Several weeks ago i started a topic with the same subject, however the solutions provided was for using MS Outlook (fullblown version). I finally found something that works directly with Outlook Express, however i dont know how to attach any document using the below code. If anybody knows how to do it, please help me to modify the below code and provide some sample on how to use it. Thanks in advance.
1
2720
by: zivon | last post by:
now for the bigger problam :) I know you pepole hate using OE for sending emails, but its user friendly and its needed in this case... I found on this forum, a code that sends email using OE with attachments. it works, but with two problams... first, its directly sends the email, without opening the OE "editing mode" of the email, like when you use the DoCmd.SendObject. this is the smaller problams though... the bigger problam...
0
8891
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
8752
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9406
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9185
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9120
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
4521
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4786
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3228
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2158
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.