How to start assembly from GAC? - gac

I try to do the following:
Put a complete program to gac and start it from there.
I tried:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\ngen install C:\GacTest\test.exe
The output said a lot with compiling assemblies which looked good - references classes should be bundled with application.
But how can I now start the application from GAC? As .net4.5 32 bit application i assumed that there would be a folder C:\Windows\Microsoft.NET\assembly\GAC_32\test - but there isn't
ngen display ..\text.exe
shows the original folder as ngen roots and a native image called Text, Version..., Culture
Maybe some information why I want to use ngen: An application needs a long startup time which should be reduced. On different places there is the information that ngen could speed up the startup time. If i try just the install as above and start from application directory - the startup time is neither changed to better or worse and I just don't know wether precompiled GAC version or jitted version is used. (That would be the bonus question - how do i know which one is used?)

Related

InstallShield UseDLL() doesn't find dll dependencies in the same directory

I have 1 dll file which I try to load during the installation with UseDLL() in one of my installscripts.
this dll has 2 dlls it depends on. they both located on the same directory of the main dll.
When in build the installation with an older installshield - it find it's dependencies and works fine.
When I try to build it with IS2016, it fails because it doesn't find it's dependencies. (If I put these 2 dlls in SysWOW64 - it finds them and works fine).
What is the problem?
Thanks,
Dudi
It looks like InstallShield 2018 makes this easier through a new Enable/Disable flag called DLL_DIRECTORY_SUPPORTDIR. But in InstallShield 2016 there's a good chance you can add the following InstallScript code to find dependencies in SUPPORTDIR. If your DLLs are in a different directory, substitute that instead.
// Add prototype for SetDllDirectory(); this typically goes near the top of your script
prototype number kernel32.SetDllDirectoryW(wstring);
// Call it; this goes in a function called before your UseDLL call
SetDllDirectoryW(SUPPORTDIR);
Note that doing this removes some protection against DLL planting, so it is safest to do this only if you ensure the DLLs in question are either proactively resistant to such things, or if you vet and secure the directory in question. (I'm uncertain whether InstallShield does this for you.)

Getting out of DLL Hell with Microsoft.VC90.CRT?

I've built a inproc com server dll which I can package as 1 file or many via the build utility py2exe. When I allow all the dependencies to remain external, I have no issues, but bundling as 1 file produces problems.
When the dll is utilized (either registering it or instantiating a com object from it), it immediately loads MSVCR90.DLL from the path c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL no matter what I do, I can't change that. There is no information that I can find (using Dependency Walker) to indicate what is causing that to load. It just happens magically...
Then, later on it loads that dll again via an explicit call to LoadLibraryA("MSVCR90.dll") (part of some py2exe black box?), but this time it does not look into the winsxs manifests / directory. Instead it looks to the system path and/or will respect a dll redirection. That's when the problem occurs. If I set the system path to start with c:\windows\winsxs\x86_microsoft.vc90.crt...\ it will load the exact same dll and be happy - but if ANY other file is utilized - inclusive of a copy of the EXACT same dll - but at a different path - then the whole thing blows up. It can't handle using two different files.
How can I fix this? Ideally, I've love to make the initial magic loading of the dll draw upon a private assembly, but no matter what I do with manifests or .dll.local etc it will not respect that until this second dll loading takes place.
Note that with the non-bundled dll (external dependencies) it always uses the winsxs MSVCR90.DLL.
I can "fix" my failure to use the dll by forcing the system path to load the winsxs copy, but that is pretty useless for a deployable com server!
The reason is that you DLL has a manifest that tells the module loader to search also in the SxS storage.
You have several choices
Build your DLL using static linkage. Not using any of the MFC-DLLs (see project settings)
Don't use a side by side manifest for the DLL and still use the MFC DLLs. But beware you have to ship those DLL with your DLL in the local path (see DLL search sequence docs)
Use a later build of VS. Later versions of VS don't use the SxS storage any more and there are no manifests for those DLLs any more.
For the 2. see this article in code project. There is an update for VS-2008 [here].
2
Build your DLL

Is File.Open directory behavior different in x86 vs x64

I am working on a application built in VB.Net that allows a document to be uploaded and saved into a database. I did not build this application, but I do maintain it, put enhancements in it here and there. The target framework is .Net4
One of the functionalities within this process when uploading and saving the document it uses the method File.Open() to access the file and run other methods to compress it. The method that uses File.Open takes in a parameter that passes just the filename, not the entire path of where it came from.
When this application is running on an x64 machine I receive an error (System.IO.FileNotFoundException) when the code hits the File.Open method, complaining that it cannot find the file to open. It is expecting the file to be in the programs executing directory, which does make sense because it is only given the filename to go off, not the entire directory that it came from.
What's getting to me, is that this exact same application (exact same built assemblies) will run fine when run on an x86 system. It does not fail on File.Open() It still passes just the filename, but somehow, it will know the directory information.
How is this possible?
It's worth noting, that the method that contains the File.Open() method is in a different project in the same solution. It's a referenced DLL. e.g. MyApp.exe (Windows Form Application) references MyUtil.dll (Class Library). I have built against x86, x64 and AnyCPU configurations.
I understand that the fix to this would be to just pass the entire directory to the method, but what I need to know is how this is even possible? I want to better understand why this would happen, and hopefully this would help someone else better understand how assemblies may differ between different system environments.
EDIT: Using an absolute path did fix the underlying issue. See the comments below for some good information on this scenario
Windows has special handling for certain folder names on 64bit systems depending on whether you have a 32bit or 64bit process. Notably, the Program Files folder and the System32 folders map differently depending on what kind of process you have.
Note that this is a difference in Windows itself. It's not a behavior that is unique to .Net or Visual Basic. Any program platform that uses Windows native file handling will give you these results.
This is why you should use appropriate relative paths or the SpecialFolders enumeration, rather than hard-coding full path names, and be careful about where you put things you expect to reference later; you might find they end up in a different location than you expected. Often, the AppData or ProgramData folders are the more correct location, instead of the Windows or Program Files folders.

How can I register ACEDAO.DLL using a Setup and without installing Office?

I am working on a program which uses Access 97 databases (with DAO350.DLL). My goal is to make this program use Access 2007 (and so ACEDAO.DLL) and then deploy the new version on several computers (win7 64bits sp1 without office at all), which don't necessarily had the previous version of the program installed.
I made a new setup by modifying the former setup of the program (created with Package & Deployment Wizard). I thought it was a good idea since PDW doesn't find all the dependencies of the program (former setup contained added-by-hand files) and so I added ACEDAO.DLL.
The setup is made of : Setup.exe, Setup.Lst (which list all files to install and their properties) and a bunch of .CAB archives that contain the files to install.
The line of Setup.Lst concerning ACEDAO is the following :
File97=#ACEDAO.dll,$(CommonFiles)\Microsoft Shared\OFFICE12\,$(DLLSelfRegister),$(Shared),08/21/11 04:52:00 PM,573440,12.0.6650.5000
When I execute Setup on an other pc, I get this error :
ACEDAO.DLL was loaded but entry point for DLLRegisterServer was not
found
I learned afterwards that ACEDAO does not contain DLLRegisterServer function, therefore it couldn't work.
Moreover, ACEDAO needs MSO.dll. When I add MSO to the Setup, this one keeps loading the last file (VB6FR.DLL) from [Bootstrap Files] section of the .Lst file forever :
Traitement de VB6FR.DLL (9/9)
My questions are :
What can I do to register ACEDAO using the setup ?
Any idea why the setup stops when I add MSO.dll ?
I apologize for the grammar quality, English isn't my native language.
Replacing/adding DLLs manually is not going to work, there is a large tree of additional file dependencies involved - for example the COM libraries that wrap ACEDAO.DLL driver.
You need to include the correct redistributable which is probably:
Microsoft Access Database Engine 2010 Redistributable
Your installer will need to run this to install all the files & prerequisites.

Racket error Failure: can not load the DLL

I send a Racket executable(in a distribution package) to a few friends and they get the error:"Failure: can not load the DLL". On my computer it runs without problems. It's using the rsound package.
Yes, good point. Currently, rsound is hard-coded to look in the collection path for the DLL. That won't work for programs compiled into executables. I've just updated rsound to tell it to look in "standard locations" as well for Windows and Mac.
Try this: Using the DrRacket package manager, update your copy of portaudio. When you're done, it should be at version "b9403a6dfbfb5eadf824ed91731ec141bf363677".
After this, it should be possible to pass along the executable file and run it, as long as the two required dll's are in the same directory as the executable. These two dll's are:
portaudio.dll
callbacks.dll
For windows, you'll find both of these in a subdirectory of the portaudio package. Finding these is going to be a teensy bit of a hassle on Windows; I believe these get installed in your user directory\RoamingData\\portaudio\lib\win32\x86_84\3m\ . If the target computer is a 32-bit machine, you'd substitute 'i386' for 'x86_64' in that path.
I know that Windows can make it quite hard to find the files you're looking for; let me know if you have any trouble.
Whew!