Welcome to Kodyaz Development Resources Sign in | Join | Help

I have been busy! If you've had problems with .NET Mass Downloader working behind a proxy server, version 1.2 adds the –proxy command line switch if you need to specify server, username, password, and domain.

The –proxy switch uses the following form: server|username|password|domainname.

Also, .NET Mass Downloader works just fine with the Visual Studio Express versions. See my article on CodeProject on how to get the .NET Reference Source with Visual Studio Express.

Please let us know if you are still having proxy problems, or any other problems with .NET Mass Downloader.

P.S: Don't forget to vote for us :)

Back again :) In the following list you can see whole version released until today.

If you own one of the bold ones, .Net MassDownloader supports them whole.

Version Name Version Number Release Date
Pre-beta ?.?.????.? 2000-07-11
1.0 Beta 1 1.0.????.0 November 2000
1.0 Beta 2 1.0.2914.0 2001-06-20
1.0 RTM 1.0.3705.0 2002-01-05
1.0 SP1 1.0.3705.209 2002-03-19
1.0 SP2 1.0.3705.288 2002-08-07
1.0 SP3 1.0.3705.6018 2004-08-31
1.1 RTM 1.1.4322.573 2003-04-01
1.1 SP1 1.1.4322.2032 2004-08-30
1.1 SP1 (W2k3) 1.1.4322.2300 2005-03-30
1.1 KB893251 1.1.4322.2310 2005-03-25
1.1 KB927495 1.1.4322.2407 2007-02-21
2.0 RTM 2.0.50727.42 2005-11-07
2.0 RTM (Vista) 2.0.50727.312 2007-01-30
2.0 (KB928365) 2.0.50727.832 2007-07-10
2.0 SP1 2.0.50727.1433 2007-11-19
2.0 SP1 (Windows Server 2008 and Windows Vista SP1) 2.0.50727.1434 ?
3.0 RTM 3.0.4506.30 2006-11-06
3.0 RTM (Vista) 3.0.4506.26 2007-01-30
3.0 SP1 3.0.4506.648 2007-11-19
3.5 RTM 3.5.21022.8 2007-11-19

The feedback and downloads for .Net Mass Downloader have been quite pleasing! Kerem and I just went through and fixed all the reported bugs so the 1.1 release is better than ever. The big fixes were that we now properly handle paths with spaces in them (see what happens when you have two old DOS guys doing a project!), and if you had trouble behind a proxy server, you shouldn't any more. As always, let us know if you find any problems or have feature requests.

Just as a reminder, to download all the parts of the .NET Reference Source Code that Microsoft has released thus far, use the following command line (one line) on 32-bit:

NetMassDownloader.exe -d "C:\Windows\Microsoft.Net\Framework\v2.0.50727"
-d "C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5"

The following command line is for 64-bit:

NetMassDownloader.exe -d "C:\Windows\Microsoft.Net\Framework\v2.0.50727"
-d "C:\Windows\Microsoft.Net\Framework64\v2.0.50727"
-d "C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5"
-d "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5"

In the 64-bit example, Net Mass Downloader will do the right thing and only download the PDB files once if the same binaries are in different directories.

Of course, with both command lines, if you want to use the source with Visual Studio 2005 or even CodeGear's RAD Studio for you Delphi .NET fans, specify the –output option for the output directory. Follow the directions in the announcement post.

Just so you're not surprised, because we bumped up the version number of Net Mass Downloader, you will see the EULA prompt again.

Welcome to the .NET Mass Downloader project. While it’s great that Microsoft has released the .NET Reference Source Code, you can only get it one file at a time while you’re debugging. If you’d like to batch download it for reading or to populate the cache, you’d have to write a program that instantiated and called each method in the Framework Class Library. Fortunately, .NET Mass Downloader comes to the rescue!

The developed this project with John Robins, to enable mass downloading of .Net Framework Source Code without the need of VS2008, or to initialy populate your symbol server caches.

The project includes the following classes , which also you can find usefull:

  • A PE (Portable Executable) Parser : To Extract The Pdb Guids And Pdb Names from any given PE File. Developed by Kerem Kusmezer.
  • A PDB Parser And Patcher : I can extract whole streams from a pdb file, also patch every stream in a pdb file. Pure C# Code. Developed By Kerem Kusmezer.
  • A Webclient Class: Which allows direct connection with the referencesources server of Microsoft, also includes the 210 code parsing, eula text parsing. Developed By Kerem Kusmezer
  • SrcSrv class  Which Parses the srcsrv files included in each pdbs, to extract the url and file mappings of each source code mentioned in the pdb file. Developed By Kerem Kusmezer
  • Console Application: Developed by John Robins, which encapsulates whole functionality and allows the download of the code using different parameters.

