Getting current file - vb.net

I know in vb.net you can use System.Reflection.MethodInfo.GetCurrentMethod.ToString to get the name of the current method you are in. However, is there a way to use System.Reflection... to get the name of the current file you are in?
So if you had a file in the project named blah.vb I would want System.Reflection... to return blah.vb
Is this possible?

You can use System.Reflection.Assembly to find the file name of the current assembly. There are several applicable methods to choose from:
GetEntryAssembly - Returns the assembly that started the process (the executable)
GetCallingAssembly - Returns the assembly that called the current method
GetExecutingAssembly - Returns the assembly in which the current method resides
I suspect that what you want is GetExecutingAssembly. All of those methods return an Assembly object through which you can get the file path, like this:
Dim myFilePath As String = System.Reflection.Assembly.GetExecutingAssembly().Location
For what it's worth, if you need get the file name of the executable, but it's not a .NET assembly (because you're in a .NET library invoked via COM), then the above method won't work. For that, the best option would be to grab the first argument from the command line, like this:
Dim myComExeFile As String = Environment.GetCommandLineArgs()(0)

Related

Is there any way to extract data from #Prompt_assignment# variable in automation anywhere?

There is a task to call DLL file and get output to the promptassignment variable in automation anywhere. That DLL returns the object (with student name and age). Is there any way to extract that students name and age from Promptassignmet variable without calling another DLL? Thnak you in advance.
Not in the way you would want it to work, no.
Keep in mind that AA is by no means Object oriented. Hence, the parsing of the returned object needs to be done either in the dll itself (if you have access to its source code) or by AA's Before-After String operation.
Note that the latter is only viable when the returned Student object is not hashed, e.g. "Obj#12f837g", but has a ToString() format, e.g. "{student:{name:Foo, age:12}}".
In the former approach, instead of returning the Student object, you could return student.name + ";" + student.age; for example.
If neither of the 2 options listed above are viable for you, you can try creating a metabot via the Metabot Designer in the AAE Client. You can attach the dll and check if you can call its methods individually. The goal would be to find a Getter method for both 'name' and 'age'.
If all else fails, yes, you'll need to either run another dll which would serve your purpose, or create the dll yourself (this sounds like a fairly easy dll, but I could be wrong of course).
Hopefully one of the above will help you or at least guide you on finding your own solution.

How to convert a type, loaded from one project, to an interface

Prerequisites
.NET environment
A Common assembly with an interface IModule
Main project, referencing Common
Implementor project, referencing Common, but not referenced from Main
When everything is built, the Common.dll is present in both Main and Implementor.
Now the Main project tries to load the class implementing IModule at runtime. What I could achieve so far:
Dim asm = Assembly.LoadFrom(asmFile)
For Each asmType in asm.GetExportedTypes()
If asmType.IsClass AndAlso
asmType.GetInterfaces().Any(Function(i) i.Name = GetType(IModule).Name) Then
Dim handle = AppDomain.CurrentDomain.CreateInstanceFrom(asmFile, asmType.FullName)
Dim inst = CType(handle.Unwrap(), IModule) ' EXCEPTION
End If
Next
So I can load the Implementor assembly and find the type implementing IModule. But I can't create an instance of it such that I can cast it to my local IModule. Is this at all possible?
Workaround
I found a workaround - in Implementor project, click on reference to Common and clear "Copy Local" flag. Then I can even use simpler code, like IsAssignableFrom(). But is this the only way? What if I get a DLL from third party, where the IModule is compiled into it?
EDIT:
Assembly.LoadFrom loads the first found matching assembly in a directory tree (via the so called Probing Path). So if you have your Common DLLin folder A and the updated Common DLL is in folder A\B then the one in folder A is taken (if both dlls have the same name).
From MSDN:
The load-from context allows an assembly to be loaded from a path not
included in probing, and yet allows dependencies on that path to be
found and loaded because the path information is maintained by the
context.
The LoadFrom method has the following disadvantages.Consider using
Load instead.
If an assembly with the same identity is already loaded, LoadFrom returns the loaded assembly even if a different path was specified.
If an assembly is loaded with LoadFrom, and later an assembly in the load context attempts to load the same assembly by display name,
the load attempt fails.This can occur when an assembly is
de-serialized.
If an assembly is loaded with LoadFrom, and the probing path includes an assembly with the same identity but a different location,
an InvalidCastException, MissingMethodException, or other unexpected
behavior can occur.
Original Answer:
Use Activator.CreateInstance to create the object and typeof to check if it implements the Interface :
Dim a As assembly = Assembly.LoadFrom(asmFile)
Dim concreteModule As IModule = Nothing
For each type In a.GetExportedTypes().Where(Function(x) x.IsClass)
Dim o = Activator.CreateInstance(type)
If TypeOf o Is IModule
concreteModule = DirectCast(o, IModule)
Exit For
End If
Next
Remark:
You wrote: But I can't create an instance of it such that I can cast it to my local IModule.
The concrete object must implement the Interface you cast to. I donĀ“t know if I understood you correctly but casting from a Interface IModule in a 3rd party dll to a different Interface IModule* in your local dll will not work (unless your local interface implements the other).

VB.NET Automatically include DLLs in specific folder

I have a project where I have a directory called plugins/ which will contain multiple DLLs.
As an example, I will have two (2) DLLs in my plugins/ directory: Visual.dll and Momen.dll
Each of those will be a Class, Visual.dll will have the Class name Visual and Momen.dll will have the Class name Momen.
I need to make a loop that will loop through all DLL files in my plugins/ directory; once in that loop, it will obviously know the file is Visual.dll or Momen.dll. First, it will need to include the DLLs (just as if I added them as References to my Project) so that I can use them. If the loop is at Visual.dll, I will then need it to create an instance of the Visual Class, and then execute a method called Run()
I'm a PHP developer, and relatively new to VB.NET, in PHP I'd be able to do something like, which would create a new instance of my Visual Class (while passing a few arguments), then execute the Run() method:
$className = "Visual";
$instance = new $className("arg1", "arg2");
$instance->Run();
I appreciate any help.
Thank you
If the DLLs are .NET assemblies, then you can load them with Assembly.LoadFile. That will give you a reference to an Assembly object.
You can use the assembly's GetExportedTypes method to view public types in the assembly, or the GetType overload that takes a string parameter to get a type from the assembly based on its name.
From there, you should be able to use an appropriate overload of Activator.CreateInstance to create an instance of the class. From there, you should also be able to find and run its Run method through reflection.
Edit This is untested, but something like this might work (or be close to working):
Dim plugin As Assembly = Assembly.LoadFile("test.dll")
Dim pluginType As Type = plugin.GetType("Test")
Dim instance As Object = Activator.CreateInstance(pluginType)
Dim runMethod As MethodInfo = pluginType.GetMethod("Run")
Dim param1 As String = "Hello"
Dim param2 As String = "World"
runMethod.Invoke(instance, New Object() {param1, param2})
If you're going to do much with plugins other than just load and run a method, then it might be worthwhile to look for a plugin framework to use.

Load DLL with parameters

I need to delete every single function from my project (VB.Net) and place them in separate DLLs. For example, i have a function that creates a text file and appends text to it. I need a solution that will load my AppendToTextFile.DLL with params just like a function works.
At this time my function accepts two parameters like
AppendToTextFile("C:\test\textFile.txt", "text to be appended")
Does anyone know how to load a custom DLL with params like the function above?
Create your custom DLL.
Then add it as reference to your project.
Call you function and use it like this :
Dim mydll As New MyCustomeDll
mydll.AppendToTextFile("C:\test\textFile.txt", "text to be appended")
That's all.

Reading from an embedded resource stream

I've been trying to access an image resource named "IndexPointer.jpg" in an embedded RESX file called "Images.resx". GetManifestResourceNames() returns a single value - SCtor.Images.resources".
Assembly::GetExecutingAssembly()->GetManifestResourceStream("SCtor.Images.resources.IndexPointer.jpg")
only returns a nullptr. Obviously, I've got the manifest name wrong. What would be the correct one ?
Open the assembly with Reflector to find out the correct resource name.
Well, I finally figured it out. Strangely, I recall coming across (and trying out) the working solution and disregarding it. In any case, I instantiated a ResourceManager object with my assembly's resource and used its GetObject method to extract the embedded image.
ResourceManager^ resources = gcnew ResourceManager("<rootNamespace>.<resourceName>", Assembly::GetExecutingAssembly());
Bitmap^ Image1 = gcnew Bitmap(dynamic_cast<Image^>(resources->GetObject("<nameOfTheImageResourceWithoutItsExtension>")));