Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can a System.Reflection.Assembly.Location be changed? #809

Open
CatGirlsAreLife opened this issue Jul 18, 2018 · 10 comments
Open

Can a System.Reflection.Assembly.Location be changed? #809

CatGirlsAreLife opened this issue Jul 18, 2018 · 10 comments

Comments

@CatGirlsAreLife
Copy link

CatGirlsAreLife commented Jul 18, 2018

So I am loading dll’s from a zip file using this Extension class located here: https://github.com/Elskom/Els_kom_new/blob/master/Els_kom_Core/Classes/AssemblyExtensions.cs

However I am not sure if they way I am loading it if their locations are set properly. I would like it to be \<assembly (or pdb or both) file name>. And if not, if I could manually change it in my method.

With that then one can tell from where exactly the assembly was loaded from in debug mode from the presence of the “.zip” on the path that vs says the filewas loaded from.

Also if desired I made the class friendly to the .NET framework if it is ever wanted or added to the .NET framework/Core. I personally do not mind it being added to it either. Just I wish I could just call it in my code as a static member of System.Reflection.Assembly though. I guess maybe that will happen when c# 8 comes.

Edit: After reading it seems there is a LoadModule method. Would it work in the case of this on this method to set the actual location to the way I want above?
My reasoning for loading dll’s and pdb’s (if enabled in the program ui or when debugging the program itself in vs) is so that the program directory is not cluttered with installed plugins (simply installing them and their debug symbols to a zip or a Plugins folder based upon the user’s personal preference seems like a good idea). And yes on the program I plan to add a sort of plugins form or something for downloading updated plugins / installing & uninstalling them similar to vs extensions where it would require restarting the program to take effect. But if the .NET framework had a way of downloading, updating, installing and updating ‘plugins’ itself to a folder or file (like a zip file or something) by just passing in a url to it that would be nice too and much help as well. Currently I am of thinking things like the following:

  • each plugin has it’s own github repository where each commit is built and deployed as a pre-release until a tag build.
  • user can add a repository to download, install, and update from that is stored in the application settings as ‘sources’ similar to apt on linux does.
  • each release and pre-release can be installed and the latest pre-releases seen as ‘newer’.
  • download the latest release or pre-release build and symbols.
  • Restart application and it loads them.
@AlexGhiondea
Copy link
Contributor

Hi -- I am not sure what exactly you are asking for -- would you mind restating the question?

@CatGirlsAreLife
Copy link
Author

CatGirlsAreLife commented Jul 31, 2018

Basically I want to be able to see things like this for example when running in VS2017:

"path\to\zip\file.zip\someassembly.dll" Symbols Loaded.

basically a way to actually show the path to the assembly and the symbols file on debuggers would be great with my current implementation of loading assemblies from a zip file.

@AlexGhiondea
Copy link
Contributor

You should be able to get the location of the assembly (the dll) by using reflection. The location of the PDB is not really something that Reflection would do. The debugger engines have a lot of heuristic for loading the PDB that matches a given assembly.

Can you tell me more about why you are interested in seeing the pdb location?

@CatGirlsAreLife
Copy link
Author

I was thinking more about the actual dll location. although it would be nice if one could pass in a string to the Load(byte[]) and Load(byte[], byte[]) to fallback on instead of string.Empty on System.Reflection.Assembly.Location. That way I do not have to try to hack a workarround for it. https://github.com/Elskom/ZipAssembly/

But does the current function it calls before it does:

if (location != null)
// some code for directory stuff

return location;

in the property even support files within zips? If it does then I do not have to worry but I load the files and their symbols in the zips from byte arrays.

@AlexGhiondea
Copy link
Contributor

Would you mind sharing some code as to what you are trying to do?

If you want to load an assembly from disk using a file path, you can use the Assembly.LoadFrom(string assemblyFile) method.

I don't think we have a way to directly load an assembly from a zip archive.

@CatGirlsAreLife
Copy link
Author

CatGirlsAreLife commented Aug 3, 2018

Sure, basically I want a way to have my Zip Assembly loader class to somehow override the normal Location property return value in the Assembly instance it creates to instead of being string.Empty because I pass the bytes of the zip entry content to the Load method to instead return like <zip file name passed to my static LoadFromZip method>\<entry path of file to load from zip passed to my static LoadFromZip method>.

The code to that class is located here:
https://github.com/Elskom/ZipAssembly/blob/master/ZipAssembly.cs
and:
https://github.com/Elskom/Els_kom_new/blob/master/Els_kom_Core/Classes/AssemblyExtensions.cs

However both have a lot of hacking, sadly the only way currently to get what I want is to reimplement much of System.Reflection itself which is not the best solution. What we need is some way to do the original work, check if someone registered some special things to do instead (if loaded from byte arrays) of the original behavior. Maybe like some sort of way to pass in the override string to return somehow whenever getting the location of an assembly instance loaded with my zip loader.

In one of them I derive from assembly but if I did so would it overwrite the normal behavior on Assemblies not loaded from a zip file?

Maybe it is possible that when loading from any of the Load(byte[][, *, *]) functions that it sets some bool to true that then the implemented Location property checks if true then if it is invoke a user defined event (if defined) that passes a event args class or something that someone can set with the path string the event wants to return, then return that string from the Location property. That way the event is set per instance if it is needed to be defined and invoked. Then this code could work with a lot less hacks to the open parts of the .NET framework that cannot be compiled by anyone to test changes on their end. Oh how I wish I could test changes I make to the .NET framework to see if they would be practical to do/add there.

Sorry for the hard links, I cannot use the good backtick code block that I can specify language for syntax highlighting on my iPhone 5s. Also the first link I plan to have it in a class library of itself relating to it all, and the second link I would use that class library as a dependency and then remove that file there. However this change needs to happen I think somehow.

@AlexGhiondea
Copy link
Contributor

Thanks for the additional information. Do you have a hard requirement to return an object that is of type Assembly? Or can you return your type that encapsulates the assembly?

Do you have a sample of how your code is going to be used?

@CatGirlsAreLife
Copy link
Author

CatGirlsAreLife commented Aug 16, 2018

I would like to return Assembly yes, and the code is used specifically for loading plugins. I tested the loader class I got so far in my code and it loads the assembly fine from a zip file.

The plugin loader is located here: https://github.com/Elskom/Els_kom_new/blob/master/Els_kom_Core/Classes/GenericPluginLoader.cs

@AlexGhiondea
Copy link
Contributor

Thanks -- so the issue you are seeing now is that you don't have a way to overwrite the location of the assembly object once you load it.

I think the current behavior is by-design. You can file an issue in the CoreFx repo to change this behavior, but due to compatibility reasons that might not be something we can do.

@katherinebai
Copy link

katherinebai commented Oct 17, 2022

How could I set Assembly Location when load assembly from bytes array? Because I need find some resources(icon, etc).
And I don't want to save Assembly to file firstly and then to load it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants