C# to vb.net conversion - vb.net

I need to convert this code from C# to VB. I'm not sure of the proper syntax.
C#
[XcoWorkerExtension(Optional = new Type[] { typeof(Subscribe<OnNewsArrived>) })]
private readonly XcoPublisher<OnNewsArrived> publisher = new XcoPublisher<OnNewsArrived>();
This is what I've come up with in VB:
<XcoWorkerExtension([Optional]:=New Type() {GetType(Subscribe(Of OnNewsArrived))})> _
Private ReadOnly publisher As New XcoPublisher(Of OnNewsArrived)()
The C# version runs fine but when I try to run the VB version I'm getting this exception:
System.IO.FileLoadException was unhandled
Message=The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)
Source=mscorlib
The exception is generated at the first line of this sub:
internal XcoWorkerExtensionAttribute Get_worker_extension_attribute(FieldInfo field)
{
object[] fieldAttrs = field.GetCustomAttributes(typeof(XcoWorkerExtensionAttribute), false);
object[] classAttrs = field.FieldType.GetCustomAttributes(typeof(XcoWorkerExtensionAttribute), false);
if (fieldAttrs.Length > 0 && classAttrs.Length == 0)
throw new XcoWorkerException("A field can only be marked with the XcoWorkerExtension attribute when its type is also marked with this attribute");
if (fieldAttrs.Length > 0)
return (XcoWorkerExtensionAttribute)fieldAttrs[0];
if (classAttrs.Length > 0)
return (XcoWorkerExtensionAttribute)classAttrs[0];
return null;
}

Sorry for giving a "meta answer".
For small conversions like this, Reflector is a nice tool if you are unsure about syntax and/or results.
Possibilities of use:
Compile in C#, and decompile to VB.Net.
Compile in VB.Net, compare to original

C# to VB Converter
Worked for one of my projects, though I suspect there are a few things that will make it unhappy. And you as well.

Related

How do I modify this code to use another project in the solution