You can download the project from : http://www.codeplex.com/NetMassDownloader

Using .NET Mass Downloader

Open a command or PowerShell prompt and navigate to where you extracted the current release. The tool itself is NetMassDownloader.exe and when run without parameters shows the following help screen:

.Net Mass Downloader 1.0.0.0 - (c) 2008 by Kerem Kusmezer, John Robbins
 
Batch download the Microsoft .NET Reference Source code.
 
Usage: NetMassDownloader [-file <file>]
                         [-directory <directory]
                         [-output <directory>]
                         [-vsver <version>]
                         [-force] [-nologo] [-verbose] [-?]
 
    -file      - Download an individual file's PDB and source code. You can
                 specify multiple file parameters. (Short -f).
    -directory - Download all the found PDB and source code for all files in
                 the specified directory. You can specify multiple
                 directory parameters (Short -d).
    -output    - The output directory for PDB and source files. The default
                 directory is the cache directory set in Visual Studio 2008.
                 By using the cache directory, you'll have the PDB and source
                 files available to Visual Studio 2008. However, to use the
                 .NET Reference Source Code with VS 2005, use the -output
                 switch and in the Options dialog, Debugging, Symbols property
                 page, add the specified output directory to the "Symbol file
                 (.pdb) locations." Also, add the directory to the Solution
                 Properties, Common Properties, Debug Source Files, Directories
                 containing source code location. The Visual Studio 2005
                 debugger will automatically load the source code. (Short -o)
    -vsver     - The Visual Studio version number to use for finding the cache
                 directory. The default is Visual Studio 2008,
                 but if you want to use the cache directory for Visual Studio
                 2005, you would pass '-vsver 8.0' (without quotes) (Short -vs)
    -force     - If specified, forces the downloading the PDB files into the
                 symbol server. When downloading to a symbol server if the PDB
                 exists, it's not downloaded. Using the -output switch will
                 always download and process the PDB. (Short -fo)
    -nologo    - Don't show the logo information. (Short -n)
    -verbose   - Do verbose output. May be worth turning on as the downloading
                 source code can take a long time. (Short -v)
    -?         - This help message.

The only required arguments are –file or –directory, both of which can be specified as many times as you’d like. When you specify a directory, only the .DLL and .EXE files from that directory will be processed. If you wanted to download all the source code from binaries in the .NET 2.0 32-bit and 64-bit directories, the command line you’d pass is: -d C:\Windows\Microsoft.NET\Framework\v2.0.50727 –d C:\Windows\Microsoft.NET\Framework64\v2.0.50727.

The main purpose of Net Mass Downloader is to populate the source code download cache for debugging, the default download location is the cache you specified to Visual Studio 2008. The –vsver switch to account for future Visual Studio versions so Mass Downloader could work with future CTPs and versions.

While it’s great to see the .NET Reference Source Code in Visual Studio 2008, there are a lot of developers out there who can’t upgrade yet, but would love to be able to debug into the .NET Reference Source Code. If you specify the -output parameter, the PDB and .NET Reference Source Code will be written to the specified directory. In Visual Studio 2005, place that directory in the Options dialog, Debugging, Symbols property page. In the “Symbol file (.pdb) locations” list box as the first item. Also in the Options dialog, Debugging, General property page, uncheck "Require source files to exactly match the original version." Finally, in each Visual Studio 2005 project go into the solution property pages, Common Properties, Debugging Source Files, and in the "Directories containing source code" add the output directory to the top of the list. That's enough for Visual Studio 2005 to debug into the .NET Reference Source Code.

When you first run Net Mass Downloader, you will be prompted with the current EULA for accessing the source code. If you don’t agree with the Microsoft EULA, clicking the Decline button will not download the source code.

Acknowledgements

Thanks to the Developer Division at Microsoft. First they released the .NET Reference Source Code, and second for allowing a couple of developers to have some fun and provide a utility for the community. Thank you for using .NET Mass Downloader. We just ask that you log any bugs and features into the project Issue Tracker.

If you have questions about particular pieces of the code, Kerem Kusmezer did the following parts: the PE (Portable Executable) Parser, the PDB Parser, the Webclient Class. and the SrcSrv class. John Robbins did the console driver, testing, and served as Kerem's code monkey.

You can contact my via keremskusmezer@gmail.com for requests and questions.

 

Check out the following project from Codeplex.

http://www.codeplex.com/SourceControl/DownloadSourceCode.aspx?ProjectName=Dynamic&changeSetId=10442

Dynamic Reflection Library

