I am using Activation Context API in a .Net client running in a location A to load a COM component reg-free in location B (which is completely different location to A, not a sibling/descendent etc. on the same machine) on WS2008 by passing in location B in the ACTCTX and it works fine.
However, I now need to do the same thing with another COM dll which in turn has dependencies on a couple of .Net COM assemblies which live in completely different locations.
I have added the dependent .Net assemblies to the manifest and put the manifest and COM dll in location B but I have to put the dependent .Net assemblies in location A (where the client runs) to get it to work. In reality, they will live in completely different directories to location A and location B.
Is what I'm attempting to do possible, i.e. is it possible to load multiple COM components in different unrelated directories using activation context api?
.NET looks at the active and process activation contexts to discover reg-free metadata (<clrClass>, etc) just like native COM does. Unlike native COM, however, it doesn't use the information contained in the activation context to determine the location of the actual files. There, I believe it looks only at the GAC, followed by locations of files next to the client EXE only. You can probably confirm this using Sysinternals Procmon. I'd imagine you could try the workarounds Hans suggested or pre-loading the needed assemblies manually into your process and see if that works; I didn't get to try this out as in my scenario the client exe was a native exe I didn't have control over.
Related
I'm somewhat new to deploying ClickOnce manifests, first off. I know the basics of how to publish to an app server, which then lets every use the newest version (after setting to check for updates before running the application).
We have multiple VB.Net applications stored on our app server, that cover a lot of different areas of the company. However, all of them connect to our Oracle database in the same way. So, my thought was to create a DLL containing commonly used functions, such as decrypting and reading our connection string, among some very common SQL functions/statements that we use a lot. Then, instead of copying and pasting the same code into each .Net program, it would be stored in one place. Of course, the major benefit to this would be that if we change the method we use to connect to the database, or need functions modified/added, we don't need to open each program, paste it in, and .republish
So, I did a test where I took a program that I wrote, added the DLL to it and tested it out. It works great. Then I took the source code of the DLL, made a change to show a message box at the beginning of a function, rebuilt the DLL, and dropped it in place of the copy that was being referenced in the test program. When I run the program, it's still using the original DLL without the message box code.
My question is, how could I accomplish what I would like to do without having to republish each and every .Net program that uses this DLL whenever a change is made to it?
Option 1
Instead of publishing your dll library via click once, Put a web service wrapper around your dll class library. Each Click once application will have a reference to the web service which will run on a web server.
Your code in the dll will then be running on the web server. Any changes to the dll code will only need to be updated on the web server. You'll have to be careful to keep the interface changes to a minimum.
Option 2
push out the dll as an separate MSI install. Reference the dll in your click once apps code and make sure you don't deploy the dll with the click once install. Changes to the dll will be pushed out separately.
I have a VB.NET winforms application (4.0) that depends on a number of external 3rd party libraries/software (ie mapping, directx, etc).
Ideally I would like to run a computationally-intensive portion of the program on another machine without having the other libraries installed (due to licensing restraints).
Is it possible to have the VB .NET application ignore the 'Imports'/requirement for the other libraries? Can I error handle it?
You could split the functionality that requires 3rd party libraries in to a separate assembly that you load using reflection only when it is configured to do so. If all the access is done through interfaces defined on the main program then it will not require a direct reference to the "plugin" assembly.
My website application uses C# COM+ components running under a particular identity to access SQL Server, invoked from classic ASP.
There's also a web service that utilises a \bin DLL in the website application that contains a method to insert some data into the SQL Server database (let's call it MyApp.Database.dll).
From the website front end, I want to be able to provide authenticated users with this same functionality.
I don't want to duplicate code in MyApp.Database.dll within the COM+ component for obvious reasons.
My idea was to utilise the COM+ component from ASP to invoke the MyApp.Database.dll method to access the SQL database using the application credential since the ASP is running as the user and has no access to SQL Server.
Problem I've seem to run into is that although I can reference MyApp.Database.dll in my COM+ component project (under 'References' and 'using MyApp.Database.dll'), when it comes to actually running or debugging the COM+ component, when it tries to invoke the method from MyApp.Database.dll, it tells me 'Could not load files or assembly 'MyApp.Database, Version=3.3.3.11658, Culture=neutral, PublicKeyToken=.....' or one of its dependencies.'
The MyApp.Database.dll is not registered in GAC (trying to avoid this, it's also used by other applications as well), and hasn't had its codebase registered in the registry using regasm (I tried this and still didn't work). The version is correct, and I've placed MyApp.Database.dll in the application folder of the COM+ component.
Am I missing something or is it not possible to do this?
Thanks in advance for your help.
This is a common mistaken expectation: just because your .NET COM DLL was found in some given folder (the folder set by the /codebase argument or RegAsm) -- it doesn't mean .NET will look on that folder for anything else.
Generally speaking, it won't. Loading a .NET assemblies via COM interop is a special case. For everything else, assemblies will be loaded in the AppDomain based on the Fusion binding policy for the process - which has nothing to do with where your .NET COM DLL is. The process is actually (depending on your version of IIS) either dllhost.exe, iisexpress.exe or w3wp.exe.
You have a few options.
First, the obvious solution is putting MyApp.Database.dll in the GAC, since .NET always looks there. Sometimes that's the right choice (I've done that and it works). You have declined to do so and you have your reasons; that's Ok.
Second, I believe you can change the binding policy with a web.config file. See here: http://msdn.microsoft.com/en-us/library/823z9h8w(v=vs.110).aspx. Yes, your ASP Classic project can have a web.config. Obviously it has no effect on your ASP Classic scripts, but (depending on the version of IIS), .NET and/or IIS itself use it for configuration. I'm afraid that I can't help you much with this alternative because I've never had to try it before, but you're welcome to explore that option - let me know how it goes.
Third option - my personal choice: You said this DLL is already a web service, right? Just call the functionality with a web service call from your COM DLL. That doesn't require mucking with magic folders, GAC and binding policies. Much cleaner. The only mild complication is tracking in configuration where your web service is located - and I bet you already do that for your database connection anyway, so it shouldn't be hard to add.
If you are curious to know where .NET is looking for the DLL, read up on these guys:
How to enable assembly bind failure logging (Fusion) in .NET
http://www.hanselman.com/blog/BackToBasicsUsingFusionLogViewerToDebugObscureLoaderErrors.aspx
http://www.hanselman.com/blog/MoreOnAssemblyBindingStrongNamingTheGACPublisherPolicyAndDynamicallyLoadedAssemblies.aspx
Good luck, and please let us know what worked for you.
I have some methods which are not compiled with Silverlight framework but are very essential for execution of SL workflow(by workflow, I mean to process my application completely). What is the best/quickest way to do so?
I was thinking of publishing a web-service(for non-sl compiled methods) and make SL call into my WS.. but I am unable to see/create webservice instance even after registering one in my SL project. (I am using VS 2010)
any help?
Esentially, you have three ways to run code.
native built-in methods in your application--this would be the easiest way
methods that live in an external silverlight assembly, like a class library
use a webservice
if you use a webservice, you have to either host the website yourself or use a 3rd party website, then add a reference to said service. if the service is not hosted on the same website as your silverlight app, there must be a cross-domain policy file in place otherwise silverlight will not use the service.
if you use an external assembly, it MUST be a silverlight assembly. you can not use a windows class library, etc.
There is a common (and relatively easy) way to solve this issue without requiring a web service: you can create a new Silverlight class library and then share the files from the other project through to your new Silverlight library.
To do this, right click on the library in the Solution Explorer, and select Add -> Existing Item, then navigate to the appropriate code file, select it, but instead of just clicking Add you should instead click the little down arrow and select Add As Link.
Of course when you do this you have to ensure that the shared files don't contain anything that cannot be compiled targeting the Silverlight runtime, if they do then you will either have to use conditional compilation directives to isolate out that code, or revert to the web service option.
I'm in need of distributing several old COM applications that are to be installed on locked down computers. I'm trying to get these applications to launch without having to be registered in the registry via regsvr32 or in the case of an EXE component via the /regserver switch. I can control and locally copy all the required dependencies in this scenario.
I know this is possible, however, I'm having a real tough time piecing together the different pieces or finding coherent information on how to set this up.
Any help or pointers would be greatly appreciated.
Microsoft has a good tutorial on Registration Free COM.
There are two basic parts to getting registration free COM working.
First, you need to convert the COM dlls to an assebmly: Just the COM dll's, and create a manifest describing them, and give it a name. Bundle this assembly in the same folder as your application.
Next, you need to tell your application to use the assembly you just created. When COM tries to create a new object, it will first look in any assemblies registered in the default activation context, before looking in the registry.
Registrationless COM can be tricky to set up but the overall process is not very complex. I wrote up my process along with some tools that help with debugging problems in a blog post here:
http://www.west-wind.com/weblog/posts/2011/Oct/09/An-easy-way-to-create-Side-by-Side-registrationless-COM-Manifests-with-Visual-Studio
FWIW, registrationless COM doesn't work with DCOM EXE servers unfortunately - only DLL servers are supported.