VB.NET and BITS - Background Intelligent Transfer Service - vb.net

Has any one used BITs in VB.NET? If so, do you have code samples and advice?
I was looking at SharpBits but I have a VB project that I wanted to use BITS for. Is it possible to use it with my VB.NET program? (.NET 2.0) I was tempted to try to convert each class to VB.NET in the SharpBits.Base folder but figured I'd ask in case someone has headed down this route before.
Edit: Ok folks in case you run across this question. What you can do is in the Sharpbits.Base folder (that you download from codeplex) there is a DLL you can reference in the Bin directory. You can add that into your references to access it. Marking Konrad as answer since he was kind enough to post.
Further edit:
I managed to get sharpbits working with some quick code which I pasted below for anyone who might stumble upon this question. Like I mentioned above add the DLL to your project.
Dim b As New SharpBits.Base.BitsManager
Dim mynewjob As SharpBits.Base.BitsJob = _
b.CreateJob("jobname", SharpBits.Base.JobType.Download)
mynewjob.AddFile("\\server\share\bigfile.zip", "c:\bigfile.zip")
mynewjob.Resume()
You'll need to write some logic to check for the status of the job. Once it hits "Transferred" status you can then mark it as complete. This will write the file from a .bin to the file name you listed. Something that helped me was installing the Windows Support Tools (you can get it from a Windows 2003 Cd/DVD in the sup tools folder)and using Bitsadmin.exe to view the status of the job while debugging. Hope this helps the next rookie. =)

Any reason why you can't simply use SharpBits in VB? The advantage of .NET is precisely that libraries written in the different .NET languages can interoperate seamlessly so you can simply use SharpBits in VB, no matter what .NET-compliant language it was written in.

You could take a look here:
Using Windows XP Background Intelligent Transfer Service (BITS) with Visual Studio .NET
I have started from here to write my own library to manage BITS to transfer big video file across private LAN. Example are for NET 1.1 but should not be difficult port it to NET 2.0.

Here's a new alternative. The BITS team at Microsoft now has a page on Calling into BITS from .NET and C# using reference DLLs plus a complete sample call BITS Manager on GitHub.
I've just tried using them with Visual Basic; my code ended up looking like this:
Imports BITS = BITSReference1_5
Module Module1
Sub Main()
Dim mgr = New BITS.BackgroundCopyManager1_5
Dim jobGuid As BITS.GUID
Dim job As BITS.IBackgroundCopyJob
mgr.CreateJob("My simple job", BITS.BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD, jobGuid, job)
job.AddFile("http://www.microsoft.com", "c:\temp\2019\BITS-VB\Downloadfile.html")
job.Resume()
End Sub
End Module
(Note that I also added a reference to a DLL that I downloaded from the BITS Manager source from the Reference DLL directory)

Related

Can Roslyn be used for VB.NET scripting?

I'm creating a script editor for my application, and I'd like to have it be able to run both C# and VB.NET scripts using Roslyn. I got this working with C# by using the CSharpScript class in the Microsoft.CodeAnalysis.CSharp.Scripting assembly/namespace, however there is no equivalent VisualBasicScript class that I can find, nor a Microsoft.CodeAnalysis.VisualBasic.Scripting assembly. I've scoured the web and can find nothing useful about running VB.NET scripts, and all the samples on the Roslyn github site are C#-specific. Am I missing something, or does support for running VB.NET scripts simply not exist the way it does for C# scripts?
Visual Basic Scripting is not currently available, presumably because it's not finished.
But its source is is the Roslyn repo, so you could try building it yourself.
When I do that, code like the following works for me:
Dim result = VisualBasicScript.RunAsync("Dim result = 1+1").Result
For Each variable In result.Variables
Console.WriteLine($"{variable.Name}: {variable.Value}")
Next
But this code does not work for me (it fails when compiling the script):
Console.WriteLine(VisualBasicScript.EvaluateAsync("1+1").Result)
I'm not sure whether this is because it's not finished, or whether it's intentional difference from C# scripting.

Runtime error 429 in VBA, but class is registered

