Lotus Domino on 64 bit system: Could not create automation object, error 208 - com

I have created a C# .NET DLL with Release/AnyCPU as per http://www-01.ibm.com/support/docview.wss?uid=swg21230705 and successfully registered it for COM Interop.
When I open my 32bit Excel on a 32bit Windows 10, and use the code
Private Sub CommandButton1_Click()
Dim obj As Variant
Set obj = CreateObject("MyTest")
MsgBox obj.AppendStr("This is")
End Sub
it returns the expected values. When I open 32bit Excel on a 64 bit Windows 8.1, and use the same code, it also returns the expected values. The same goes for a similarly crafted VB6 executable deployed on both systems.
But when I try the same from Notes 32 bit using the code
Sub Click(Source As Button)
Dim obj As Variant
set obj = CreateObject("MyTest")
MsgBox obj.AppendStr("This is")
End Sub
it returns the expected values on a 32 bit Windows 10
it throws the error "Could not create automation object" on a 64 bit Windows 8.1
Furthermore, and this is the most interesting part for me, it throws "Could not create automation object" when run as a LotusScript http agent on the Domino 64 bit server on a 64 bit Windows Server system.
Do you have any ideas how I could get the DLL function call to work with both 32 as well as 64 bit Lotus Domino Server?
Or are there any other ways to call a single function in my C# DLL from Notes, which takes a single string as parameter and returns a byte array? (e.g. through a Java agent, through a Domino shell object, or both?)

I just found the solution, and it wasn't a Domino problem at all. The linked tutorial is for pre-64bit systems and says:
To make the objects in this DLL accessible via the COM interface, enter the following command:
regasm MyTest.dll
Since the introduction of AMD64, you have to read this step as follows:
To make the objects in this DLL accessible via the COM interface for both 32 bit and 64 bit applications, enter BOTH the following commands:
%Windir%\Microsoft.NET\Framework\<version>\regasm MyTest.dll
%Windir%\Microsoft.NET\Framework64\<version>\regasm MyTest.dll
I only did the first, which made it work for 32bit, but not for 64bit.

To answer the question in a technical aspect, you can call yout 32 bits DLL by copying it to Windows\SysWow64.see Can a 64 bit EXE link against 32-bit DLLs? for more details.
To answer your need we just need to transform a string to byte array.
You can do this in java and use ls2j to call it.
I also think to use the lib of native consumer to dothis.
Look also at https://www.experts-exchange.com/questions/23120423/Using-NotesStream-to-convert-a-string-to-a-byte-array.html it give you a lotuscript solution.

Related

COMInterop - System cannot find file - IDE only

I've an old VB6 program which I have haven't used for several months. The program references numerous C# assemblies (.NetFramework 4.8). Running the programs as binaries, it all works fine.
I have opened the VB6 ide to step some of my code and I am now encountering an automation error "The system cannot find the file specified." (Err 80070002) when trying to instantiate one of the COM Interop classes. This didn't used to happen.
Private Sub InitMessageStore()
Dim l_oBusFactory As IfxBusService.BusFactory <= COM Interop reference
Set l_oBusFactory = New IfxBusService.BusFactory <= ERROR here
l_oBusFactory.InitialiseMessageStore GetConnection(m_oIfxsys.Dbase.Database.Definition)
End Sub
The COM Interop decls
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ComDefaultInterface(typeof(IBusFactory))]
[Guid("200C6C26-6881-4CB5-A8E7-E0E5532D6D5F")]
public class BusFactory : IBusFactory
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("5531BD20-2C7B-452B-A7D7-2D05E39EB83E")]
public interface IBusFactory
I have rechecked the registry registrations for the above ... the salient one being
and the file is in the folder location as specified in the registry.
I'm using Win10 Version 10.0.19044 Build 19044. I'm running everything as administrator. I have DEP switched to essential Windows programs and services only.
As I said above, everything works fine when run as binaries, but, to me, it looks like the OS is stopping the VB6 ide from loading a COM Interop assembly.
Any suggestions as to how I can get stepping through (but not necessarily into) my COM Interop code working again.
In the end, I missed that there were 2 entries under the InprocServer32, one of which pointed to the correct file (1.0.0.0), but the other one (5.80.0.111 - which is actually the version no of our com binaries) didn't point to a file:///, but rather the pure .net assembly. Once I deleted the incorrect one, it all started working ok.
Still not sure where the wrong one came from!

