How do I create 1 .NET Settings per instance of DLL - appsettings

My service is a DLL and it can be installed multiple times. The DLL has its settings stored in Settings.settings. Each instance of the DLL will have its own Settings.settings. Can this be done with Settings.settings, or do I have to create my own configuration scheme? I want to avoid reinventing the wheel if possible. I don't have to necessarily have separate files, just a mechanism for allowing me to load the correct settings for the correct instance of the DLL.

perhaps you could use an app.config that will get installed in the same directory as your service: http://www.codeproject.com/KB/dotnet/dllappconfig.aspx

Related

How to create a manifest file for TLBs which are used for remote COM objects only?

My Delphi application Client.exe needs a couple of .tlb files to work. These files define server interfaces. The corresponding object instances are created with System.Win.ComObj.CreateRemoteComObject.
What is the problem?
For now the .tlb files are registered globally during the installation using regtlibv12.exe and are unregistered on uninstalling the software. This makes it impossible to install and uninstall multiple instances of the same software since it can break the TLB registrations.
Attempt to solve it with Registration Free COM
The idea is to use the .tlb files without registration but with a .manifest file.
I know how to use a customized Windows application manifest file with Delphi. But I don't know how to extract the information from the .tlb files and create the correct .manifest file.
I have found Mt.exe which can be used to generate .manifest files but it doesn't help me because
it's asking for a corresponding DLL file when the -tlb parameter is set but there are no .dll files shipped with the application since the COM objects are created on remote machines
it doesn't accept multiple .tlb files in the parameter list.
Other tools like Make My Manifest or Unattended Make My Manifest aren't available anymore or don't help me either.
What is the right way to create a manifest file in this case?
AFAIK RegFree COM does only support registration of local instances, via a dll. There is no way of using it with DCOM, which is something much more complex than local COM.
From my own experiment, DCOM could be a real PITA, especially in terms of registration. IMHO you should either use local COM objects, or switch to another much standard approach, like REST services. You may be able to re-use almost the same interfaces using e.g. an SOA approach over REST/JSON - see especially sicClientDriven mode to emulate DCOM objects.

Developing Reg-Free COM application with VB6

