Registering DLLs using .reg file in WiX - com

Background to Question
I am currently in the process of trying to put together a means of distributing a new project I am working on which requires that a COM exposed .NET DLL be registered on the user's system and as I am new to WiX and making the move to it for this I am trying to keep things as simple as possible.
The Problem
The big issue with my DLL registration is that regasm sets the default value of the InProcServer32 key to "mscoree.dll", but my DLL can only seem to be instantiated when the full path to it is used, e.g. "C:\Windows\SysWow64\mscoree.dll"
Currently I have a custom action in my setup project (which I want to abandon to use WiX) which will call the SearchPath API to find the full path to mscoree.dll and overwrite the default value with the full path, so that the DLL can be instantiated without any issues.
Proposed Solution / Question
As I am new to WiX I have had the idea of preparing a .reg file that will contain all the necessary information to go into the CLSID tree and then having WiX execute that some how.
My question is:
Are there any inherent flaws by registering a DLL this way?
As the main reason I am trying to find work arounds here is the mscoree.dll issue, is there any native means of doing this in WiX?

Take a look at the WiX program called "Heat". This can "harvest" your DLL including registry information related to the RegAsm / COMVisible parts. You can then snip this code and work it into your wxs file.
You can also use Regasm /regfile and then manually transform that information into RegistryValue elements.
With regard to your path problem, use the SystemFolder property.
[SystemFolder]mscoree.dll
If you mark your install as 32bit (x86) this will automatically resolve to the SysWow64 folder when run on a 64bit OS and the System32 folder when run on a 32bit OS.

Related

Should my Wix installer use guids that are in my DLL?

Rolling out product for multiple languages and platforms? Not me. I just want to create a one-method DLL that returns "Hello World" and install it on my own computer, then communicate with it from Classic ASP or MS Access.
The code in the DLL is no problem. Discovering all relevant property sheets and filling them out correctly are. It's almost comical, after attempting an install, to see which property sheet values are used as file paths, which are in the registry, which are in the install/uninstall page, and so on. Who would expect the name of the INSTALL PROJECT to be used as the ACTUAL PRODUCT'S file path?
But today I limit my question to this: Should any GUID in my WiX project also be found in my DLL? My interface and class both have GUIDs. Do those need to be in the installer code, so the installer can add those to the registry? (Or are those GUIDs needed in the registry? If not there, then how are they used?)
Just trying to create a simple test to see WHAT WORKS!
If you have COM classes in your Dll that need registering then the general answer is to look at heat.exe, the WiX harvesting tool. For example the answer here:
How to run heat.exe and register a dll in wix
https://www.firegiant.com/wix/tutorial/com-expression-syntax-miscellanea/components-of-a-different-color/

Dll not appearing in references for VBA after installing using install shield

I created an install shield project for an Excel add-in.
I selected .dll file and the .tlb file to be moved to the GAC (in destination folder) and program files folder
Those files are present in the program files folder
But when I go to Excel, click on tools-> reference, they are not appearing in that list!
I had to manually browse to the location of that .tlb file and select it
What change should i make so that it automatically comes in the references list
This article gives you description of two methods to do the registration with Installshield: Installshield Register.Net DLLs.
I definitely recommend Approach 2 - Run a .bat file to register the files. This approach runs the RegAsm for the install and uninstall processes using a batch file. This will give you control over the registration process, where you know exactly what is done, and you can handle all bitness scenarios 32/64/Wow64. In Approach 1 you don't, as stated in the article:
For some reason, perhaps that I am installing a 32bit component on a 64bit machine, this didn’t work as expected. [...] some DLL’s perform post registration actions the run when you run RegAsm.exe VirtualCam.dll /nologo /codebase but don’t get captured when you run RegAsm.exe VirtualCam.dll /nologo /codebase /regfile
If possible I would recommend switching to a different installation package creator, that supports run operations and gives better control over the process than using a batch.
*As it's not a native COM dll but a dotNet dll exposed to COM, there's no need for regsvr32 registration.

Registering DLLs and .TLBs

I am working for a company that registers a lot of COM DLLs in the System32 folder/SYSWOW64 folder. I recall a question some time ago where Hans Passent said that this is wrong as the folders specified are for Windows DLLs. I cannot find the post so I want to check that this is correct?
Also if I want to register a COM DLL or a TypeLibrary in a foreign folder then can I just use the following command (for COM):
regsvr32 app.dll
Finally I was reading about the CODEBASE flag of Regasm: http://www.vbforums.com/showthread.php?597928-RESOLVED-How-to-delete-a-VB6-Reference. Do you have to use this flag if you want to register a TypeLibrary (.TLB)? What happens if you .NET assembly uses a third party library that is not signed?
If you are talking about installing COM DLLs in the System folder, then you are correct. All applications, and their support libraries, should be installed under the Program Files folders, or the Common Program Files folders.
You are also correct that REGSVR32.EXE can be used to manually register DLLs and OCX. "Foreign folder" is not a Windows concept - you can register a component anywhere in the file system, including the Windows and Windows System folders. By the way, if you use an installer, then you shouldn't have to use REGSVR32.EXE.
However, TLB files cannot be registered with REGSVR32.EXE, because that application basically loads the DLL/OCX, and calls an exported function on the library, so effectively the library registers itself. Instead, you need another tool, e.g. REGTLIB.
You don't use /CODEBASE to register a raw type library, because REGASM is used for registering .NET DLLs as COM components, not TLB files.

How to force creation of manifest file in release folder?

