none
Different Environment.CurrentDirectory per AppDomain RRS feed

  • Question

  • Hello,

    I'm doing to Cross AppDomain Assembly loading and I want to change my Enviroment.CurrentDirectory to the directory the other assemblies are.

    The issue I'm facing; Changing the Environment.Currentdirectory in one AppDomain will change it for the whole running assembly.

    I read a thread from 2005 that it's not possible to have such things but, I suppose that the great .NetV4.0 has a nice and simple feature to make this possible!


    Regards, MusicDemon
    • Moved by CoolDadTxModerator Monday, October 24, 2011 2:27 AM Not language specific (From:Visual C# Language)
    • Moved by Andrew.Wu Monday, October 24, 2011 9:18 AM (From:Visual C# General)
    Saturday, October 22, 2011 5:36 PM

Answers

  • You need not enforce it. Plugins not following rules shall break and you have no control over it, but the user will know. Just make sure the errors are properly assigned to each faulty component (be it your own component or the plugins).

    If you planned the plugins are to be made commercially instead of homebaked, you may also follow what is done on Java runtime, to blacklist particular version(s) of ill-behaved plugins and preventing them from running. Just make sure you properly announce the reason behind blacklisting in the release notes (See the release note for Java 6 update 29 released recently for example).



    • Edited by cheong00 Monday, October 31, 2011 9:53 AM
    • Marked as answer by Paul Zhou Tuesday, November 8, 2011 7:38 AM
    Monday, October 31, 2011 9:49 AM

All replies

  • No. In Windows environment, the rule is one Environment set per process. Running in .NET won't change the basic rules.

    Instead of that, if you experienced problem in loading assemblies, consider adding the corresponding folder to the PATH environment variable. It might help.

    Monday, October 24, 2011 2:13 AM
  • Hi MusicDemon,

    For your concern, I'm going to help move your post to the Common Language Runtime forum for better support.

    Thanks for your understanding.

    Best Regards,


    Andrew Wu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, October 24, 2011 9:17 AM
  • Monday, October 24, 2011 4:08 PM
    Moderator
  • The problem isn't loading; The problem is that the assemblies that are loaded see the root directory as their own.

    Regards, MusicDemon
    Monday, October 24, 2011 4:45 PM
  • I tried either of them. That property is really only for loading assemblies.
    Regards, MusicDemon
    Monday, October 24, 2011 4:45 PM
  • But that's the way it should work. DLL / ActiveX libraries are expected to read the configuration file and binrary data at the same folder the main EXE is in, or if they're written to support newer system, they should read from ApplicationData special folder. They're never expected to read files in their own folder.

    If you have configuration files that come with the libraries, you should copy them to folders within your reach before loading them.

    If you're willing to accept a much much greater overhead, you can try to go the Unix way, i.e. Multi-process programming. In such way you can have Environment.CurrentDirectory set to different folder as you wish. Apache once have gone that way when first landed Windows platform, but found the overhead too large and not acceptable, and re-coded to use multithread instead here.

    • Edited by cheong00 Tuesday, October 25, 2011 1:41 AM
    • Proposed as answer by Paul Zhou Wednesday, October 26, 2011 7:50 AM
    Tuesday, October 25, 2011 1:38 AM
  • As I  noticed; FireFox has multi-processing as well, right?

     

    Other than that; I suppose that doing so will be quite hard...?


    Regards, MusicDemon
    Wednesday, October 26, 2011 3:30 PM
  • In the case of Firefox, it has chosen the same path as IE, that is to become multiprocess as it needs to be, and for good reason.

    Many a time when browsers loads a buggy plugin, or visit a site that has buggy coded script that leads to infinate loop, the browser has to restart to regain stalibility (note that in the latter case, Firefox includes feature to stop buggy script now). Since the brwoser has to support visit multiple webpages at the same time, it also means at this case, the user will lost multiple session they're using. Of course the brwosers now support automatic recovery of previous browse state, but for many website that has user action attach to session, there's still lost to the user.

    With multiprocessing, now when one browser instance goes buggy, you can choose to just nuke that instance and have other brwoser instance unaffected. Life (as a netizen) is better since then.

    The most difficult step is to perform interprocess communication if those instances has to cooperate to perform tasks. In the browser's case it means to find a way to share session data between the instances with minimal impact to performance without affecting stalibility. The remaining challenge would be mainly on reducing memory usage and so on.

    I'll also note the difference for you consideration. For browsers, most people will keep 5 active at a time, with the total of at most 20 for most sane people. For web servers, ability to support 50 concurrent sessions would be bare minimum, and for those for production purpose have to prepare for above 1,000 in order to qualify. I think you could imagine even if each worker process can handle 50 session requests at the same time, your server's process list could easily flood with that much workers.

    • Edited by cheong00 Thursday, October 27, 2011 1:16 AM
    Thursday, October 27, 2011 1:06 AM
  • So, as for me? I really don't want my loaded assemblies to have the location of the loading assembly.

     

    So I must create an executable that is located inside the loaded assemblies location and that executable does the thing, loading, unloading...

     

    C:\my assembly\loading.exe

    C:\my assembly\privates\toload.dll

    C:\my assembly\privates\loader.exe

     

    Loading will create an instance of loader.exe with the command the load toload. And further? Is this where Serialization comes in scope?

    And how will I do it? I got function calls included.


    Regards, MusicDemon
    • Edited by MusicDemon Thursday, October 27, 2011 8:48 AM
    Thursday, October 27, 2011 8:44 AM
  • This is a interesting topic and I'll find some free time to create a sample project, but this means it could be as late as next week or even later. It's probably not going to be simple, I think.

    I hereby invite others to provide sample solution or links to solve this problem if it's urgent.

    Thursday, October 27, 2011 10:10 AM
  • That would be awesome! :D
    Regards, MusicDemon
    Thursday, October 27, 2011 2:56 PM
  • Why not install the dlls to GAC?

    If you install them to GAC, the problems of directory or folder would be resolved.


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, October 31, 2011 6:09 AM
  • I think he has some static files (configarations, bitmap files, etc.) that come with the DLL but somehow doesn't want to embed them in the library file itself, or the DLL when is not written by MusicDemon is attempting to load files in CurrentDirectory.

    Traditionally when talking about doing that in the Windows way, the most natural idea is to build some out-of-proc COM, or build some kind of "fork + IPC" implementation mix if OO is not required. I'm wonder if things would be easier and/or more efficient when implementing that in .NET.

    I'm not sure I'd be able to make it though, seeing that even Microsoft only be able to create event enabled COM control on .NET v4 to successfully interop with old VB6 applications, enable my ex-company to smoothly migrate from VB6 to .NET module by module. (That's about 10 years from .NET v1) 


    • Edited by cheong00 Monday, October 31, 2011 6:45 AM
    Monday, October 31, 2011 6:31 AM
  • Paul Zhou, I doubt that I could do that. I'm using this for a plug-in system. From 3rd parties. I my opinion it's rather unsafe to do so, not?

    cheong00, it's true about the first paragraph. I don't think that I'll be building all the plug-ins myself. But, just to make it clear; The thing you planned to do failed? Or did I misunderstood?


    Regards, MusicDemon
    Monday, October 31, 2011 8:03 AM
  • Not started. I have to go work on Saturday, and have some debug/RE(i.e.: looking inside binaries I didn't write so as to resolve bugs) tasks on Sunday, so literally no rest for the whole week.

    Btw, if you're developing plugin enabling systems for 3rd party, why don't you follow the way foobar has gone to explicitly spell out the interfaces the plugins have to implement? You can even pass back the plugin's path on some interface so thing will be simpler.


    • Edited by cheong00 Monday, October 31, 2011 8:27 AM
    Monday, October 31, 2011 8:26 AM
  • I want to enforce using Interfaces or Abstract classes... Hmm.. While writing I began thinking... I could make a class from where the plug-ins can read their base location from. The only issue; Every must keep at those rules... As far as I know I can't enforce it.
    Regards, MusicDemon
    Monday, October 31, 2011 8:54 AM
  • You need not enforce it. Plugins not following rules shall break and you have no control over it, but the user will know. Just make sure the errors are properly assigned to each faulty component (be it your own component or the plugins).

    If you planned the plugins are to be made commercially instead of homebaked, you may also follow what is done on Java runtime, to blacklist particular version(s) of ill-behaved plugins and preventing them from running. Just make sure you properly announce the reason behind blacklisting in the release notes (See the release note for Java 6 update 29 released recently for example).



    • Edited by cheong00 Monday, October 31, 2011 9:53 AM
    • Marked as answer by Paul Zhou Tuesday, November 8, 2011 7:38 AM
    Monday, October 31, 2011 9:49 AM
  • What I did:

    Load an assembly

    Check every type

    Load it if it's MarshalByRefObject (optional: and it matches a given type) and has a parameterless constructor

    That's what I mean with forcing.

     

    Anyway, I've made it possible for the host to check the private path of each plug-in, it's only a little bit annoying that I must do it via-via instead of directly...

     

    (I thought I already replied here...)


    Regards, MusicDemon
    • Edited by MusicDemon Tuesday, November 8, 2011 11:52 AM
    Tuesday, November 8, 2011 11:52 AM