The Dynamic Reflection Library is a small set of classes designed to greatly speed the use of .Net reflection to call constructors, member methods, property setters and getters including those with indexing arguments such as the Item (a.k.a. [] operator), and fields.

The libary uses Lightweight Code Generation (LCG) to synthesize the minimum wrapper code to allow fully type-safe calls to arbitrary methods in any class through type-safe delgates. If appropriate runtime rights are available, these methods can even access private fields, methods and properties.

All members may be bound by name, or MemberInfo with optional automatic type coercision of the delegate's arguments to the called-method's argmuents. It also will do type-signature mapping to allow you to match a desired delegate signature and method name to the best-fit method.

Also included in this library is a DynamicCompare class, that generates a very-high performance IComparer method against any class for one or more fields/properties (with ascending/descending support). This allows you to generate the delegate to pass to Sort at runtime against a user-defined sort criteria and get near native speed.

Grab your copy from:

http://www.microsoft.com/downloads/details.aspx?FamilyID=10CC340B-F857-4A14-83F5-25634C3BF043&displaylang=en

Microsoft has release the beta version of the Service Pack 1 For Visual Studio 2005.

You can get it from here:

http://www.microsoft.com/downloads/details.aspx?FamilyID=8d702463-674b-4978-9e22-c989130f6553&DisplayLang=en

I wrote a little wrapper for Ngen .Net 2.0. It misses some features as ques , which will be implemented very soon.

Namespace CSFUpdater

Public NotInheritable Class NgenHelper

#Region "Private Variables"

Private Const NGENPATH As String = "ngen.exe"

Private Shared NgenFullPath As String

Private Shared ngenFound As Boolean

Private Shared resultCache As System.Text.StringBuilder

#End Region

Shared Sub New()

NgenFullPath = String.Format("{0}{1}", System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory, NGENPATH)

ngenFound = (System.IO.File.Exists(NgenFullPath))

End Sub

Private Sub New()

End Sub

Public Shared Function RegisterGivenDlls(ByVal ParamArray fileName As String()) As String

Return ""

End Function

Public Shared Function UnRegisterGivenDlls(ByVal ParamArray fileName As String()) As String

Return ""

End Function

Public Shared Function RegisterWholeApplicationDlls(Optional ByVal Debugable As Boolean = False) As String

Dim files() As String = System.IO.Directory.GetFiles(CSF.CO.ReflectionDynamicCompile.ReflectionUtilities.GetExecutingAssemblyPath, "*.dll")

Dim registerCache As New System.Text.StringBuilder()

Try

For Each file As String In files

registerCache.Append(StartGivenProcess(String.Format(" install {0}{1}{2}", Chr(34), file, Chr(34)), CSF.CO.ReflectionDynamicCompile.ReflectionUtilities.GetExecutingAssemblyPath))

Next

Catch

End Try

Return registerCache.ToString()

End Function

Public Shared Function UnRegisterWholeApplicationDlls(Optional ByVal Debugable As Boolean = False) As String

Dim files() As String = System.IO.Directory.GetFiles(CSF.CO.ReflectionDynamicCompile.ReflectionUtilities.GetExecutingAssemblyPath, "*.dll")

Dim registerCache As New System.Text.StringBuilder()

Try

For Each file As String In files

registerCache.Append(StartGivenProcess(String.Format(" uninstall {0}{1}{2}", Chr(34), file, Chr(34)), CSF.CO.ReflectionDynamicCompile.ReflectionUtilities.GetExecutingAssemblyPath))

Next

Catch

End Try

Return registerCache.ToString()

End Function

Public Shared Function RefreshNgenCache() As String

Return StartGivenProcess(" update", "")

End Function

Private Shared Function StartGivenProcess(ByVal commandLine As String, ByVal workingDirectory As String) As String

Dim startInfo As ProcessStartInfo

resultCache = New System.Text.StringBuilder

Dim runningProcess As New Process

startInfo = runningProcess.StartInfo

With startInfo

.WindowStyle = ProcessWindowStyle.Hidden

.RedirectStandardOutput = True

.RedirectStandardError = True

.UseShellExecute = False

If Not (String.IsNullOrEmpty(workingDirectory)) Then

.WorkingDirectory = workingDirectory

End If

End With

AddHandler runningProcess.OutputDataReceived, AddressOf OutputDataReceived

runningProcess.Start()

With runningProcess

.BeginOutputReadLine()

.BeginErrorReadLine()

.WaitForExit()

End With

Return resultCache.ToString()

End Function

Private Shared Sub OutputDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs)

resultCache.Append(e.Data)

End Sub

Private Shared Sub NgenLibraries()

Try

Dim startInfo As ProcessStartInfo