I'm maintaining a VB6 application with many COM components (DLLs and OCXs). In order to streamline development and deployment I'd like to use reg-free com. The problem with development is that the application runs within the VB6.EXE instance. How can I trick VB6 to use my (unregistered) components? It is very important for me to not have to go through registering/unregistering components when switching between branches. Generating a .manifest file for VB6 is not out of the question but is there some other, more optimal way, to specify a .manifest file when launching VB6.EXE?
Note: The Activation Context API doesn't seem to help, even if used from within the development environment.
Solutions I've thought:
A utility application that activates a context from a manifest and launches VB6 as a child process (doesn't work; processes don't inherit activation context)
Injecting context activation into the VB6 process at startup (too complicated; must hack the executable to do this)
Hosting VB6 in my own process after activating the right context (can't even find out if this is possible)
Using a VB6 Add-In or other utility that runs within VB6 to activate a context (tried that but it doesn't seem to work)
Update Jan. 16
As suggested by wqw, I did some testing with a VB.exe.manifest. The VB6.exe.manifest worked, with some caveats:
The SxS dll specified in the manifest would not appear in the references window on projects that didn't actually reference the component
On projects that did reference the component it would be shown to reside in the directory according to the following order:
The pathname recorded in the project file (if the file was still present)
A pathname as if it resided in the same folder as the project (vbp)
If the file was not in any of these folders, the project would not compile (just running the code causes an internal compile in VB6) with the message "Can't find project or library".
Obviously, VB6 actualy scans the registry to find COM components and verifies, during compilation, that they exist where they say they exist. I'm not sure what that might mean if I actually want to use VB6.exe.manifest to redirect COM component instantiation. Perhaps having dummy component files at some predefined location might trick VB6 into believing that everything is as it should be, although an entirely different set of components got loaded for use.
Further update:
I did a test on that last assumption and it proved to be false. The component has to actually be there in order for the project to compile. It must even properly load (no dummy, zero-length files accepted!). Now I'm not even sure if the manifest works. That's a more time-consuming test (requires a component with two versions that produce different results, one with the project, and one for the manifest).
Our approach to this problem was to write a build assist program that registered and unregistered components, run the VB6 compiler, and would even rewrite project files with updated GUIDs when interfaces changed. You would hand it a VBG project group and it would do the rest.
I suppose we could also have added a mode that unregistered components when you switched branches.
Are you following the practice of using "compatibility" binaries? You shouldn't use the binary at your build location for compatibility references - you should commit a separate copy to version control and configure your project to consider that the "compatible" version - only change this file when you break interfaces.

Common runtime for different DLLs

I need to build a DLL capable to load other DLLs at runtime; these other DLLs have a rather intimate relationship with the main DLL (this is Python and extensions), so they must have a common runtime. The main DLL must be a single file that can be simply copied on the target machine. The auxiliary DLLs will be placed in a different directory.
So: "common runtime" means no static linking; "single file + simple copy" rules out the shared MS redistributables, especially when coupled with "different directories".
I only see the following options: link all DLLs against msvcrt.dll; embed current msvcrtXX into the main DLL and re-export all its symbols; use the msvcrtXX of the host application. To me the first looks the simplest, because it's a common need and there are many web pages explaining how to go about it. How would you approach this?
I suggest you re-architecture so that your plug-in DLL (the one the host application loads explicitly) contains nothing but proxy functions plus the file management logic. This DLL could use a static runtime, or no runtime at all.
Put the actual functionality (and in particular all code that needs to share a runtime with the Python extensions) in a separate ("primary") DLL and put this DLL, as well as the runtime of your choice, in the same directory as the Python extensions.
The primary DLL and the runtime could be zipped to the plug-in DLL, along with the core extensions. (I presume this is within the scope of the runtime's redistributable license, since it's basically the same as the way most installers work, but you should check for yourself.)
The calls to the plug-in will be slightly less efficient since they have to go through the proxy DLL, but the performance difference probably won't be measurable. :-)
Another option (in my humble opinion, much better) would be to dynamically link - aka. LoadLibrary/GetProcAddress) the dependencies when the main starts. This would allow you to support cases of missing DLLs and/or support your own internal version scheme.

Can I use manifests to consume a COM server without specifying its version?

Two of our programs use the same COM server (also made by us) with the same class ids. Each program when installing copies the COM server files into its folder and regsvr32s the COM server.
The problem is how to install the COM server so that the user can install either one or both of our programs into different folders in any order and likely of different versions. Clearly it's impossible without changing the class ids and that's lots of hassle with configurations. Ideally we would like to use manifests for that and go without regsvr32.
The problem is every time I read about reg-free COM (for example, here) there's the version attribute in the assemblyIdentity. The version number should change every nightly build and I totally don't like the idea of (automatically) adjusting it. I understand why specifying dependency on a specific version is good, but it's completely useless in our scenarion.
Is there a way to write manifests for both the COM server and the consumer so that they don't specify versions and just work with whatever version of the file happens to be in the folder? Also is there a way to restrict the search to the same folder as the consumer?
Windows searches for manifests only in the global location followed by the application directory. If you don't install anything globally, search is effectively restricted to the same folder.
If you're always shipping the COM server in the same folder as the COM client, they are effectively one "software unit". version considerations are interface contracts between different software units, so in your scenario it doesn't matter. You can either omit the version attribute from the identity or set it to something fixed like "1.0.0.0", knowing that at that point, it's up to the way you distribute the software to ensure the proper versioning story, and not the side-by-side system.

Loading multiple copies of a group of DLLs in the same process

Background
I'm maintaining a plugin for an application. I'm Using Visual C++ 2003.
The plugin is composed of several DLLs - there's the main DLL, that's the one that the application loads using LoadLibrary, and there are several utility DLLs that are used by the main DLL and by each other.
Dependencies generally look like this:
plugin.dll -> utilA.dll, utilB.dll
utilA.dll -> utilB.dll
utilB.dll -> utilA.dll, utilC.dll
You get the picture.
Some of the dependencies between the DLLs are load-time and some run-time.
All the DLL files are stored in the executable's directory (not a requirement, just how it works now).
The problem
There's a new requirement - running multiple instances of the plugin within the application.
The application runs each instance of a plugin in its own thread, i.e. each thread calls functions exported by plugin.dll. The plugin's code, however, is anything but thread-safe - lots of global variables etc..
Unfortunately, fixing the whole thing isn't currently an option, so I need a way to load multiple (at most 3) copies of the plugin's DLLs in the same process.
Option 1: The distinct names approach
Creating 3 copies of each DLL file, so that each file has a distinct name. e.g. plugin1.dll, plugin2.dll, plugin3.dll, utilA1.dll, utilA2.dll, utilA3.dll, utilB1.dll, etc.. The application will load plugin1.dll, plugin2.dll and plugin3.dll. The files will be in the executable's directory.
For each group of DLLs to know each other by name (so the inter-dependencies work), the names need to be known at compilation time - meaning the DLLs need to be compiled multiple times, only each time with different output file names.
Not very complicated, but I'd hate having 3 copies of the VS project files, and don't like having to compile the same files over and over.
Option 2: The side-by-side assemblies approach
Creating 3 copies of the DLL files, each group in its own directory, and defining each group as an assembly by putting an assembly manifest file in the directory, listing the plugin's DLLs.
Each DLL will have an application manifest pointing to the assembly, so that the loader finds the copies of the utility DLLs that reside in the same directory. The manifest needs to be embedded for it to be found when a DLL is loaded using LoadLibrary. I'll use mt.exe from a later VS version for the job, since VS2003 has no built-in manifest embedding support.
I've tried this approach with partial success - dependencies are found during load-time of the DLLs, but not when a DLL function is called that loads another DLL.
This seems to be the expected behavior according to this article - A DLL's activation context is only used at the DLL's load-time, and afterwards it's deactivated and the process's activation context is used.
Edit: Works with ISOLATION_AWARE_ENABLED as expected - runtime loading of DLLs uses the original activation context of the loading DLL.
Questions
Got any other options? Any quick & dirty solution will do. :-)
Will ISOLATION_AWARE_ENABLED even work with VS2003? Edit: It does.
Comments will be greatly appreciated.
Thanks!
ISOLATION_AWARE_ENABLED is implemented by the Windows SDK header files and thus probably wont worth with VS2003 at all. However, it is possible to download the latest Windows 7 SDK and use that with VS2003.
You don't need to use MT to link in manifests. Manifests can be embedded as resources in environments that dont have explicit knowledge.
Add the following to a dll's .rc file to embed a manifest. (With a recent enough platform sdk RT_MANIFEST should already be defined):
#define RT_MANIFEST 24
#define APP_MANIFEST 1
#define DLL_MANIFEST 2
DLL_MANIFEST RT_MANIFEST dllName.dll.embed.manifest

Resources