This is driving me crazy. I have developed a .NET COM DLL that is used by a VB6 DLL wrapper in order to update and replace some legacy functions in an application.
I am now trying to remove the requirement to use regasm on client machines so have worked out how to do that on a test DLL which all works fine.
I branched the DLL just in case and added an app.manifest file. Everything else worked out fine and I got it all working. The manifest is embedded and Visual Studio 2012 generates a mydll.dll.manifest file in the release folder.
Then I went back to the original trunk and added an app.manifest file (no point in merging as there were no code changes). I copied the contents of the branch into the app.manifest file and built the release version. The manifest is embedded in the DLL but no mydll.dll.manifest file is generated.
I know that it's not strictly necessary to have the mydll.dll.manifest file but I'd like things to be consistent (and for some reason the test process doesn't produce the same results with the trunk version) so how can I force it to be created?
This is a VB.NET DLL project so it doesn't have (or I can't find) the 'Generate Manifest' property drop down mentioned in the first answer here. How can I set this? Or is there a way to set it by editing the project file directly?
References:
Original walkthrough article and some corrections.
Overview by Junfeng Zhang in two articles plus a useful tool
You are making a fairly common mistake. A reg-free COM manifest helps an application find a COM server without looking in the registry to locate the DLL. Embedding the manifest in the DLL is like trying to solve the chicken and egg problem, Windows cannot possibly find that manifest if it cannot locate the DLL first.
The manifest needs to be part of the client app. Which is tricky since it is VB6, it doesn't support embedding manifests in its executables.
You could tinker with the mt.exe tool, an SDK utility that supports embedding manifests in an executable. You'd have to run it by hand after building the VB6 binaries. That's unfun and very likely to cause trouble when you forget. It is in general not a joyful tool to use, documentation is meager, incomplete and unhelpful, a chronic problem with manifests.
The fall back is a separate app.exe.manifest file, what Windows will look for next when it cannot find a manifest embedded in the executable. Where "app.exe" must be renamed to the name of the VB6 program. The EXE, not the DLL. This now also gives you a chance to avoid having to register the VB6 DLL, presumably what you really want if you truly want to make your program run reg-free. The disadvantage is that it will not work when you debug your VB6 program, wrong EXE. You'd also need a vb6.exe.manifest, located in the VB6 install directory.
Needless to say perhaps, very hard to get ahead with VB6 here. It just wasn't made to help you do this, they didn't have a time machine in 1998.
I have to admit that I don't know VB at all, but in the case of C++ and C# Visual Studio projects I previously had to resort to calling mt.exe in a post-build step in order to get the DLL manifest I wanted. Maybe that workaround would work in your case as well?

VB.net app without installation

Is it possible to create a VB.Net application which users can just run without installing it first.
If not, is it possible in another .Net language.
If not, how IS it possible :)
PS: The application only has to run under Windows (>= XP).
If they have the .NET Framework installed (the version of it that you developed it), they only need the .exe. You can find the .exe file in the bin directory of your projects folder in your Visual Studio workspace.
If they do not have the framework installed, you'll need to produce an installation for them. It's extremely easy with Visual Studio by just creating a setup project in the same solution as your code.
As long as the user has the .net runtime installed, and your exe has any needed resources in the same folder (dll's, images, ect) theres no problem with that.
If you mean without installing the .net framework though, that won't be possible.
just build the program, and go into the (assuming the project name is app1) app1/app1/bin/debug/ dir. there should be a file there called app1.exe. this file is the compiled .exe from you project. any other computer will be able to run this without doing any installation (provided they have the .NET framework installed (it comes standard on any computer with an os > WinXP))
EDIT: If you were building with debug configuration, it would be app1/app1/bin/debug/, but if you were building with release configuration (which would probably be a better idea if you are distributing) the path would be app1/app1/bin/release/
If you mean running it without the .NET Framework, it used to be possible, but apparently the company's website is no longer in English so I have no idea what's happened to it.
EDIT: If you were building with debug configuration, it would be
app1/app1/bin/debug/, but if you were building with release
configuration (which would probably be a better idea if you are
distributing) the path would be app1/app1/bin/release/
I am developer and have no administration rights to live(production) network.
I had to find away to deploy an app without installation... and my app is self updating this cause other problems too....
The production network Computer check/monitors the file versions etc, so updating in the program files can not be done, where a MSI has been used for deployment.
Using this above I am able to copy and Run the App from the User Profile (where the user has full rights).
lets understand how program runs-
an .exe needs some function which are not inside the .exe, such as , for example substring() function. these predefined function resides in some .dll libraries.
when .exe is executed by user, .exe first finds the .dll and then the function inside that particular .dll.
.exe first looks within the current folder for that .dll
if not found then it searches that in PATHs. (PATH is Environment variable which value is a list of folders such as System32 etc.)
an .exe usually needs only 3 things - .exe itself, .dll which predefined function it is using, and some ActiveX controls(.ocx). apart from these 3, .exe only uses resources (such as icons etc).
lets focus on these 3(.exe, .dll, .ocx)
first you need to check what .dlls your .exe is using. you can easiely do this by using a dependency walker.
then make sure all these .dlls (that dependency walker is showing,or in other words- all these dlls whose functions your .exe needs) are either in current folder(in which your .exe resides) or in the PATHs.
if this step is done then your .exe has high chances to run whithout "installing".
the only problem is that some .dll and all of .ocx, needs to be registered first(means they have to have some kind of registry entry). they are not ready to use just by copying and pasting in current folder or PATHs.
but you can register these .dlls and .ocx's by using regsvr32 (with command line).
after that your .exe should not face any problem to run successfully.
hope you got the main concept.