Here's my problem.
I have written a class in VB.NET under Visual Studio 2015 (MyLibrary).
I compile it as a DLL with 'Make assembly COM-Visible' checked, so it generates a .tlb file in addition to the DLL file.
Then I try to instanciate this class in C++ code, under Visual Studio 2013, using the COM mechanism.
For that, I make the .tlh file generated by :
#import "MyLibrary.tlb" raw_interfaces_only
Then I do :
// Initialize COM.
HRESULT hr = CoInitialize(NULL);
// Create the interface pointer.
cMyLibraryPtr l_pclMyLibrary(__uuidof(MyLibrary));
// Use it
l_pclMyLibrary->DoThings();
When I do it from the computer where both versions of Visual Studio are installed, it works well, either in debug or release mode.
But when I launch it from another computer where I "installed" my software, I get the REGDB_E_CLASSNOTREG when the constructor of my class calls "CreateInstance".
I've checked or tried those things to make it work :
Everythings is compiled in x86 (VB.NET and C++) and I'm on two 32bits targets
I tried to register my library by calling "regasm.exe MyLibrary.dll". I checked in regedit that the registration worked.
I don't know what I can do more... So any help would be welcome!
Thanks
Alex.
I've had better luck using:
regasm /tlb /codebase MyLibrary.dll
Note the /tlb and /codebase parameters...
I'd also want to make sure you run it from an elevated command line that has administrator privileges.
In addition, you need to be sure that the version of regasm.exe that you are using is
1) the same version of .NET that you build your DLL
2) In your case, that it is the 32-bit version of regasm.exe and not the 64-bit version
The other thing, is if you are going to distribute these in the same install directory, you could use Isolated COM so that registration is not even necessary.
Related
I'm developing a dll library. My solution (cmake core, Visual Studio sln generated) consists of a few static .lib projects that are used to build this dll and the dll project itself. There are also some 3rd party dependencies (boost, nana and some more). I'm using hell dependencies manager (https://rilis.io/projects/hell) to download my dependencies. I know it's not widely used, but to put it short it is just a simple tool that after reading config file downloads dependencies using git, generates projects using cmake and compiles using the requested generator.
I need my dll to support Windows XP. I develop on Windows 10 machine and I copy the dll to Windows XP SP3 machine, which is where I run the tests. However my dll fails to load on windows xp. LoadLibrary returns nullptr. The name and architecture are matching. I'm not getting any system error, just the pointer returned is nullptr. I used to have system errors but I eliminated them by switching to functions that were present in Windows XP API. I enabled Snapping and ran profiling in DependencyWalker. I got errors about
api-ms-win-core-synch-*
api-ms-win-core-fibers-*
api-ms-win-core-localization-*
failing to load (probably also through dynamic loading during dll initialization. I found out its Windows XP compatibility issue. I figured out that I need to build my module using v140_xp toolset. Cmake provides options to specify toolset and hell is supposed to propagate this setting to build other dependencies using provided toolset. To the best of my knowledge about hell, cmake and visual studio that should be the case. However my dll still fails to load and DependencyWalker + snapping still show the same failed load attempts.
I want to know whether I missed something in my approach or if the toolset setting is not propagated to all static libraries. The second one could cause one or more of dependencies to be compiled with non xp toolset, resulting in linking with non-xp cruntime (I'm linking statically with crt - MTd/MT) and failed dependency.
I need some ideas that would help me troubleshot this issue. Anyone knows how I can check which obj or lib that my dll consists of could add dependency to non-xp API? Or maybe someone has an idea what I could have missed when building my module?
Thank you for your time!
It's my first time using Visual Studio 2017. I built a simple program in C++ on my PC. I was curious to see if my program works on another PC. I tried to execute the .exe on the other computer and it gave me this kind of error:
vs(some letters and numbers).dll is missing.
I assume that the .dll in question is part of Visual Studio.
I tried on a third PC, and this time the cmd stops working and becomes unresponsive after I execute my .exe.
I also have this problem when I compile with MinGW using the g++ compile feature in the cmd. When I execute the program compiled with MinGW on another PC, it gives me the same error, but this time it says something like
gw...dll is missing
Is there a way to avoid this error without installing the Visual Studio (or MinGW at this point) on any other PC I want my program to run on?
If you're interested in the code, I can put it here, but I don't think it's the problem here because I have the same issue for every other .exe compiled on my PC.
Here's a picture of the error:
In case of Visual Studio, you need to install Visual C++ Redistributable libraries or provide the libraries that are required by your application with .exe file (I am not sure if it violates license or not though).
In case of MinGW, you need to provide required DLL as well. I guess that you need libgcc_s_dw2-1.dll and libstdc++-6.dll, but you would better check it yourself. And remember about the license.
You may use Dependency Walker to analyse dependencies of your application.
UPDATE (2017-12-12):
I've missed the time you posted the screenshot. As far as I see from it the problem is that you are trying to run debug version of your executable: ucrtbased.dll is the debug version of the ucrtbase library and is only available (from what I know) from Visual Studio distribution. If you want to run your application on the computers that do not have installed Visual Studio, then you should use the Release version of your application.
In order to understand your problem you need to understand the concept of DLL.
Dynamic-link library(DLL) - As described by Microsoft:
A DLL is a library that contains code and data that can be used by
more than one program at the same time. For example, in Windows
operating systems, the Comdlg32 DLL performs common dialog box related
functions. Therefore, each program can use the functionality that is
contained in this DLL to implement an Open dialog box. This helps
promote code reuse and efficient memory usage.
So to put it simply, DLL is basically a bunch of compiled code, which is being linked to your code at load (or even run-time). Now, of course if your system is missing the DLL, your progrem will fail to work. To make things even worse, DLL are sensitive to the compiler that was used. So each DLL might have multiple version, so you will need to right DLL.
Now to the problem itself, the error message are the best way to start. They guide you what DLL are missing, and what is their name. For instance in your case "vs*.dll" is most likely related to Visual C++ runtime redistributable.
Finally, please note you have another consideration to make in addition to make your own system work: Every one that will use your code might face the exact same problem. So if you actually intend to share your .EXE with other people, you will need to understand how to guide them, or even automate their installation process.
I have a simple application which reads a few text files does some calculations and writes a few text files. Works perfect on my development machine (Server2008R2 VC++ 2010). I can't get it to run on a Win7 machine even thought I have installed/run the vs2010 redistribute x86.
The first error I got was missing mfc100ud.dll (yes, I'm using debug, if I try the release it just crashes, as debug tells you what's wrong). I put mfc100ud.dll in the application's directory, now fgets asserts as shown below. str is not null and the file did open successfully.
What have I missed?
My goal here is to just run the MFC app on the Win7 machine without have to install vs2010.
Another consideration, the only reason I am using MFC is for the COleTimeDate functionality. I've looked for alternatives but haven' found anything workable or as simple to use.
Thanks.
Assertion Error
This error occures if the file stream pointer (provided by fopen) is NULL.
Is it possible that you don't have any error checking after you used fopen?
Basically use "static linking" to the MFC and CRT. Than there is no Need to install and copy any runtime files.
Redistributable assemblies are only available for release builds. If you really want to distribute a debug build, you have two options:
link your app statically, so you don't need any shared DLL (such as mfc100ud.dll)
distribute together with your app (in your app folder) all the dependent DLLs. you can check the dependencies with depends.exe
I've been using the CppShellExtContextMenuHandler sample project from Microsoft's All-In-One framework to add a custom menu item + icon to windows's context menu.
However, it seems that I can't register the DLL provided by this sample on other computers than mine. The DLL, compiled on a Windows 7 x86 machine from unmodified code, doesn't run on:
Another Windows 7 x86
A fresh Windows XP SP3 x86 install on VirtualBox
I get:
LoadLibrary(CppShellExtContextMenuHandler.dll) Failed to find
specified procedure
(translated) on the XP machine
The module "CppShellExtContextMenuHandler.dll"
failed to load.
Make sure the binary is stored at the specified path or debug it to check for problems with the binary or dependent .DLL files.
The specified module could not be found
on the other Windows 7 machine
I use Regsvr32 CppShellExtContextMenuHandler.dll in the commandline to register the DLL.
Did anyone encounter this problem? Did I miss something (dependencies/project config)?
I'm not sure how to debug this one.
Thank you for your help!
PS1: Code is available here: http://1code.codeplex.com/releases/view/71395, under ./Visual Studio 2010/CppShellExtContextMenuHandler in the package.
PS2: Compiled version of the sample is here: https://fgt.bo/GmQ
Finally found the answer, thanks to Choosing a Deployment Method on MSDN.
To make the DLL file compiled from the CppShellExtContextMenuHandler sample work on non-dev computers, you need to accompany it with the VC++ Runtime DLLs it depends on.
I used the wonderful tool on a client's (non-dev) machine to get the name of the DLLs my context menu handler depended on (the tool indicates which of them are missing on the arget computer!).
It turned out I had to redistribute the msvcr100.dll and msvcp100.dll files from [Program Files\Microsoft Visual Studio 10.0\VC\Redist] along with the CppShellExtContextMenuHandler.dll file to make it work.
To make the handler work on Windows XP, I also had to replace the two occurences of
hr = HRESULT_FROM_WIN32(RegDeleteTree(...
by:
hr = SHDeleteKey(...
...in the Reg.cpp file. In fact, according to C++ Windows Shell context menu handler Sample, the RegDeleteTree function isn't available on XP.
The SHDeleteKey is equivalent and can be found in Shlwapi.h, on all versions of windows I tested.
Thank you for your time reading and trying to solve this!
I am using Qt 4.6.3 with MinGW on Windows to build Qt apps and now need to add a COM interface to my application. I enabled ActiveQt but was getting post-link errors because I was missing a copy of the MIDL compiler. I downloaded a copy of the latest MS Windows SDK, which includes MIDL, but now MIDL complains it cannot find cl.exe. The only conclusion I can draw is that you can only build ActiveQt applications using the MS compiler, which I would rather avoid. Is a way to get this working with MinGW or am I out of luck?
Using the MS compiler and tools seems to be the only reliable way to get this working.
Well, you can build ActiveQt with MinGW, but using a bunch of COM stuff on top of that may not be possible, because it may or may not be present in MinGW. Some thoughts:
Using any MS SDK tools with MinGW won't work (exception is mingw.org + DXSDK which should work most of the time).
Are you sure you are linking all necessary libraries when compiling? I can't help more if you don't show the exact error messages.
The mingw-w32/w64 project tries to provide a completer "Windows SDK for GCC"; it may contain the libraries/files you are looking for. They provide a x64 and x86 compiler, and pretty good DX support. I have no experience with their COM stuff, but I believe it would be a bit more complete than mingw.org's. You can always contact the developers on the forums or mailing list, they are very helpful.
You could try the Wine implementation of midl, widl. See the Wine wiki page regarding building on Windows.
If you want to give it a quick run, get wine-prgs-0.9.14-mingw.zip and see how it works.
I agree with Rob's second post: it's a very bad thing using mingw for construction of ActiveX objects. Mingw has some bugs regarding ActiveX: https://bugzilla.mozilla.org/show_bug.cgi?id=203299 and also: https://qt.gitorious.org/qt/qt/merge_requests/2710. I kill the whole day to discover it. Use Qt for MSVS instead and all will be ok. ;)
I've solved this problem next way:
Got QtCreator, Msys2 and VS2015 Community installed.
Launching Qt Creator with batch script:
#echo off
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 8.1
setlocal
set MSYSTEM=MINGW32
set MSYS2_PATH_TYPE=inherit
start "" "C:\msys64\usr\bin\mintty" -i /msys2.ico -e /usr/bin/bash --login -c "/c/Qt/Tools/QtCreator/bin/qtcreator.exe"
exit /b 0
I am launching QtCreator out of Msys2 envioronment because it provides standart Unix tools needed to build 3rd party in my project.
So in theory this is not mandatory to have Msys2 for you.
Please note: do not use WinSDK 10.0 (or above) because it does not have midl.exe in PATH variable.
Doing this way will create PATH environment variable with Qt Creator on top priority (so you will use gcc from Qt installation), Msys2 next (so you can use standard Unix tools) and MSVC and WinSDK 8.1 at last place (so while building you will find midl compiler).
Right now I succeed building dll and passed it to midl form WinSDK, but as for now I am stil trying to register it in system.
I did actually succeed in creating and invoking in-process and out-of-process servers using QT+mingw-w64 today, so here is a write-up.
This was based on the instructions at https://doc.qt.io/qt-5/activeqt-server.html , although they were written for the Windows-native build of QT and using MSVC, so some changes were needed .
Tools installed
MSYS2 updated to latest version (as of 29 Oct 2020).
qtcreator and mingw64/mingw-w64 (64-bit target), installed via MSYS2.
Package mingw64/mingw-w64-x86_64-qt5-static installed (this causes the "Qt5 Static" kits in qtcreator to be enabled).
Visual Studio 2019 Community edition (this provides midl.exe).
https://github.com/lucasg/Dependencies - lucasg Dependencies walker. (Not essential but good for checking your static build worked).
Creating the COM DLL (without a type library yet)
These steps assume prior familiarity with QtCreator+qmake for "normal" executables.
Copy the example project from qtactiveqt/examples/activeqt/simple . I actually couldn't find this anywhere in the MSYS2 installation of QT so I cloned the QT source directly and picked out the example.
In the Kit Management in QtCreator, I selected the qt5-static 64-bit kit. This is to avoid any issues due to DLLs not being found at runtime.
This example is an out-of-process server, so to change to in-process, add to the simple.pro file the lines: TEMPLATE=lib and CONFIG += dll.
Enable static linking in GCC as I describe in this answer: https://stackoverflow.com/a/64583309/1505939
Build the project . This will give a warning that it couldn't read simple_res.o but that can be ignored. This should successfully create the output file simpleax.dll, but then there are some error messages to do with widl not found -- which we will address in the next section.
Writing the type library to the DLL
Other Windows tools (e.g. regsvr32, and any other client who wants to use the DLL) expects to be able to read the type library out of the DLL.
The DLL which was created in the previous steps does not contain a type library. I think this is because none of our toolchain tools know how to create a type library. Instead, we have to use midl.exe supplied with VS Community to generate the type library.
In QtCreator there is a post-build script that's supposed to invoke midl . However that doesn't work in the MSYS2 flavour of QtCreator. It seems it was only written for the native flavour using MSVC as the kit.
So we have to manually do the post-processing, which involves:
In the MSYS2 shell, go to the directory of simpleax.dll.
Run this command: idc simpleax.dll -idl simpleax.idl -version 1.0
Start the "x64 Native Tools Command Prompt" start menu item that came with the VS Community installation.
Navigate to the directory of simpleax.dll
Run the command: midl simpleax.idl /nologo /tlb simpleax.tlb. (Note - just adding midl to the MSYS2 path doesn't work as it can't then find a bunch of other dependencies).
Back in the MSYS2 shell, go idc simpleax.dll -tlb simpleax.tlb.
Note that you only need to do all this if the type library changes (i.e. you make a change to the class definition of your exported COM objects). If just rebuilding the project then only the last step would be needed, which you probably can add as a manual build step in the QtCreator config.
Registration and run test
Congratulations! You should now be able to open an elevated command prompt and run regsvr32 simpleax.dll and have it succeed. (If it doesn't work, run dependencies -chain simpleax.tlb and then at the end it will list any DLL dependencies).
After registration succeeded, I was able to invoke the COM object using VS Community (New C++ Console project, and #import "D:\path\to\simpleax.dll", build, and then it creates a .tlh C++ header file that contains wrappers for the DLL).
Cleaning up the type library
The type library that was created contains a whole bunch of annoying QT guff. I discovered that if you want to create a COM object that's not an ActiveX control, you can use QObject instead of QWidget as the base class. Then you don't get most of the guff that is to do with GUI elements.
Also, taking out the Q_CLASSINFO("EventsID",... line from the COM object's class definition means you don't get all the source/sink guff in the type library (for some reason it decides it has to put all the QT event sinking stuff in there).
After doing that, there is only about one screenful of guff left, including the definition of QPoint and so on, that I would consider to be a bug on the part of QT (since the stuff is not needed). I found I could just remove that from the .idl file prior to invoking midl, and hey presto we have a clean interface that can be published.
The out-of-process server
This also worked for me, identical to the above steps but without step 3 (i.e. leave it as app instead of lib). The procedure for attaching the type library via midl is the same.
Registering the type library via testobject.exe -regserver gives no message to tell you if it succeeded or failed, so another way is to use idc -regserver testobject.exe from elevated MSYS2 prompt, then it will give you a failure message.
I was able to invoke the object via VS Community just the same as for the in-process server.
Further issues still to work out
Figure out how to do this in CMake.
Automate the post-build type library procedure.
Get non-static linking working.
Automate removal of the type library guff (or report a bug)