Dim ngenProcess As Process

Dim files() As String = System.IO.Directory.GetFiles(CSF.CO.ReflectionDynamicCompile.ReflectionUtilities.GetExecutingAssemblyPath, "*.dll")

Try

For Each file As String In files

startInfo = New ProcessStartInfo(String.Format("{0}{1}", System.Runtime.InteropServices.RuntimeEnvironment.GetRuntimeDirectory, NGENPATH), String.Format(" install {0}{1}{2}", Chr(34), file, Chr(34)))

startInfo.WorkingDirectory = CSF.CO.ReflectionDynamicCompile.ReflectionUtilities.GetExecutingAssemblyPath

ngenProcess = Process.Start(startInfo)

ngenProcess.WaitForExit()

Next

Catch

End Try

Catch ex As System.Exception

End Try

End Sub

End Class

End Namespace

Well as i surfed the web i came across this nice article:

http://weblogs.asp.net/ssharrock/archive/2003/04/20/5875.aspx

A little bit late but it shows you this tip:

Just two simple steps to client-side debugging nirvana.
  1. Clear the "disable script debugging" checkbox in Internet Explorer's advanced properties.
  2. Add the keyword "debugger" somewhere within your JavaScript.

And VS will launch and enable you to debug your script as you were debugging C#.

Greate Feature Thx VS Guys :)

Happy Debugging

Microsoft has just created a test drive page for Office 2007 Beta,

Where you can Test Drive The Features.

http://www.microsoft.com/office/preview/beta/testdrive.mspx

You can also get the beta version at $2, which expires next year.

I have downloaded it yesterday , and tested the new Office Features.

There are a lot of improvements in the Outlook Object Model especially for com-addin and Outlook Forms Developers.

Some Links For Consolidated Development in Outlook 2007:

http://www.microsoft.com/downloads/details.aspx?familyid=09c426ce-b06d-415c-a9e1-976268e16181&displaylang=en

What is new for Developers in Outlook 2007:

http://msdn.microsoft.com/office/program/outlook/2007/default.aspx

http://www.microsoft.com/downloads/details.aspx?FamilyID=AABF127D-D069-4549-A1B1-667A698C3EF6&displaylang=en

Happy Customizing.

In the project that i am working, there is a interop between Com and .Net where the Com Functions Expect Recordsets And They also provide Recordsets back to the .Net.

Using System.Xml namespace and some schema parsing code i am able to convert between DataSet Generated Xml Files And Recordset Generated using .Net without any need of reference to the ADO Com Libraries.

First Part Is DataSet To Recordset:

Option Strict Off

#Region "Imported Libraries"

Imports System.IO

Imports System.Xml

Imports System.Text

#End Region

Namespace AdoClassic

''' <summary>

''' This class converts a .NET DataSet to an ADODB Recordset.

''' Converts The Provided ADO.Net DataSet or Datatable Structures Into The ADO 2.5 Versions Recordset Objects Xml Based Representation using Schema Transformation And Dataset Xml Conversion.

''' Generally used for the transformation and data providing to the CSF.Reporting layer, so other Office Applications can use the Data Created By The CSF.

''' </summary>

''' <remarks></remarks>

Public NotInheritable Class AdoNetAdoClassicTools

Private Const MICROSOFTSCHEMAROWSET As String = "urn:schemas-microsoft-com:rowset"

''' <summary>

''' Initializes a new instance of the <see cref="T:ADONETToADOClassic" /> class.

''' </summary>

Private Sub New()

End Sub

''' <summary>

''' Converts The Given Recordset Xml File To DataSet

''' </summary>

''' <param name="fileName"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Shared Function ConvertRecordsetXmlToDataSet(ByVal fileName As String) As DataSet

Return ConvertRecordsetXmlToDataSet(New FileStream(fileName, FileMode.Open))

End Function

''' <summary>

''' Converts The Given Recordset Xml File To DataSet

''' </summary>

''' <param name="recordsetXml"></param>

''' <returns></returns>