I'm trying to recreate a program that uses javascript to open a connection to a PLC and then display all sorts of information on a web page. I'd rather have it in a form in MS Access for various reasons, and have spent forever trying to find the right dll to use (Jet32X.dll, if anyone is curious). I finally tracked the CLSID called out in the javascript back to a registered class for the PLC, and I'm trying to create that object in VB code. It won't get any further than the Dim As New line, however, throwing runtime error 429: "Active X Component Cannot Create Object." Really wish I had some more information about why.
I know the class is registered, since that's how I found it in the first place. I know the DLL file isn't corrupted, since the program runs fine from the JS version. I have a sneaky suspicion that there's some sort of incompatibility going on here, since the PLC and supporting software is pretty old, and I'm working in Microsoft Access 2013 (and its associated VBA). I can't really think of a good way to verify this, however. Does anyone have any other ideas? Could anything else be causing this problem?
Figured it out; in case anyone else runs into this sort of issue:
32bit COM dlls will not run in 64bit applications. If you don't want to go back and reinstall 32bit versions of whichever application you're using, one of the easiest workarounds is using dllhost.exe as a surrogate.
You can read a little about it here, but I found this tutorial easier to follow.
I send a new reply just to recap the information and avoid anyone that stumbles in the same problem again after me wasting precious time. All the steps involved assume that you already correctly registered the dll you are trying to use.
How to make a 32bit COM Dll work in a 64bit application
The "easy" solutions involve using the Dll Surrogate method, which runs dllhost.exe and as an intermediary process in 64bit to expose the underlying 32bit dll. When done correctly this works seamlessly without any special measure needing to be taken in neither in the 32bit dll nor in the 64bit application.
There are two main approaches to this:
Using Oleview.exe (i.e. using a GUI)
Oleview can be obtained downloading the Window 10 SDK.
In order to use Oleview it you have to:
Download the Window 10 SDK at the following link:
https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/
Go to C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x86 to find the 32bit version of oleview.exe
ONLY THE FIRST TIME: run it as administrator to avoid see the message related to the impossibility to load iviewer.dll
In the left pane, Object Classes -> All Objects and find your dll name.
WARNING: you may find many entries for your dll. In particular each class has got its own entry such as YourProjectName.YourClassName
In the right pane, go to Implementation -> Inproc Server, and tick Use Surrogate Process. Leave the Path to Custom Surrogate empty to use the system default surrogate, that is dllhost.exe.
You can check the procedure went correctly by returning to the Registry tab, always in the right pane of the Oleviewer and make sure that now under CLSID = {yourAppIdHere} [DllSurrogate] = is listed among the entries.
Edit manually the Windows Registry
The Oleview method is recommended, but the manual method may be ok if you need to do this only once. The tutorial that NickGlowsinDark mentions was moved to https://techtalk.gfi.com/32bit-object-64bit-environment/ .
In order to avoid problems in the future with the page going offline I copy and paste here the most important steps involved. All credit goes to Emmanuel Carabott that is the original author of the tutorial, I added the first two steps in order to facilitate you in the process.
Open the Registry Editor (Windows+R -> regedit), and follow the following steps:
You first need to find your dll GUIDs. You will probably have many GUIDs, one for each of the classes that your dll exports. I find it's easier to find the GUIDs if you go to HKEY_CLASSES_ROOT\YourProjectName.YouClassName. It is the (Default) String Value you find under the Clsid key.
I recommend you find all the GUIDs first and make a note of them in order to have an easier time with the steps after this one.
Then, as Emmanuel Carabott kindly explains in his article, you have to do the following for each of the GUIDs you found:
Locate your COM object GUID under the HKey_Classes_Root\Wow6432Node\CLSID\[GUID]
Once located add a new REG_SZ (string) Value. Name should be AppID and data should be the same COM object GUID you have just searched for.
Add a new key under HKey_Classes_Root\Wow6432Node\AppID\
The new key should be called the same as the com object GUID
Under the new key you just added, add a new REG_SZ (string) Value, and call it DllSurrogate. Leave the value empty.
Create a new Key under HKey_Local_Machine\Software\Classes\AppID\
Again the new key should be called the same as the COM object’s GUID. No values are necessary to be added under this key.
That’s it, your COM Object should now be accessible from a 64bit environment and can be used like a regular COM Object.

Running Data From External Classes

Over the past few months I have been struggling to find a way to execute external un-compiled classes from my program.
EXAMPLE:
I have a simple run button on a windows forum. When that run button is pressed I wan't to run the Main sub in run.vb. (Run.vb is not part of the program and is located in a directory)
Is their a way to do this without using .dll's?
You want to run VB.Net code as I see. There are a bunch of classes in System.CodeDom.Compiler namespace to deal with .Net source code.
See http://www.codeproject.com/Articles/5472/Compiling-NET-code-on-the-fly
There is a good example with explanation here.
If you want to run VB6 code, the only way is compiling it to dll and then dynamically load and run. Or you can use VBscript if it will suit you.
In fact, CodeDom compiles your code to dll assembly too, but keeps it in memory, so you don't need to clean up any mess after you app is dead

Loading (and executing) a lisp-file in autocad using .NET

I'm currently in the process of rewriting some old AutoCAD plugins from VBA to VB.NET. As it turns out, a (rather large) part of said plugin is implemented in LISP, and I've been told to leave that be. So the problem became running LISP-code in AutoCAD from .NET. Now, there are a few resources online who explain the process necessary to do so (like this one), but all of them takes for granted that the lisp-files/functions are already loaded. The VBA-function I'm currently scratching my head trying to figure out how to convert does a "(LOAD ""<file>"")", and the script is built in such a way that it auto-executes on load (it's a simple script, doesn't register functions, just runs from start to end and does it's thing).
So my question is. How can I load (and thus execute) a lisp-file in autocad from a .NET plugin?
Ok, there are two ways to sendcommand via .NET.
The first thing you need to understand is that ThisDocument doesn't exist in .NET.
ThisDocument is the document where the VBA code is written, but since your addin is document undependant, it stands alone and you must take the documents from the Application object.
You access the application with:
Autodesk.AutoCAD.ApplicationServices.Application
If you want to transform it to the same Application object as in VBA, with same methods and functions
using Autodesk.Autocad.Interop;
using Autodesk.Autocad.Interop.Common;
AcadApplication App = (AcadApplication)Autodesk.AutoCAD.ApplicationServices.Application.AcadApplication;
The first application has MdiActiveDocument, from where you can call the Editor and send written commands, or call the SendStringToExecute as said in other answer.
The AcadApplication has ActiveDocument (an AcadDocument object that behaves exactly as in VBA).
This document will have the same SendCommand your VBA has, use it the same way it's done in VBA.
If you can explain better the autoexecute part, I can help with that too.

How can I easily call an IronPython function from VB.net?

I am struggling with this program which uses emgucv(an opencv wrapper for .net) for about 2 weeks. The problem is unfortunately not programming, but setting up emgucv in such a way that it works. I didn't manage to do so for vb.net so I tried doing it for ironpython(because I know python too). Emgucv seems to work perfectly when using ironpython, so I created a function that takes an image as an argument and analyses it in the way I want, returning another image with the results in it. The problem is I want to call this function, giving it the image argument(it could be a string containing the path) from within VB.net and become another string containing the result image as return. I later plan to package that project in a setup so I can redistribute it.
So I am asking you guys: Do you know an easy way to call an IronPython function in VB.net in such a way so I can also package the whole project and redistribute it to people?
Thank you so much for reading this and it would be great if you could also help me with my problem! :)
While IronPython is not my expertise I am well versed in EMGU and its applications. If you insist in using IronPython the following website clearly shows how to pass a string to an IronPython Class.
The following code is taken from the link and is not my own:
Option Explicit On
Option Strict On
Imports Microsoft.Scripting.Hosting
Imports IronPython.Hosting
Imports IronPython.Runtime.Types
Module Module1
Sub Main()
Dim helloWorld As New HelloWorldVB()
Console.WriteLine(helloWorld.HelloWorld("Maurice"))
Dim runtime As ScriptRuntime = PythonEngine.CurrentEngine.Runtime
Dim scope As ScriptScope = runtime.ExecuteFile("HelloWorld.py")
Dim pythonType As PythonType = scope.GetVariable(Of PythonType)("HelloWorldIronPython")
helloWorld = CType(runtime.Operations.Call(pythonType), HelloWorldVB)
Console.WriteLine(helloWorld.HelloWorld("Maurice"))
Console.ReadLine()
End Sub
End Module
I would follow the tutorial from the link but the important code is bellow as this imports the require runtime information for IronPython:
**Imports Microsoft.Scripting.Hosting
Imports IronPython.Hosting
Imports IronPython.Runtime.Types**
&
**Dim runtime As ScriptRuntime = PythonEngine.CurrentEngine.Runtime
Dim scope As ScriptScope = runtime.ExecuteFile("HelloWorld.py")
Dim pythonType As PythonType = scope.GetVariable(Of PythonType)("HelloWorldIronPython")
helloWorld = CType(runtime.Operations.Call(pythonType), HelloWorldVB)
Console.WriteLine(helloWorld.HelloWorld("Maurice"))**
Obviously Console.WriteLine(helloWorld.HelloWorld("Maurice")) would be corrected to:
Dim result_location As String = helloWorld.HelloWorld("Maurice")
Where "Maurice" would be the string containing your image location.
Now I have to ask about the problems you were having setting up EMGU in visual studio I know it can be frustrating to do especially to people who are new to it. If you would like I would be happy to help you set it up properly. The reason I ask is since you are providing this to and end user your code could be more efficient without calling IronPython. Especially since each process will require reading and writing from the hard drive.
To start: I will assume that you have included References to Emgu.CV, Emgu.CV.UI, and EMGU.Util in your project. But it is essential that you add "opencv_core220.dll", "opencv_imgproc220.dll" files directly to your project and ensure in the properties window that the 'Copy to Output' option is set to "Copy always". If it isn't you will get errors of not a having the image in the right format etc. You only really need these two .dll to read images in and access the data etc you may need others for .avi movies for example. Note that these two .dll must now be distributed with your project for it to work.
To note this may change depending if your using a 64 bit machine or a 32 bit machine but the 64 bit EMGU version will not run on X86 machines. You must also ensure that your target platform is correct in Visual Studio.
I hope this helps you,
Cheers
Chris