Configuration files with COM - c#

I have an old PowerBuilder application that we are slowly phasing out. We are also moving to a more service orientated. So in order to facilitate this we are using C# COM wrappers to call WCF methods so old direct SQL calls can be slowly removed. We also use the C# COM wrappers when need functionality is needed in the power builder application.
Since we are using COM calls to DLL from PowerBuilder to C#, there is no need for an external executable. This means that a app.config file will not be loaded on its own. At least that is what I noticed. Example: Let's say the main DLL that has the wrapper methods is Wrapper.dll. If I had config named Wrapper.dll.config it would not get loaded when the make my call from PowerBuilder to C#.
The reason I would like to use a config file is because I would like to start using log4net in the C# dlls in order to make debugging easier because it is hard enough with PowerBuilder. There are other reasons that I would like to load configuration files but the easiest to explain is basically it is easier to set up some stuff using a config file.
So is there a way to load a configuration files into the Configuration manager for a COM call?
Thanks
Tony

Check out this code from Mike Woodring. I think it will enable you to do what you want.

Nice snippet JP.
By default, Runtime assemblies actually get their config settings from the calling executable's config file. Your snippet allows the loading of one associated with the actually library assembly.

Thanks for the answers, while helpful it was not what I was looking for. The "easiest" to do what I need is to name the config file after the calling applications exe. So if the application's name is test.exe and your C# dll is wrapper.dll, then you would name the config file test.exe.config. Since test.exe in this case is a PowerBuilder application, I can get away with this for now. If it were a .net app (and probably others) it would probably already have a config and thus get in the way.
Tony.

Related

IIS ASP.NET MVC and dllimport calls lock the file preventing future deployment

So I have a ASP.NET MVC project handling video files uploads, and I used the MediaInfo library (C++) along with the included C# wrapper (using DllImport functions) to determine the video duration. I added the MediaInfo.dll file to my project, and set the "copy to output directory" to always. Everything works perfectly.
My problem is that when I rebuild (from Visual Studio) or re-deploy the project to my production environment, it fails because the file is locked.
Unable to copy file "Sources\MediaInfo\MediaInfo.dll" to "bin\MediaInfo.dll". The process cannot access the file "bin\MediaInfo.dll" because it is being used by another process.
Of course, that's because IIS is still running. I'm aware I can stop the AppPool, rebuild, and restart it, but it is an hassle to do it every time you build in development, and complicate updates in production. Especially when every other DLLs (.NET) and the rest of the project can be updated without having to do that.
So I tried the method suggested here and here . Each time I want to scan a video, I use LoadLibrary() and after call FreeLibrary() until it returns false. The FreeLibrary part works, it unlock the file. But calling the method a second time, it calls LoadLibrary and then at the first DllImport function call, I get an InvalidOperationException and the process crash.
I feel like I'm overdoing thing and it don't feel normal and I'm wondering if I'm completely on the wrong track.
What's the usual method to develop using non-managed dll calls in a usual Visual Studio / MVC environment?
After reading more on the subject, if you want to control the DLL loading/unloading process, it can't be done with DllImport. You need to use GetProcAddress to call the functions. You could also create a C++/CLI library.
In my case, I managed to "hack" around the problem by creating a different AppDomain every time and forcing a FreeLibrary call and a AppDomain.Unload. This cause the DllImport to reload the dll successfully because it's a different AppDomain.

Generate a CIL executable not EXE then execute it

