DLL working in one application but not another -- environmental differences? - plugins

Speaking broadly...
I have a COM DLL that is loaded at run-time. That DLL loads another DLL from an absolute path specified in the registry. When I load the COM DLL in a stand-alone test executable, the second DLL is found and loaded fine. However, when I load the COM DLL in a different executable, the second DLL is not found. Both executables are in the same directory and have the same permissions. The COM DLL is a driver that provides a high-level interface for the executable; both executables are, theoretically, making the same calls.
Any pointers to things to investigate that could possibly cause this?

For a not-so-exciting conclusion: unregistering the second DLL and reregistering it resolved the issue. I had registered the DLL multiple times without thinking that unregistering it first would do anything different.
Thanks #CareyGregory

Related

Can the Powershell "using" statement with dynamic module paths?

I have some powershell modules which contain classes I need to instantiate from various powershell scripts. To access the classes from the powershell scripts I am have statements like:
using module "..\..\Library\Mymodule.psm1"
But I dont know ahead of time where in the folder hierarchy my library will be relative to the script.
We dont want to use the standard powershell modules folders because these classes are under source control and deploying to user's folders would be nightmarish.
This is an extremely hard topic to google because, well "using" is used everywhere!
Tried provide multiple possible locations for the same file but of course we get an error for the alternate locations that do not exist:
The specified module 'C:...Mymodule.psm1' was not loaded because no valid module file was found in any module directory.
At line:0 char:0
using module "..\..\Library\Mymodule.psm1"
using module "..\Library\Mymodule.psm1"
using module ".\Library\Mymodule.psm1"
But I'd rather run a function to first determine the correct module path, and then use something like this
using module "$foundModulePath"
Is there any way to dynamically set the path of a module and then "using" it?
I would version my modules in a separate repository and write a function the clones that repository inside the workspace at runtime.
Using tags in that repo - would allow me to control the version of the modules I am loading for each script.
This will make the development of the modules possible, even when a script still has to use the old versions and I don't want to "invest" time in re-writing it , just because I've changed a dependency.
idea no 2.
Gradle is very good in handling messy dependencies lists in big projects.
You can build a gradle script that prepares the workspace and then, from inside of it, execute your powershell script.
See Link here

How to manage development of PowerShell snap-ins with x86 and x64 versions

I am currently writing a PowerShell snapin that has specific dependencies on mixed-mode assemblies (assemblies containing native code) that specifically target x64 or x86. I have both versions of the dependent assembly, but I am wondering how best to manage the build and deployment of this snapin, specifically:
Is it necessary to have two versions of the snapin, one x86 and one x64, and use the two different versions of installutil to install it, once for each architecture?
Assuming #1 is true, is it recommended to install the two different versions of the snapin in the different "Program Files" and "Program Files (x86)" directories?
What is the ideal (least hassle) way to structure a pair of projects that share everything but a single reference, in order to build for the two different architectures?
If the snapin is compiled as "AnyCpu", and the dependent dlls are both loaded into the GAC, will the runtime load the correct assembly from the GAC based on the architecture of the currently running PowerShell host?
Is there a slick way to dynamically, at run-time, choose which dependent dll to load (if it cannot, for various reasons, be installed in the GAC) without running into headaches with assembly load contexts?
Mark, we have this very situation with the PowerShell Community Extensions with 32-bit and 64-bit versions of 7zip.dll. You can pretty easily work around this by PInvoking to LoadLibrary early in your snapin startup (or before you need to call out to the native DLL). You can then test if you're a 32-bit or 64-bit process (IntPtr.Size) and then load manually the correct DLL using the LoadLibrary PInvoke. After that the, DllImport("YourNative.dll") will notice that the dll is already loaded and use that DLL.
Take a look at these two PSCX source code files:
http://pscx.codeplex.com/SourceControl/changeset/view/74794?ProjectName=Pscx#1358100
http://pscx.codeplex.com/SourceControl/changeset/view/74794?ProjectName=Pscx#1358102
I ended up creating a module (thanks, Richard!), but that didn't solve the problems related to processor architecture. In order to solve that, I put both versions of the dependent dll in the module directory, and in each cmdlet's constructor I put some initialization code (that only runs once) to load the appropriate version of the dependent dll.
Thanks, all, for the pointers.

How do find out what libraries a windows exe uses?

I have a 3rd party application that doesn't come with an installer. It's a very small exe, a simulator.
Anyhow, it crashes on startup due to some missing libraries. But the error doesn't tell me which ones. Is there an application on windows that tells me which libraries are going to be loaded at program load time?
It's been a few years since i've used it but Dependency Walker got me through a lot of DLL hell.
Also, Process Explorer is a great and fast way to see what DLLs are loaded by an EXE on a test machine... for comparison purposes when hunting down missing DLLs.
Only a partial answer: DEPENDS.EXE tells you what dlls a dll needs. I think it works for EXE's too.

Deploy system DLL inside CAB file

I’m looking for a way to deploy a system DLL within my ActiveX CAB file. CAB cannot update system file and whole installation fails. Perfectly, I would like to copy the DLL into ActiveX installation folder.
My best suggestion (I didn’t try it yet) is using INF file hooks with some standalone installer, but I wonder is there another way?
Any other ideas will be appreciated…
Pack your dll in as a resource of the main ActiveX control. Use your own code to write it to a file.
The malware industry has lots of experience doing this, and example code should be available.
You can install the dll into the ActiveX installation folder and dynamically load the dll (using LoadLibrary) and its methods (using GetProcAddress).
This way you will be able to control from where to load the dll and use your local copy instead of the system.

Nant, Booc, and x64

I have a .NET project that's always been built/run by/on 32 bit machines. I got a new a 64 bit computer and am trying to tackle the task of getting it working there. The build script is in nant, and at one point we compile some boo code using the nant task. The boo code references our core DLL, which is built from c# source earlier in the build process.
I've tried two things: build it to run in 32bit mode and build it to run in 64bit mode. By using corflags on several programs (including booc), I was able to build the project built in 32bit mode, but ended up with a bunch of downstream issues at runtime. So I need to get it built in 64bit mode, which I think is preferable anyway.
According to the nant/booc source code, the booc nant task calls the booc.exe in-process using the CLR's Process class, so (I think) it should inherit 32bitness or 64bitness from the parent process. That doesn't reflect what I'm seeing, though.
Here's what I've done:
Used the 64bit version of powershell to invoke nant
Specified platform="x64" on my tasks. I feel like I shouldn't have to do this because anycpu should be fine, but it seems to make a difference.
Here's the error I'm getting:
[booc] Compiling 5 files to 'C:\dev\build\MyProjectBoo.dll'.
[booc] BCE0106: Failed to access the types defined in assembly 'MyProject, Version=5.5.0.0, Culture=neutral, PublicKeyToken=null' - (C:\dev\build\MyProject.dll):Unable to load one or more of the requested types. Retrieve the LoaderExceptions property for more information.
[booc] is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)
[booc] is not a valid Win32 application. (Exception from HRESULT: 0x800700C1)
[booc] .
[booc] 1 error(s).
Which means, according to the booc source code, "I tried to reflectively list the types in your referenced assembly but failed". I don't know if that means, "I think I'm 32bit but these are 64bit dlls" or what, and I'm very confused.
Any ideas on how I can get this to work?
Update after some work, I've discovered that the issue has nothing to do with boo. I wrote a quick c# program that reflectively loads the dll and it breaks in the same way. So for some reason, no matter what I set as the platform (x86, x64 or anycpu), I can't load it reflectively on an x64 machine. So not really boo's fault. So I'm going to dig into this and repost if I have a better question.
Newer Update
Turns out that one of my main DLL's third party dependencies insists on being in a 32 bit environment, even though it isn't built with corflags. This causes assembly.GetTypes() fail in 64 bit mode.
The problem is dependencies on third-party DLL's that require 32 bit mode, which is possible even if they don't have corflags set.