;;; Adds additional paths to the search-path used by the ;;; assembly-loader; so that e.g. (load-assembly x) will search for x ;;; not only in the system and application directories, but also in ;;; every directory in *additional-assembly-directories* ;;; ;;; Example: ;;; RDNZL-USER 3 > (load-assembly "AproposGui") ;;; Warning: Returning NULL object from .NET call ;;, NIL ;;; RDNZL-USER 4 > (pushnew (translate-logical-pathname #P"rdnzl:examples;") ;;; *additional-assembly-directories*) ;;; RDNZL-USER 5 > (install-assembly-resolve-handler) ;;; # ;;; RDNZL-USER 6 > (load-assembly "AproposGui") ;;; # ;;; ;;; Alternative method of loading an assembly that doesn't lock the ;;; assembly file: ;;; byte[] asm = File.ReadAllBytes(asmPath); ;;; return Assembly.Load(asm); (in-package :rdnzl-user) (defparameter *additional-assembly-directories* nil) (defun assembly-resolver (app-domain resolve-event-args) (declare (ignore app-domain)) (let ((assembly-name (property resolve-event-args "Name"))) (loop with filename = (make-pathname :name assembly-name :type "dll") for dir in *additional-assembly-directories* for dirpath = (if (pathnamep dir) dir (parse-namestring dir)) for path = (merge-pathnames dirpath filename) when (probe-file path) do (let* ((evidence (property (invoke "System.Reflection.Assembly" "GetExecutingAssembly") "Evidence")) (assembly (invoke "System.Reflection.Assembly" "LoadFile" (namestring path) evidence))) (return-from assembly-resolver assembly)) finally (return (make-null-object "System.Reflection.Assembly"))))) (defun install-assembly-resolve-handler (&optional (handler #'assembly-resolver)) (let ((my-domain (property "System.AppDomain" "CurrentDomain")) (assembly-resolve-delegate (new "System.ResolveEventHandler" handler))) (prog1 assembly-resolve-delegate (invoke my-domain "add_AssemblyResolve" assembly-resolve-delegate)))) (defun uninstall-assembly-resolve-handler (handler) (invoke (property "System.AppDomain" "CurrentDomain") "remove_AssemblyResolve" handler))