Why does Imports System not give access to Windows namespace in vbc.exe?

I manage an application that allows the users to automate tasks by writing their own VB code. The user code is compiled using the VBCodeProvider and invoked against the running instance of the application. We've been doing this for a few years now starting with .NET 2.
Traditionally, we have imported the System namespace in the compiler settings so users wouldn't have to write System. all the time. When we went to .NET 4, however, we found that statements like Windows.Forms.Form wouldn't compile anymore. The error was "Type 'Windows.Forms.Form' is not defined." This is odd because other namespaces work. IO.Stream and Reflection.Assembly do not have an error without the System at the beginning.
I've created a simple example. I've put the below code into a file. Then I compiled this file with vbc.exe from both the .NET2 and .NET4 directories. The 2 version works fine. The 4 version will not compile unless you comment out the variable f2.
Imports System
Public Class MyClassName
Public Shared Sub Main
'this works in v2 and v4
Dim f As New System.Windows.Forms.Form
f.ShowDialog
'this does not work in v4
Dim f2 As New Windows.Forms.Form
f2.ShowDialog
End Sub
End Class
Does anyone know how to get this to compile in vbc.exe version 4? And before you say "Just tell the users to type System.Windows.Forms" I will agree that it would be great if they would do that, but users do what users do and I have to work it out.
UPDATE:
I've found that the Windows.Foundation.Diagnostics namespace is causing a collision with the abbreviated use of Window.Forms. Is there any way to hide this namespace from my compilation? Visual Studio 2010 does not have the same conflict, so it must be getting around it somehow.

Print NASM program on Windows 7 SP1 64-bit excluding DOSBOX, excluding C, and "possibly" Excluding Windows API calls

