I was always under the impression you could make two .net programs for acad, say called prog1 and prog2, and place supporting dll's in each of the folders.
So Prog1's folder would have "helpers.dll", as well as Prog2's folder.
Now, each prog should look to its helpers.dll, as these are not going into the GAC.
What I am seeing though, is my Prog2 is using the Prog1's helper.dll during debug in acad.
Note that Prog1 gets neloaded on startup, so its loaded first.
I had not noticed this before as I kept helpers.dll in synch. I then allowed Prog2's to get ahead, by adding a method, and noticed I got a "method missing" error at runtime in acad.
Its like VS said everything was ok, but acad somehow said "no, use this helpers.dll for the .net prog already loaded".
I am not netloading the helpers.dll, it just sits there as support.
Any ideas how this crosstalk could happen?
The implication is I would not be able to have duplicate supporting dll's for various progs I do.
That is wrong though, .net does allow dupe named dll's so long as they sit right next to the calling dll.
Solved! Go to Solution.
Your issue is that you expect the different DLLs with the same file name, the same version, and the same namespace, but broken compatibility (e.g. all the information in the AssemblyInfo.vb[cs] are the same) to be loaded into the same process (AutoCAD running process).
Your DLL is dynamically loaded when needed, Then the running process (AutoCAD) sees the need to use functionalities in a DLL, it would examine the meta data of loaded assemblies, if it has already been loaded, it will not try to load it from file again. If not loaded, it will try to loaded by looking into GAC/App folder... the usual probing.
So, that is why Helps.dll has already been loaded because of Prog1, then when Prog2 is loaded and needs Helps.dll, AutoCAD simply uses the loaded Helps.dll, and not tries to load Helpds.dll again from Prog2 folder.
The probelems is when do you deliberately create a DLL with the same filer name (and probably the same version, namespace...) yet make different interface (properties, methods) in it? At least you need to make different versions (.NET allows the same components with different version being loaded side by side), if you have to keep the DLL name, namespace the same for some reasons.
I see, very well explained.
Things like versions have never mattered to me since I generally recompile all programs if my central library changes.
Its always "the latest"
I will try that right now. Dealing with making sure no other .net progs of mine were loaded into the debug session was not easy (or fun)....
thanks a bunch!
Nicely explained Norman. Kudos to you.
James - I suggest you mark that as your accepted solution.
I was going to mark it as solution, and think it is the right answer, but its not working.
I opened the solution for prog1, and edited all the Assemblyinfo.cs files to have:
I commented the file version so it would use the AssyVersion, and I could see in props of file in windows explorer.
I purposefully commented out a particular method I know prog 2 needed before I compiled.
I then compiled, and placed the new files in my regular prog1 folder which is where acad finds them.
It seemed to assign the version info as expected. I verified in explorer.
I then uncommented the method and ran prog2 under debug, and got the method missing error.
I looked at the details to see what dlls were loaded, and it only lists the one from Prog1.
See Pic of one acad listed, and details of one from prog2 folder. The versions are different, but acad never loaded the one from prog2.
That HAH General CS.dll is the helper function that is different between prog1 and prog2.
Did I misunderstand something? I thought the different versioning would make acad load both and use the one prog2 is calling for.
just thought of something. Does acad maybe only look at major version (3rd number) of an assy to decide if its the right one?
The attributes window explorer show are just for public information Product, File, version etc....
The one that matters is AssemblyVersion but unfortunately AutoCAD does not allow strongly named assemblies which is required for the CLR to look at the AssemblVersion.
I have no idea if this would in this situation but if you want reference the assembly of different versions in the same project..
Select reference then in the Properties palette change alias from global to oldversion or whatever
Then in code file instead of a using directive use
extern alias oldversion;
I have no idea if it will work in this situation but that is one way to load multiple versions of same assembly from different locations into same project.
In my previous reply, I mentioned versioning. At the time I just vaguely recall .NET allows different versions of a component lives side by side from my early experience with .NET and had not touched this topics for years. Then I went to a bit study and test last night and here what I can say:
If you want to load the same component with the same assembly file name, namespaces..., but different version, into the same running process (AutoCAD, or other), the assembly has top be strongly signed and installed into GAC.
I did a test as following:
1. create 2 class library projects that has the same output DLL file name, the same namespaces, only differ with their assembly versions (188.8.131.52, and 184.108.40.206). Both projects have a static method doing different things: Add() and Substract().
2. Strongly signed the 2 projects and compile them;
3. Add the 2 DLLs (the file names are the same: "myLib.dll") to GAC with gacutil.exe tool;
4. Create a 2 Acad Addin projects. One of them references to myLib.dll v1.0.0, the other references to MyLib.dll 1.1.0. Note, I needed to point the reference to correct MyLib.dll file, because the MyLib.dll added into GAC does nt show up in "references" dislog box (unless I update the windows registry, which I do not bother). "Copy local" to MyLib.dll should be set to False, but even leaving it to True does not do hurt, because 2 versions of MyLib.dll in the GAC, and any app using them will always try to load them from GAC first anyway.
5. One Acad Addin has a command method ("Test1") that calls Add() in MyLib.dll v1.0.0, the other Acad addin has a command method ("Test2") that calls Substract() in MyLib.dll v1.1.0. Compile each projecys.
6. Start AutoCAD, net load AcadAddin1 and then netload AcadAddin2. execute command "Test1" and Test2". both work as expected: one does the adding and the other does the substracting, obviously from the 2 MyLib.dll versions being loaded into the same AutoCAD process.
Of couse I tried to load the 2 version of MyLib.dll into AutoCAD before strongly signed them and adding them to GAC. It did not work.
If we think it through, it make sense for not strongly signed DLL, the file name determines whether the assembly has been loaded or not, because it is physically stored in file system and can be overwitten by the any file with the same file name, regardless its version, content. While GAC is a special storage for .NET assembly that allows different versions of assembly stay side by side (but must be strongly signed).
So, if you really have to use the same assembly file name with different versions for particular reason, you have to strongly sign them and place them into GAC. which requires admin priviledge to get it done on each computer that may use your application. It may not worth the trouble doing it.
wow, I think the whole ADN team should give you kudos on that research.
I would guess experienced .net people know you must use the GAC, but its not mentioned much in this forum.
Very much appreciated.
You are correct that I do not want to have to "install" my prog1 and 2 with admin.
I support about 60 cad users and update their tools via xcopy methods (robocopy.exe actually).
So I will have to figure out how I do things.
I will likely recompile both progs should I make any library changes.
If I am doing that, I might as well throw both progs in same folder too, no point in keeping separate.
I sure wish really really badly there was a way to do the GAC stuff via script, even if it meant exposing my login password.
I do not have security problems, I have timing problems.
I need to be able to tell users via an email to close acad's when convenient, then run some batch to update their tools.
As is, for admin requiring items, I have to have them close acad's, then run a special script through our remote admin prog from my desk. It interrupts what I am doing.
So solving that would pave the way for using GAC, I know its the right way to do it really.
Public deploy - GAC(Shared among different applications)
Privatley deployed - Placed in directory or sub-directory of application.
It just has to be Strongly named for the CLR to lokk at version number.
You can add Probing paths, Redirective bindings, etc.. inside app.config file(acad.exe.config)-Privately deployed.
You can avoid the GAC but would have to be strongly named and inside of autocad installtion folder.
This might be more of a project structure-maintenece problem instead of trying to load 2 different versions.