public void Launch()
{
if (LinkedInstance != null) return;
LinkedInstance = new OrderInstance(ServiceLocation, Algorithm, MaxPrice, Limit, PoolData, ID, StartingPrice, StartingAmount);
if (HandlerDLL.Length > 0)
{
try
{
Assembly ASS = Assembly.LoadFrom(HandlerDLL);
Type T = ASS.GetType("HandlerClass");
HandlerMethod = T.GetMethod("HandleOrder");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
This code will open an assembly based on file name and assign HandlerMethod with T.GetMethod.
The thing is I do not want to create a dll file.
I want to do this with a project file in the solution.
The type of HandlerMethod is this
private MethodInfo HandlerMethod;
So How do I assign HandlerMethod to point to a method in a class I have.
It just happens that the name of the assembly of sample Handler is Handler Example
So I tried to change the code to this
Assembly ASS = Assembly.LoadFrom("HandlerExample");
Type T = ASS.GetType("HandlerClass");
HandlerMethod = T.GetMethod("HandleOrder");
It simply cause exception.
How do I arrange that ASS would refer to the dll file that is in another project in the solution. I want minimal code change.
If the method is present in some other project then you can either add a reference to that project and use the method directly, or if you want to use reflection, then Assembly ASS = Assembly.LoadFrom(HandlerDLL); will do the job that you are already using.
If the class is in the same project then you can use Assembly ASS = Assembly.GetExecutingAssembly(); and in this case you don't need to provide dll name.
Note: Though it is not mentioned by OP what language he is using, but the code looks like c# to me.

Call instance method inline after New statement

How can i convert this code to VB.net
public void SetBooks(IEnumerable<Book> books)
{
if (books == null)
throw new ArgumentNullException("books");
new System.Xml.Linq.XDocument(books).Save(_filename);
}
in http://converter.telerik.com/ it says:
Public Sub SetBooks(books As IEnumerable(Of Book))
If books Is Nothing Then
Throw New ArgumentNullException("books")
End If
New System.Xml.Linq.XDocument(books).Save(_filename)
End Sub
But visual studio says "Syntax error." because of "New"
What is the keyword for this situation, i searched on Google but no result.
Actually, you can do it in one line with the Call keyword
Call (New System.Xml.Linq.XDocument(books)).Save(_filename)
You cannot initialize an object and use it in one statement in VB.NET (as opposed to C#). You need two:
Dim doc = New System.Xml.Linq.XDocument(books)
doc.Save(_filename)
In C# the constructor returns the instance of the created object, in VB.NET not.

working with sqlce and ErikEJ.SqlCe library

i got this errors
Error 1 The type 'System.Data.SqlServerCe.SqlCeTransaction' is defined in an assembly is not referenced That. You Must add a reference to assembly 'System.Data.SqlServerCe, Version = 4.0.0.0, Culture = neutral, PublicKeyToken = 89845dcd8080cc91'.
WHERE DO I DOWNLOAD VERSION 4.0.0.0? I didn't find it.
Error 2 The type 'System.Data.SqlServerCe.SqlCeConnection' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91'.
same problem..
Error 3 The best overloaded method match for 'ErikEJ.SqlCe.SqlCeBulkCopy.WriteToServer (System.Data.DataTable)' Some invalid arguments have
overloaded? only i want to use it :s
Error 88 The best overloaded method match for 'ErikEJ.SqlCe.SqlCeBulkCopy.WriteToServer(System.Data.DataTable)' has some invalid arguments
?? it DOES allow datatable . i dont understand it..
Error 94 Argument '1': cannot convert from 'System.Data.DataTable [c:\Program Files\Microsoft.NET\SDK\CompactFramework\v3.5\WindowsCE\System.Data.dll]' to 'System.Data.DataTable []'
convert to datatable[]?? what?
well this is my method code.
private void DoBulkCopy(bool keepNulls, System.Data.DataTable tabla, string nombretabla)
{
if (tabla.Rows.Count > 0)
{
ErikEJ.SqlCe.SqlCeBulkCopyOptions options = new ErikEJ.SqlCe.SqlCeBulkCopyOptions();
if (keepNulls)
{
options = options |= ErikEJ.SqlCe.SqlCeBulkCopyOptions.KeepNulls;
}
//using (SqlCeBulkCopy bc = new SqlCeBulkCopy(connectionString, options))
using (SqlCeBulkCopy bc = new SqlCeBulkCopy(Resco.Data.Database.Instance.ConnectionString,options))
{
bc.DestinationTableName = nombretabla;
try
{
bc.WriteToServer(tabla);
}
catch(Exception ex) { }
}
}
}
Easy way -> install to project using Package Manager Console.
PM> Install-Package ErikEJ.SqlCeBulkCopy
See http://nuget.org/packages/ErikEJ.SqlCeBulkCopy

Reflection - Iterate object's properties recursively within my own assemblies (Vb.Net/3.5)

I wonder if anyone can help me - I've not done much with reflection but understand the basic principles.
What I'm trying to do:
I'm in the process of developing a class that gathers a lot of information about the local system, network, etc... to be used for automated bug reporting. Instead of having to change my test harness every time I add a new property, I'd (ideally) like to be able to serialise the lot as an XML string and just display that in a textbox.
Unfortunately, the Framework won't use the default XML serializer on read-only properties (which almost all of mine are) as they wouldn't deserialize properly
[Not sure I agree with the assumption that anything serialized must be de-serializable - MS says this is a feature "by design" which I suppose I can understand - Perhaps a tag to indicate that it should be serialized anyway would be advantageous?]
The initial approach was to make properties gettable and settable (with a throw exception on the setter) but the amount of work tidying this up afterwards seems a little excessive and I would want the properties to be read-only in the final version.
What I need help with:
My current plan is to use reflection to recursively iterate through each (public) property of my topmost gathering class. The problem is, the samples I've seen don't handle things recursively. Additionally, I only want to inspect an object's properties if it's in one of my assemblies - Otherwise just call .ToString on it.
If I don't have the inspection limited to my assembly, I assume I'll get (say) a string which then contains a Length which in turn will have .Tostring method...
For the purposes of this project, I can almost guarantee no circular references within my code and as this will only be used as a development tool so I'm not too concerned about it running amok now and then.
I'd appreciate some examples/advice.
Many thanks in advance.
This will hopefully get you started. It prints a tree directly to the console so you'll need to adjust to output XML. Then change the IsMyOwnType method to filter out the assemblies you're interested in, right now it only cares about types in the same assembly as itself.
Shared Sub RecurseProperties(o As Object, level As Integer)
For Each pi As PropertyInfo In o.GetType().GetProperties()
If pi.GetIndexParameters().Length > 0 Then Continue For
Console.Write(New String(" "c, 2 * level))
Console.Write(pi.Name)
Console.Write(" = ")
Dim propValue As Object = pi.GetValue(o, Nothing)
If propValue Is Nothing Then
Console.WriteLine("<null>")
Else
If IsMyOwnType(pi.PropertyType) Then
Console.WriteLine("<object>")
RecurseProperties(propValue, level+1)
Else
Console.WriteLine(propValue.ToString())
End If
End If
Next
End Sub
Shared Function IsMyOwnType(t As Type) As Boolean
Return t.Assembly Is Assembly.GetExecutingAssembly()
End Function
you extension version on c# to use on any object
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace Extensions
{
public static class ObjectExtension
{
public static string ToStringProperties(this object o)
{
return o.ToStringProperties(0);
}
public static string ToStringProperties(this object o, int level)
{
StringBuilder sb = new StringBuilder();
string spacer = new String(' ', 2 * level);
if (level == 0) sb.Append(o.ToString());
sb.Append(spacer);
sb.Append("{\r\n");
foreach (PropertyInfo pi in o.GetType().GetProperties())
{
if (pi.GetIndexParameters().Length == 0)
{
sb.Append(spacer);
sb.Append(" ");
sb.Append(pi.Name);
sb.Append(" = ");
object propValue = pi.GetValue(o, null);
if (propValue == null)
{
sb.Append(" <null>");
} else {
if (IsMyOwnType(pi.PropertyType))
{
sb.Append("\r\n");
sb.Append(((object)propValue).ToStringProperties(level + 1));
} else{
sb.Append(propValue.ToString());
}
}
sb.Append("\r\n");
}
}
sb.Append(spacer);
sb.Append("}\r\n");
return sb.ToString();
}
private static bool IsMyOwnType(Type t)
{
return (t.Assembly == Assembly.GetExecutingAssembly());
}
}
}

How to programmatically get DLL dependencies

How can I get the list of all DLL dependencies of a given DLL or EXE file?
In other words, I'd like to do the same as the "Dependency walker" tool, but programmatically.
What is the Windows (ideally .NET) API for that?
You can use EnumProcessModules function. Managed API like kaanbardak suggested won't give you a list of native modules.
For example see this page on MSDN
If you need to statically analyze your dll you have to dig into PE format and learn about import tables. See this excellent tutorial for details.
NOTE: Based on the comments from the post below, I suppose this might miss unmanaged dependencies as well because it relies on reflection.
Here is a small c# program written by Jon Skeet from bytes.com on a .NET Dependency Walker
using System;
using System.Reflection;
using System.Collections;
public class DependencyReporter
{
static void Main(string[] args)
{
//change this line if you only need to run the code one:
string dllToCheck = #"";
try
{
if (args.Length == 0)
{
if (!String.IsNullOrEmpty(dllToCheck))
{
args = new string[] { dllToCheck };
}
else
{
Console.WriteLine
("Usage: DependencyReporter <assembly1> [assembly2 ...]");
}
}
Hashtable alreadyLoaded = new Hashtable();
foreach (string name in args)
{
Assembly assm = Assembly.LoadFrom(name);
DumpAssembly(assm, alreadyLoaded, 0);
}
}
catch (Exception e)
{
DumpError(e);
}
Console.WriteLine("\nPress any key to continue...");
Console.ReadKey();
}
static void DumpAssembly(Assembly assm, Hashtable alreadyLoaded, int indent)
{
Console.Write(new String(' ', indent));
AssemblyName fqn = assm.GetName();
if (alreadyLoaded.Contains(fqn.FullName))
{
Console.WriteLine("[{0}:{1}]", fqn.Name, fqn.Version);
return;
}
alreadyLoaded[fqn.FullName] = fqn.FullName;
Console.WriteLine(fqn.Name + ":" + fqn.Version);
foreach (AssemblyName name in assm.GetReferencedAssemblies())
{
try
{
Assembly referenced = Assembly.Load(name);
DumpAssembly(referenced, alreadyLoaded, indent + 2);
}
catch (Exception e)
{
DumpError(e);
}
}
}
static void DumpError(Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Error: {0}", e.Message);
Console.WriteLine();
Console.ResetColor();
}
}
To get native module dependencies, I believe it should be ok to get it from the PE file's import table, here are 2 links which explain that in-depth:
http://msdn.microsoft.com/en-us/magazine/bb985992.aspx
http://msdn.microsoft.com/en-us/magazine/cc301808.aspx
To get .NET dependencies, we can use .NET's API, like Assembly.Load.
To get a .NET module's all dependencies, How about combine the 2 ways - .NET assemblies are just PE file with meta data.
While this question already has an accepted answer, the documentation referenced in the other answers, where not broken, is old. Rather than reading through all of it only to find it doesn't cover differences between Win32 and x64, or other differences, my approach was this:
C:\UnxUtils\usr\local\wbin>strings.exe E:\the-directory-I-wanted-the-info-from\*.dll > E:\TEMP\dll_strings.txt
This allowed me to use Notepad++ or gvim or whatever to search for dlls that were still depending on MS dlls with 120.dll at the end of the dll name so I could find the ones that needed updating.
This could easily be scripted in your favorite language.
Given that my search for this info was with VS 2015 in mind, and this question was the top result for a Google search, I supply this answer that it may perhaps be of use to someone else who comes along looking for the same thing.
To read the DLL's (modules) loaded by a running exe, use the ToolHelp32 functions
Tool help Documentation on MSDN.
Not sure what it will show for a .Net running exe (I've never tried it). But, it does show the full path from where the DLL's were loaded. Often, this was the information I needed when trying to sort out DLL problems. .Net is supposed to have removed the need to use these functions (look up DLL Hell for more information).
If you don't want to load the assembly in your program, you can use DnSpy (https://www.nuget.org/packages/dnSpyLibs):
var assemblyDef = dnlib.DotNet.AssemblyDef.Load("yourDllName.dll");
var dependencies = assemblyDef.ManifestModule.GetAssemblyRefs();
Notice that you have all the infos you can want in the "ManifestModule" property.