I've been filling myself up with notes trying to successfully create my first program on Windows 7 with NASM, but with a few self imposed stipulations (until I'm ready to move forward). In creating this first program, however, I have a ton of questions.
.
The stipulations for now are that:
I'm running Window 7 SP1 - 64-bit
I do not wish to use DOSBox so Interrupts 0x21-24 are likely not applicable
I do not wish to rely on C so this is all NASM
I would really like to avoid downloading Visual Studio or associated WDK tools if I can (this depends on whether or not I NEED to interact with the Windows API and relates to Question 2 below)
I've downloaded and installed MinGW
I'm writing my code in Notepad++ and saving as *.asm
I am linking using "ld" for now, but from what I've read, most seem to recommend "GoLink" (and Alink hasn't been updated in years?). I'll probably migrate to GoLink after I've assured myself that "ld" may be too limiting
I want to know if printing is possible without the use of the Windows API or C because of the code below?
.
The only code example that has worked for me in some capacity can be found here.
nasm is not executing file in Windows 8
.
;FILE: main.asm
[section] .text
global _main
_main:
mov eax, 6
ret ; returns eax (exits)
Linked:
c:\Users\James\Desktop>nasm -fwin32 main.asm
c:\Users\James\Desktop>ld -e _main main.obj -o main.exe
c:\Users\James\Desktop>main.exe
c:\Users\James\Desktop>echo %errorlevel%
6
.
My questions (a ton):
The fact that in the code above "ret" by itself gives output, although it just returns whatever is in EAX, is there a way to use it (or another directive outside of the Windows API) to return the contents of a variable (hopefully a string variable)? I tried to use ret with DOS calls, but as noted above, that definitely doesn't work because I'm on a 64-bit system.
In case I absolutely must use the Windows API, is the only way to interact with it by using the WDK tools? Is there some other way because that last time I downloaded Visual Studio and associated WDK tools it took up a ton of memory and massively slowed down my computer. Is there another way to make programs give output or print to the screen either by using internal commands or some other method to use API calls? One thread I admittedly skimmed (amidst 40 more tabs I have open) mentions "Russinovich's Windows Internals" but not a direct answer. At current every time I use code with the extern commands "ld" tells me that the references to commands like WinMain/WinMain#16 are undefined. In the same vein is there a table I can consult containing accurate calls to the API (i.e. _ExitProcess#4 vs. ExitProcess). I found this link to what think may be the NT API but I'm not sure it applies given my stipulations, but in reality, I'm just kind of confused:
http://j00ru.vexillium.org/ntapi/
In bits of code I've encountered I've seen directives for [Bit 16], [Bit 32], and [Bit 64]. [Bit 16] is likely ignorable, but I'm confused by the [Bit 32] and [Bit 64] for the following reasons which may not even be related: Via the code above I'm using the command, "nasm -fwin32 main.asm", then I'm linking it successfully and going on to receive output. For some reason - though I have not read the full "ld" documentation yet - when I use the command "nasm -fwin64 main.asm" and link it in the same way I receive an error saying "main.obj: File not recognized: File format not recognized". I don't understand why differentiating between 32 and 64 while I'm on a native 64-bit machine causes an error although this probably is just unique to ld.
.
In the meantime I'll be reading this question and will post an update it if helps: Executable isn't compatible with 64 bits processor
I can't answer some parts in great detail, so I expect somebody either putting up better answer, or feel free to edit this one.
you are linking against default clib, so your _main is called after Clib is initialized, the ret with value in eax is like return 6; in C++. Then Clib correctly destructs everything and calls windows exit process with exit code 6. You can return only int from _main, and I'm not even sure if full int is propagated to exit process call, or only 8 bit value is used. So you can return single char in ASCII encoding, if you treat that number as char.
You must call Windows API, if you want to display something in console/window, or write something into file, ie. do any output (and of course also for input). There's no peripheral available to win32/64 executable directly, like in DOS CGA/EGA/VGA text modes accessible trough int 10h or video ram at B800:0000. Any try to access some I/O peripheral directly should result into access violation. Only Win API should be legal for user-level application code.
How much of WDK you need I have no idea, haven't developed anything for windows for years. I think it's even possible to create executable without WDK, which would provide correct externs and dependencies on kernel32.dll and similar, but the amount of effort is way beyond simply using proper parts of WDK or clib from MinGW.
I think your linker is set to default to 32b executable, you have to figure out what kind of object format is produced by nasm for -fwin64 and how link that one with ld.
Why the difference. The 64b OS can run 32b binaries. But you can't mix 32/64 in single executable so easily (if at all). So you are either producing 32b or 64b binary, and you have to adjust everything to it (asm instructions used, directives and options, and WinAPI calls).

Build Error in VB.NET program when MS Office XP is upgraded to MS Office 2007

I have a VB.NET 2010 program that works perfectly with MS Office XP. Because of security concerns attributed to Office XP, I recently upgraded to MS Office 2007. I made no changes to the VB program.
A single Build Error, Type Excel.Global is not defined. is preventing the program from running. The ErrorList points to the UpgradeSupport module as the location of the error.
The entire UpgradeSupport module is as follows:
Module UpgradeSupport
Friend DAODBEngine_definst As New DAO.DBEngine
Friend ExcelGlobal_definst As New Excel.[Global]
End Module
The instance of Excel.[Global] above is the only visible instance of it in the entire program, and there are no instances of Excel.Global at all, anywhere. The variable name, Excel.Global (or Excel.[Global]) suggests a structure. Moreover, I believe Global (or [Global]) is a property, not a type, and I believe Excel.Global and Excel.[Global] are not equivalent expressions. I can successfully define structure Excel.[Global] as follows:
Public Structure Excel
Shared Property [Global] As Object
End Structure
Note: The above will not define successfully without the square brackets around Global, which supports my assertion that the two expressions are not equivalent. I question whether any instance of Type Excel.Global exists in the program. Nevertheless, the Build Error continues to prevent the program from running. How can I eliminate the Build Error?

VB.NET and BITS - Background Intelligent Transfer Service

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)