''' <remarks></remarks>

Public Shared Function ConvertRecordsetXmlToDataSet(ByVal recordsetXml As Stream) As DataSet

Dim tempDocument As XmlDocument = New XmlDocument()

tempDocument.Load(recordsetXml)

recordsetXml.Close()

Return ParseOutSchemaInformation(tempDocument)

End Function

Private Shared Function ParseOutSchemaInformation(ByVal document As Xml.XmlDocument) As DataSet

'<s:AttributeType name="DelDate" rs:number="52" rs:nullable="true" rs:write="true">

' <s:datatype dt:type="string" dt:maxLength="20" rs:precision="0" rs:maybenull="false"/>

'</s:AttributeType>

Dim resultDataTable As New DataTable

With document

Dim nodeList As XmlNodeList = .GetElementsByTagName("AttributeType", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882")

For Each rsNode As XmlNode In nodeList

Dim fieldName As String = rsNode.Attributes("name").Value

Dim fieldType As String = ""

Dim fieldMaxLength As Integer = 0

Dim declarationRow As XmlNode = rsNode.ChildNodes(0)

Dim attributes As XmlAttributeCollection = declarationRow.Attributes

For Each attribute As XmlAttribute In attributes

Select Case attribute.Name

Case "dt:type"

fieldType = ResolveDataType(attribute.Value)

End Select

Next

Dim tempColumn As New DataColumn(fieldName, System.Type.GetType(fieldType))

resultDataTable.Columns.Add(tempColumn)

Next

End With

Return ParseOutData(document, resultDataTable)

End Function

Private Shared Function ResolveDataType(ByVal typeName As String) As String

'TODO Additional Data Type Conversions Should Be Added Here

Select Case typeName

Case "string"

Return "System.String"

Case "int"

Return "System.Int32"

Case "float"

Return "System.Double"

Case "boolean"

Return "System.Boolean"

Case "uuid"

Return "System.Guid"

Case Else

Return "System.String"

End Select

End Function

Private Shared Function ParseOutData(ByVal document As Xml.XmlDocument, ByVal ds As DataTable) As DataSet

With document

Dim nodeList As XmlNodeList = .GetElementsByTagName("row", "#RowsetSchema")

For Each dataNode As XmlNode In nodeList

Dim dr As DataRow = ds.NewRow()

For Each attribute As XmlAttribute In dataNode.Attributes

attribute.Normalize()

dr(attribute.Name) = attribute.Value

Next

ds.Rows.Add(dr)

Next

End With

Dim resultDataset As New DataSet()

resultDataset.Tables.Add(ds)

Return resultDataset

End Function

''' <summary>

''' Takes a DataSet and converts into a Recordset. The converted

''' ADODB recordset is returned as a Recordset persisted XML string.

''' </summary>

''' <param name="DS">DataSet object</param>

''' <param name="dbName">DataTable Name</param>

''' <returns>String containing ADODB formatted XML</returns>

''' <remarks></remarks>

Public Shared Function ConvertDataSetToAdoRecordset(ByVal DS As DataSet, ByVal dbName As String) As String

Dim mStream As New MemoryStream

Try

'Create a MemoryStream to contain the XML

'Create an XmlWriter object, to write the formatted XML to the MemoryStream

Dim xWriter As New XmlTextWriter(mStream, Nothing)

'Additional formatting for XML

xWriter.Indentation = 8

xWriter.Formatting = Formatting.Indented

'call this Sub to write the ADONamespaces

WriteADONamespaces(xWriter)

'call this Sub to write the ADO Recordset Schema

WriteSchemaElement(DS, dbName, xWriter)

'Call this sub to transform the data portion of the Dataset

TransformData(DS, xWriter, dbName)

'Flush all input to XmlWriter

xWriter.Flush()

'Prepare the return value

mStream.Position = 0

Dim Buffer As Array

Buffer = Array.CreateInstance(GetType(Byte), mStream.Length)

mStream.Read(Buffer, 0, mStream.Length)

Dim TextConverter As New UTF8Encoding

Return TextConverter.GetString(Buffer)

Catch ex As Exception

Return ""

Finally

mStream.Close()

'mStream.Dispose()

End Try

End Function

''' <summary>

''' Add ADO XML namespaces to the XML output

''' </summary>

''' <param name="xWriter">The x writer.</param>

''' <remarks></remarks>

Private Shared Sub WriteADONamespaces(ByRef xWriter As XmlTextWriter)

'Use the following line to change the encoding if special characters are required

'writer.WriteProcessingInstruction("xml", "version='1.0' encoding='ISO-8859-1'")

With xWriter

'Add XML start element

.WriteStartElement("", "xml", "")

'Append the ADO Recordset namespaces

.WriteAttributeString("xmlns", "s", Nothing, "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882")

.WriteAttributeString("xmlns", "dt", Nothing, "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882")

.WriteAttributeString("xmlns", "rs", Nothing, MICROSOFTSCHEMAROWSET)

.WriteAttributeString("xmlns", "z", Nothing, "#RowsetSchema")

.Flush()

End With

End Sub

''' <summary>

''' Add Schema element to the XML output

''' </summary>

''' <param name="DS">The DS.</param>

''' <param name="dbName">Name of the db.</param>

''' <param name="xWriter">The x writer.</param>

''' <remarks></remarks>

Private Shared Sub WriteSchemaElement(ByVal DS As DataSet, ByVal dbName As String, ByRef xWriter As XmlTextWriter)

'write element Schema

With xWriter

.WriteStartElement("s", "Schema", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882")

.WriteAttributeString("id", "RowsetSchema")

'write element ElementType

.WriteStartElement("s", "ElementType", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882")

'write the attributes for ElementType

.WriteAttributeString("name", "", "row")

.WriteAttributeString("content", "", "eltOnly")

.WriteAttributeString("rs", "updatable", MICROSOFTSCHEMAROWSET, "true")

WriteSchema(DS, dbName, xWriter)

'write the end element for ElementType

.WriteFullEndElement()

'write the end element for Schema

.WriteFullEndElement()

.Flush()

End With

End Sub

''' <summary>

''' Add field definitions to the schema

''' </summary>

''' <param name="DS"></param>

''' <param name="dbName"></param>

''' <param name="xWriter"></param>

''' <remarks></remarks>

Private Shared Sub WriteSchema(ByVal DS As DataSet, ByVal dbName As String, ByRef xWriter As XmlTextWriter)

Dim i As Int32 = 1

Dim DC As DataColumn

For Each DC In DS.Tables(dbName).Columns

DC.ColumnMapping = MappingType.Attribute

With xWriter