I have a c# project that generates an EXE file. Now, I'm in a "secure" corporate environment, where I can compile my project, but I cannot execute the EXE file.
As a Java programmer, I'm wondering if there is not a way to compile the c# project into something that would not be an EXE file, but a CIL file and then execute the CIL file by something that corresponds to java.exe in the dotnet world.
EDIT in response to comments:
I can run exe files that have been installed by a package manager
Yes, I know the corporate policy is stupid.
Well, this should be pretty easy.
.NET executables are simply DLLs like any other - the main difference being the executable format itself, and the fact that EXE files have an entry point, while DLLs don't.
It also means that you can load the EXE into memory exactly the same way as you would with a DLL:
Assembly.LoadFrom("SomeExe.exe");
You're already half way there - now we just need to find and execute the entry point. And unsurprisingly, this is also pretty trivial:
var assembly = Assembly.LoadFrom("SomeExe.exe");
assembly.EntryPoint.Invoke(null, null);
For most applications, this should work perfectly fine; for some, you'll have to make sure the thread you're using to invoke the entry point has STAThread or MTAThread respectively (Thread.TrySetThreadApartment if you're starting a new thread).
It might need tweaking for some applications, but it shouldn't be too hard to fix.
So you can just make some bootstrap application ("interpreter") that only really contains these two lines of code. If you can't get even that approved, and you really need something as an "official package", try some .NET application that allows you to execute arbitrary code - for example, LINQPad, or PowerShell.
EDIT:
This does have limitations, of course, and it does introduce some extra setup work:
The bootstrapper has to target the same or higher version of .NET Framework. .NET Portable might be particularly tricky, but I assume you have that well under control. It also has to have the same bitness (if specified explicitly).
You need to run the debugging through the bootstrapper. That actually isn't all too hard - just go to project properties, debug and select "Start external program".
The bootstrapper has to run under full trust conditions - it's necessary for reflection to work. On most systems, this simply means you have to have the exe as a local file (e.g. not from a network share). Tools like LINQPad will run under full trust by default.
The application must not depend on Assembly.GetEntryAssembly. This isn't used all that often, so it shouldn't be a problem. Quite a few similar issues should also be fine since you build the application you're trying to run yourself.

What files are mandatory in release windows form?

I have files in ...bin/release where is my windows form application, I have used EEPlus library as well. What the files do I need to send to client to have application work correctly?
My files:
name.exe
name.exe.config
name.pdb
name.vshost.exe
name.vshost.exe.config
name.vshost.exe.manifest
EEPlus.dll
EEPlus.xml
I know that first two are mandatory, but what about all rest?
thanks in advance
name.exe //necessary, it is your main executable
name.exe.config //necessary, it is your application config file
name.pdb //not necessary, it contains code and debug symbols configuration of your assembly, but let it be there, it is useful when users encounter a bug or crash
name.vshost.exe //not necessary, it is the hosting process of visual studio for debugging purposes
name.vshost.exe.config //not necessary, config file of name.vshost.exe
name.vshost.exe.manifest //not necessary, manifest of name.vshost.exe
EEPlus.dll //necessary, it is one of your application dependencies
EEPlus.xml //not necessary, contains some information for EEPlus.dll
reference for xml, reference for vshost, reference for pdb
All except *.pdb and *vshost*.
Really you should look at the REFERENCES of your project.
Generically all the assemblies that don't make part of the NET Framework need to be redistributed.
In this case, it seems that you need to distribute EEPlus.dll only.
The other files are there just as a byproduct of the compilation.
Of course, you should also consider that a thirdy party library could need other files, but this should be explained in their documentation under the redistrubute page.
You could try this:
Delete all files except the name.exe, name.exe.config and EEPlus.DLL, then run your app outside VS directly in the BIN\RELEASE folder. However I recommend to have a clean virtual machine where you could test your app and be sure to not forget anything.
Always
name.exe
name.exe.config
Dependency dlls
Interop dlls
First we check this mandatory files before giving to client, because at client, when running application that will be crashed without displaying any errors...

location of external dlls in c#

I am a newbie to c# and developed a small WPF application which depends on a external dll files. I have added it as reference in the visual studio and started using the methods in side it.
I started to face the problem when I am deploying this utility to other computers. It is mandating me to place the external dll file in the same location of WPF exe file. And I want to avoid this. Instead I want it to look a specific folder(local or remote).
Is it possible to do this way?
Thanks,
Sitaram
The best solution would be to set the LocalCopy Property of the Reference to true. That will copy it to your output exe.
A very bad solution would be to load the assembly manuall in code (Assembly.Load) and add it to your AppContext.

Whats a good approach for white labeling dll

Whats a good approach for white labeling dll and exe with visual studio?
In essence we want to be able to have the name of the dll and exe change based on the client that we are packaging the solution for, e.g.:
Instead of myCompany.exe and myCompany.db.dll, I would like yourComany.exe and yourComany.db.dll or acme.exe and acme.db.dll, etc
Edit:
Currently we are using a straight visual studio build process with a wix project to create an msi.
If the only justification for rebuilding it is to change the name, can you just use something generic in the first place? Imagine having to patch 50 identical DLLs, and build/deploying each one separately because they all must be named different things. Even if it's only for a few clients, I would hate to have to maintain that. Versioning could be a hassle too.
If you must do it, I would probably go with a build task (which can perform fairly advanced operations). You mention that you are "packaged the solution"; the viability of a build task would depend on how it is being packaged.
In response to your comment about naming the EXEs with client-specific names... My obvious suggestion there would be to have those applications contain as little code as possible.
The simplest build integration I can think of would be to create a post-build task which ran upon successful compilation in release mode. The task could then read a config file which defined the unique names, and copy the successfully built EXEs to an output directory.
Some of the operations can be accomplished just from the task config file: http://msdn.microsoft.com/en-us/library/ms171466.
Alternatively, you might want to create a little application to do all the work for you, and just pass config switches to it.
For example, here is a little post-build command that I execute to minify my JavaScript/CSS upon successful build of a web application. The concept is similar:
build
execute an app (like msbuild.exe, or your custom build app)
pass data to the executable (like paths, switches, etc.)
executable writes the files out
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild.exe
"$(ProjectDir)Properties\build\minify.xml"
/p:SourceLocation="$(ProjectDir)client"
/p:CssOutputFile="$(ProjectDir)client\final\final-full.css"
/p:JavaScriptOutputDirectory="$(ProjectDir)client\final"
You could use ILMerge in whatever post-build process you want on all your outputted assemblies (dll and exe), to create one-off customer-branded builds.
ilmerge /out:CustomerName.exe internalName.dll internalName.exe
I don't know that there is a good way to do this without actually building the project as XYZ company. You could try something like this which will give you the desired result BUT it will change the physical name of the assembly as well which may cause dependency problems.

Categories

Resources