We build our setups with Wix. We have a mix of native and .NET components, and use COM for interop.
Until now, I have used heat.exe to generate wix fragments for installing .NET assemblies and registering them as COM servers. The wix fragment created by heat takes care of writing the COM related registry entries.
However, somebody just told me that you can also use the ComPlusExtension to do COM registration. The documentation I can find regarding this "ComPlus" stuff is quite cryptic.
Is this ComPlusExtension a valid alternative to the heat.exe approach for registering .NET assemblies as COM components? Are there any differences or gotchas I should be aware of?
I guess you could register as COM+ it isn't really the same thing and means the components would then be running out of process with respect to your calling process (they runs as dllhost.exe IIRC). If you want to see how to use the COM+ extensions checkout the WiX Tutorial. Personally I would stick to regular COM or if you can Registration Free COM.
COM+ ( aka Component Services ) is cryptic. That's why Microsoft invented .NET Remoting, WebServices and WCF. :-)
I havn't used the WiX Complus extension but I would imagine it's not a proper substitute for actually registering the COM server. COM Plus just makes it available for invocation on other machines as a package / application. (See DCOMCNFG.EXE ). I know I did this stuff about 5 years ago and I would lay the DLL down, register it using MSI tables and then call out to a custom action that would set the rest up.
Related
What's the story going to be (if any) around interop with unmanaged code for ASP.net vNext / Core CLR?
The key bits (DllImport and friends) appear to be present to allow for unmanaged code interop, but how would things such as packaging and deployment work in this context? The basic build artifact in vNext / CoreFX no longer appears to be an assembly, but a NuGet package. So in that case, how would we make the new project.json system work so that unmanaged dlls that we're P/Invoking into are also included in the resulting NuGet package?
Or am I talking about scenarios that have not been considered yet (or more disappointingly, not going to happen)?
The story is yet to be fully fleshed out, but there are already examples of how to do this. Ultimately we (the Microsoft teams working on this) are working on some scenarios to enable NuGet packages to better support native content in packages.
To see one example of this, the Kestrel web server has some of its own managed code, plus it includes libuv in its NuGet package for an efficient async IO implementation that is cross-platform.
Because there isn't yet a built-in general solution in NuGet, the build scripts for Kestrel use some custom actions to include the native content in the NuGet package. Then to load libuv there's some code that dynamically figures out which native libuv to load based on the environment in which it is running.
So, yeah, it's a bit messy, but it does work, and this is definitely high on the team's priority list to improve.
I have a couple of COM components which i register during installation. These COM components are part of a Merge Module which I include in my WIX project. I used used the below code for registering
<InstallExecuteSequence>
<RegisterClassInfo/>
<RegisterProgIdInfo/>
<RegisterTypeLibraries/>
<WriteRegistryValues/>
</InstallExecuteSequence>
The components were registered successfully. However, during uninstallation, these COM components were not un-registered. How do I make sure that these components are un-registred when the SharedDLL Count is 1 before un-installation?
Ugh, I just went through a whole bunch of hoops in regards to COM.
Really, you shouldn't be registering COM components on the system anymore. It causes way more problems than it solves. When you register COM components, you register them globally, potentially hi-jacking the component registration for that COM library from other applications. Hopefully, that won't happen, but you can't know that for sure.
Since Windows XP onwards, there has been something called registry-free COM registration. In order for this to work, you need to provide manifest files for each of the COM libraries in use by your application. You will also need to provide a manifest file for your application that states the app's dependencies on those COM libraries.
The beauty of this, is that you can deploy the COM libraries in your application's installation folder and no system registration is needed.
The following URLs can help you create the manifest files you'll need:
Registration-Free Activation of COM Components: A Walkthrough
Simplify App Deployment with ClickOnce and Registration-Free COM
Manifest Files Reference
MSI Writing Guidelines
Let me know if you need any further information. I was able to successfully deploy my application with old VB6 COM components without registering them globally in the Windows registry and deploying the COM libraries in my application's installation folder (as opposed to %windir%\system32 or %windir%\SysWow64 (on 64-bit windows).
I have one problem in vb6. I created a .tlb file in VB.net 2005 by adding Com class to project. I built the project, I got .tlb file and .dll files while building project, i selected "Register for Com interop" from project properties and built. It registered autometically and I can use created .tlb file in that PC in Vb6 working fine. if I deploy application to another PC and run I am getting "Error 429 ActiveX Component Can't create object" run time error. What I need to do? Please help me as soon as possible. I can't deploy the application to client due to above error.
one possible solution is to install .net frame work on client pc i never want to install .net framework any other solution will be most appreciatable.
If you've created a DLL in a .NET language (such as VB.NET), the target computer must have the .NET Framework installed in order to use the DLL.
This a hard and fast requirement, irrelevant of how you're utilizing the DLL, whether from a VB 6 application through COM interop or otherwise. It is also a hurdle you'll have to jump over first, before you worry about things like registering COM components, as Uday's answer suggests.
If you don't want a dependency on .NET, you need to use another environment to create the ActiveX DLL; either C++ or VB 6 are possible choices.
One option may be that, while deployment, you need to register that .tlb file in System Registry using regsvr32 command in command-prompt. Generally static libraries does not work until they are registered with System Registry.
You might have seen many programs register components during installation like 'Registering Type Components' or 'Registering COM Components' (for those who do networking especially). Those components are nothing but native COM dlls and tlbs.
so when creating deployment project, add some scripting login to register thode dlls and tlb to System registry using:
regsvr32 <path to tlb/dll>
you have to recursivey call this command for every dll/tlb you want to register with system. For example, if you have 4 dlls and 2 tlbs then you have to call it 6 times providing the path of dll and tlb one at a time.
I have an existing (C# based) windows service that is derived from the Installer class and I currently use the MS supplied, command line InstallUtil to install it and uninstall it. This works fine and as part of my system I have attached event handlers to the AfterUninstallEventHandler and CommittedEventHandler events. In my case I simply use them to log messages to a custom event log - showing the install and uninstall dates and times and program versions.
At the moment I am experimenting with Wix v3.5 Beta 1 to package up a bunch of my stuff including this service and I am using the Wix ServiceInstall and ServiceControl to replace what I manually did with InstallUtil.
However it seems that Wix uses a totally different mechanism to InstallUtil for installing services. This is seen in the name and description of the service being controlled by Wix (as opposed to what was embedded in the service program) and that my events no longer fire (which, if a different install mechanism is being used I doubt that they would).
So is it possible for Wix to perform a service installation in the same manner as InstallUtil or am I just going to put up with the differences?
Edit
Christopher has suggested factoring out the service related definitions from my code and moving them into the Wix installer project. This makes me uneasy as now I either have to find a way to share information between two separate systems (which I have no idea how to share between the code and Wix projects) or put up with defining the information in two separate locations (very bad software practice).
From a windows installer perspective, InstallUtil is an evil antipattern because it injects fragile out of process code into a declarative programming model. The Windows Installer has long had the ServiceInstall and ServiceControl tables and this works really well. The same applies to Regasm and Regserver. We prefer to extract the COM data and author it into the installer and have MSI take care of applying the registry value rather then loading assemblies and calling entry points in the hope that it works. When it fails, you have no idea why and you can't roll the state of the machine back.
What kind of stuff are you doing in your events? I would either eliminate and/or refactor each of them into something MSI can do for you. If it's still not enough, write a DTF custom action and schedule it between InstallServices and StartServices.
I'm working on a project whose setup uses the APIs documented in Microsoft Knowledge Base article KB317540 to install and uninstall assemblies into the GAC. The KB article states:
SUMMARY
The native code application
programming interfaces (APIs) that
allow you to interact with the Global
Assembly Cache (GAC) are not
documented in the .NET Framework
Software Development Kit (SDK)
documentation.
MORE INFORMATION
CAUTION: Do not use
these APIs in your application to
perform assembly binds or to test for
the presence of assemblies or other
run time, development, or design-time
operations. Only administrative tools
and setup programs must use these
APIs. If you use the GAC, this
directly exposes your application to
assembly binding fragility or may
cause your application to work
improperly on future versions of the
.NET Framework.
The GAC stores assemblies that are
shared across all applications on a
computer. The actual storage location
and structure of the GAC is not
documented and is subject to change in
future versions of the .NET Framework
and the Microsoft Windows operating
system.
The only supported method to access
assemblies in the GAC is through the
APIs that are documented in this
article.
Most applications do not have to use
these APIs because the assembly
binding is performed automatically by
the common language runtime. Only
custom setup programs or management
tools must use these APIs. Microsoft
Windows Installer has native support
for installing assemblies to the GAC.
For more information about assemblies
and the GAC, see the .NET Framework
SDK.
Use the GAC API in the following
scenarios: When you install an
assembly to the GAC. When you remove
an assembly from the GAC. When you
export an assembly from the GAC. When
you enumerate assemblies that are
available in the GAC. NOTE:
CoInitialize(Ex) must be called before
you use any of the functions and
interfaces that are described in this
specification.
What are the pros and cons of this technique? Are these APIs safe to use? Anyone out there using them? If so, why?
Why not just create a Windows Installer package? See Demystifying the .NET Global Assembly Cache. Quoting:
Developers of Windows Installer
packages can install assemblies to the
GAC using Microsoft Windows Installer
2.0. This is the preferred way for installing such shared assemblies and
should be the only way shared
assemblies are installed on non
development machines.
It says, "Only administrative tools and setup programs must use these APIs."
There are tools (e.g. command-line tools) to work with the GAC. Why not invoke these executables, instead of using these APIs directly?