.WriteStartElement("s", "AttributeType", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882")

.WriteAttributeString("name", "", DC.ToString)

.WriteAttributeString("rs", "number", MICROSOFTSCHEMAROWSET, i.ToString)

.WriteAttributeString("rs", "baseCatalog", MICROSOFTSCHEMAROWSET, dbName)

.WriteAttributeString("rs", "baseTable", MICROSOFTSCHEMAROWSET, DC.Table.TableName.ToString)

.WriteAttributeString("rs", "keycolumn", MICROSOFTSCHEMAROWSET, DC.Unique.ToString)

.WriteAttributeString("rs", "autoincrement", MICROSOFTSCHEMAROWSET, DC.AutoIncrement.ToString)

.WriteStartElement("s", "datatype", "uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882")

.WriteAttributeString("dt", "type", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882", GetDatatype(DC.DataType.ToString))

.WriteAttributeString("dt", "maxlength", "uuid:C2F41010-65B3-11d1-A29F-00AA00C14882", DC.MaxLength.ToString)

.WriteAttributeString("rs", "maybenull", MICROSOFTSCHEMAROWSET, DC.AllowDBNull.ToString)

'write end element for datatype

.WriteEndElement()

'end element for AttributeType

.WriteEndElement()

.Flush()

End With

i += 1

Next

DC = Nothing

End Sub

''' <summary>

''' Function to get the ADO compatible datatype

''' </summary>

''' <param name="DType"></param>

''' <returns></returns>

''' <remarks></remarks>

Private Shared Function GetDatatype(ByVal DType As String) As String

Select Case (DType)

Case "System.Int32", "System.Int16", "System.Integer"

Return "int"

Case "System.DateTime"

Return "dateTime.iso8601tz"

Case "System.String"

Return "string"

Case "System.Byte[]"

Return "bin.hex"

Case "System.Boolean"

Return "boolean"

Case "System.Guid"

Return "guid"

Case Else

Return "string"

End Select

End Function

''' <summary>

''' Transform the data format to ADO Recordset data format

''' This only transforms the data

''' </summary>

''' <param name="DS"></param>

''' <param name="xWriter"></param>

''' <remarks></remarks>

Private Shared Sub TransformData(ByVal DS As DataSet, ByRef xWriter As XmlTextWriter, ByVal tableName As String)

'Loop through DataSet and add data to XML

xWriter.WriteStartElement("", "rs:data", "")

Dim i As Long

Dim j As Integer

'For each row...

For i = 0 To DS.Tables(tableName).Rows.Count - 1

'Write the start element for the row

xWriter.WriteStartElement("", "z:row", "")

'For each field in the row...

For j = 0 To DS.Tables(tableName).Columns.Count - 1

'Write the attribute that describes this field and it's value

If DS.Tables(tableName).Columns(j).DataType.ToString = "System.Byte[]" Then

'Binary data must be properly encoded (bin.hex)

If Not IsDBNull(DS.Tables(tableName).Rows(i).Item(DS.Tables(tableName).Columns(j).ColumnName)) Then

xWriter.WriteAttributeString(DS.Tables(tableName).Columns(j).ColumnName, DataToBinHex(DS.Tables(tableName).Rows(i).Item(DS.Tables(tableName).Columns(j).ColumnName)))

End If

Else

If Not IsDBNull(DS.Tables(tableName).Rows(i).Item(DS.Tables(tableName).Columns(j).ColumnName)) Then

xWriter.WriteAttributeString(DS.Tables(tableName).Columns(j).ColumnName, CType(DS.Tables(tableName).Rows(i).Item(DS.Tables(tableName).Columns(j).ColumnName), String))

End If

End If

Next

'End the row element

xWriter.WriteEndElement()

Next

'Write the end element for rs:data

xWriter.WriteEndElement()

'Write the end element for xml

xWriter.WriteEndElement()

xWriter.Flush()

End Sub

''' <summary>

''' Helper function - encodes binary data to a bin.hex string

''' </summary>

''' <param name="thisData"></param>

''' <returns></returns>

''' <remarks></remarks>

Private Shared Function DataToBinHex(ByVal thisData As Byte()) As String

Dim sb As New StringBuilder

Dim i As Integer = 0

For i = 0 To thisData.Length - 1

'First nibble of byte (4 most significant bits)

sb.Append(Hex((thisData(i) And &HF0) / 2 ^ 4))

'Second nibble of byte (4 least significant bits)

sb.Append(Hex(thisData(i) And &HF))

Next

Return sb.ToString

End Function

End Class

End Namespace

The usage of the class is very simple:

Dim sampleDataSet as new DataSet()

Dim sampleDataTable as new DataTable()

sampleDataTable.TableName = "TestTable"

sampleDataTable.Columns.Add("TestColumn")

sampleDataSet.Tables.Add(sampleDataTable)

Dim adoxml as String = CSF.DAL.AdoClassic.AdoNetAdoClassicTools.ConvertDataSetToAdoRecordset(customerFactFileDataSet, dt.TableName)

just write out this adoxml to a file:

Dim file as new System.IO.FileStream("c:\result.xml",System.IO.FileMode.Create)

Dim writer as new System.IO.StreamWriter(file)

writer.Write(adoxml)

writer.Flush

writer.Close

And now the classic Vb 6.0 Part:

Private Function StringToRS(ByVal Value As String) As ADODB.Recordset
    On Error Resume Next
    Dim ADONETStream As New ADODB.Stream
    Dim RS As New ADODB.Recordset
    With ADONETStream
    .Open
    .WriteText (Value)
    .Position = 0
        RS.Open ADONETStream
    .Close
    End With
    Set ADONETStream = Nothing
    Set StringToRS = RS
End Function

Just Read The Above File As String

Set fs = CreateObject("Scripting.FileSystemObject")
Set file = fs.OpenTextFile("c:\test.txt", 1)
Dim resultString As String
resultString = file.ReadAll
file.Close
Dim resultset

set resultset = StringToRS(resultString)

Now you have a recordset that is generated from the DataSet without Com-Interop.

Part 2 of the series will have sample for converting from Recordset Generated Xml Files Directly To Datasets.

Happy Interoping

How many times you asked your self, what is going under the hood , if you call the function System.Net.WebClient.DownloadData, with .Net 2.0 you can see whole the requests going and coming when you call this method with 2 steps.

1) Just create a app.config file for your application

2) Add the following entries to your app.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.Net">
        <listeners>
          <add name="TraceFile" />
        </listeners>
      </source>   
    </sources>
    <sharedListeners>
      <add
        name="TraceFile"
        type="System.Diagnostics.TextWriterTraceListener"
        initializeData="NetTrace.log"
      />
    </sharedListeners>
    <switches>
      <add name="System.Net" value="Verbose" />
    </switches>
  </system.diagnostics>
</configuration>

3) Just Call WebClient.DownloadData from your code, you will have entries like this in your nettrace.log file and debug window:

ystem.Net Verbose: 0 : [3816] WebClient#47633461::DownloadData(http://www.yahoo.com/#2136786598)

System.Net Verbose: 0 : [3816] WebClient#47633461::DownloadData(http://www.yahoo.com/#2136786598)

System.Net Verbose: 0 : [3816] WebRequest::Create(http://www.yahoo.com/)

System.Net Verbose: 0 : [3816] HttpWebRequest#63130991::HttpWebRequest(http://www.yahoo.com/#2136786598)

System.Net Verbose: 0 : [3816] Exiting HttpWebRequest#63130991::HttpWebRequest()

System.Net Verbose: 0 : [3816] Exiting WebRequest::Create() -> HttpWebRequest#63130991

System.Net Verbose: 0 : [3816] HttpWebRequest#63130991::GetResponse()

System.Net Information: 0 : [3816] Associating HttpWebRequest#63130991 with ServicePoint#64981649

System.Net Information: 0 : [3816] Associating Connection#38493088 with HttpWebRequest#63130991

System.Net Information: 0 : [3816] Associating HttpWebRequest#63130991 with ConnectStream#54467399

System.Net Information: 0 : [3816] HttpWebRequest#63130991 - Request: GET http://www.yahoo.com/ HTTP/1.1

System.Net Information: 0 : [3816] ConnectStream#54467399 - Sending headers

{

Host: www.yahoo.com

Proxy-Connection: Keep-Alive

}.

System.Net Information: 0 : [3816] Connection#38493088 - Received status line: Version=1.1, StatusCode=407, StatusDescription=Proxy Authentication Required ( The ISA Server requires authorization to fulfill the request. Access to the Web Proxy service is denied. ).

System.Net Information: 0 : [3816] Connection#38493088 - Received headers

{

Proxy-Authenticate: NTLM,Basic realm="istwwebacs0.euea.corp.bshg.com",Kerberos,Negotiate

Via: 1.1 BLABLABLA

Connection: Keep-Alive

Proxy-Connection: Keep-Alive

Pragma: no-cache

Cache-Control: no-cache

Content-Type: text/html

Content-Length: 2381

}.

System.Net Information: 0 : [3816] ConnectStream#35113868::ConnectStream(Buffered 2381 bytes.)

System.Net Information: 0 : [3816] Associating HttpWebRequest#63130991 with ConnectStream#35113868

System.Net Information: 0 : [3816] Associating HttpWebRequest#63130991 with HttpWebResponse#36620214

System.Net Verbose: 0 : [3816] ConnectStream#35113868::Read()

System.Net Verbose: 0 : [3816] Data from ConnectStream#35113868::Read

System.Net Verbose: 0 : [3816] 00000000 : 3C 21 44 4F 43 54 59 50-45 20 48 54 4D 4C 20 50 : <!DOCTYPE HTML P

System.Net Verbose: 0 : [3816] 00000010 : 55 42 4C 49 43 20 22 2D-2F 2F 57 33 43 2F 2F 44 : UBLIC "-//W3C//D

System.Net Verbose: 0 : [3816] 00000020 : 54 44 20 48 54 4D 4C 20-34 2E 30 20 54 72 61 6E : TD HTML 4.0 Tran

System.Net Verbose: 0 : [3816] 00000030 : 73 69 74 69 6F 6E 61 6C-2F 2F 45 4E 22 3E 0D 0A : sitional//EN">..

System.Net Verbose: 0 : [3816] 00000040 : 3C 48 54 4D 4C 20 64 69-72 3D 6C 74 72 3E 3C 48 : <HTML dir=ltr><H

System.Net Verbose: 0 : [3816] 00000050 : 45 41 44 3E 3C 54 49 54-4C 45 3E 54 68 65 20 70 : EAD><TITLE>The p

System.Net Verbose: 0 : [3816] 00000060 : 61 67 65 20 63 61 6E 6E-6F 74 20 62 65 20 64 69 : age cannot be di

System.Net Verbose: 0 : [3816] 00000070 : 73 70 6C 61 79 65 64 3C-2F 54 49 54 4C 45 3E 0D : splayed</TITLE>.

System.Net Verbose: 0 : [3816] 00000080 : 0A 3C 53 54 59 4C 45 3E-41 3A 6C 69 6E 6B 20 7B : .<STYLE>A:link {

System.Net Verbose: 0 : [3816] 00000090 : 0D 0A 09 46 4F 4E 54 3A-20 38 70 74 2F 31 31 70 : ...FONT: 8pt/11p

System.Net Verbose: 0 : [3816] 000000A0 : 74 20 76 65 72 64 61 6E-61 3B 20 43 4F 4C 4F 52 : t verdana; COLOR

System.Net Verbose: 0 : [3816] 000000B0 : 3A 20 23 66 66 30 30 30-30 0D 0A 7D 0D 0A 41 3A : : #ff0000..}..A:

System.Net Verbose: 0 : [3816] 000000C0 : 76 69 73 69 74 65 64 20-7B 0D 0A 09 46 4F 4E 54 : visited {...FONT

System.Net Verbose: 0 : [3816] 000000D0 : 3A 20 38 70 74 2F 31 31-70 74 20 76 65 72 64 61 : : 8pt/11pt verda

 

This logging feature is enable for whole System.Net based classes , which is also used by the webservices.

 

Happy Tracing :)

What do you expect when you write *.bat , whole files ending with .bat , no just be careful, because it brings also files ending with bat_bla, batt, batter, etc.

So if you are using this expression with System.IO.Folder.GetFiles always check the extensions of the files using System.IO.Path.GetExtension before processing them.

Happy Coding.