Me refiero a la segunda opción, tengo el exe en una carpeta y la dll en otro
Bueno. Como ya te mencioné por privado, puedes crear un enlace simbólico (SymLink o también llamado SoftLink) con la herramienta
mklink.exe de Microsoft:
Sintaxis que debes usar:
MkLink.exe "C:\Enlace Destino.dll" "C:\Archivo Origen.dll"
Esto creará una especie de acceso directo de "cero" bytes con el que no tendrás problemas para cargar el archivo de origen en tu aplicación. Logicamente debes asignarle el mismo nombre al archivo simbólico que el nombre original de tu librería.dll.
Esta es la opción que más te recomiendo bajo mi criterio. Te permite mantener la misma estructura de archivos (reemplazando el archivo original por otro archivo "fantasma" y funcional), el resultado no ocupa nada de espacio, y no supone ningún impacto negativo en el rendimiento del S.O. Solamente el archivo simbólico y tú, tú y el archivo simbólico
.
Si quieres crear el enlace de forma programática desde .NET, puedes utilizar la función Win32
CreateSymbolicLink:
Aqui tienes un ejemplo de uso y definiciones para VB.NET (de mi framework
ElektroKit que puedes encontrar a la venta en CodeCanyon):
NativeMethods.
CreateSymbolicLink("C:\Destination Link.ext",
"C:\Source File.ext", NativeEnums.
SymbolicLinkFlags.
File)
<SuppressUnmanagedCodeSecurity>
Public NotInheritable Class NativeMethods
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Creates a symbolic link.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa363866%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
''' <param name="dstFilePath">
''' The path of the symbolic link to be created.
''' </param>
'''
''' <param name="srcFilePath">
''' The path of the target for the symbolic link to be created.
''' <para></para>
''' If <paramref name="srcFilePath"/> has a device name associated with it,
''' the link is treated as an absolute link;
''' otherwise, the link is treated as a relative link.
''' </param>
'''
''' <param name="flags">
''' Indicates whether the link target is a file or is a directory.
''' </param>
''' ----------------------------------------------------------------------------------------------------
''' <returns>
''' If the function succeeds, the return value is <see langword="True"/>.
''' <para></para>
''' If the function fails, the return value is <see langword="False"/>.
''' <para></para>
''' To get extended error information, call <see cref="Marshal.GetLastWin32Error"/>.
''' <para></para>
''' </returns>
''' ----------------------------------------------------------------------------------------------------
<SuppressMessage("Microsoft.Interoperability", "CA1401:PInvokesShouldNotBeVisible", Justification:="Visible for API")>
<DllImport("Kernel32.dll", SetLastError:=True)>
Public Shared Function CreateSymbolicLink(ByVal dstFilePath As String,
ByVal srcFilePath As String,
<MarshalAs(UnmanagedType.I4)> ByVal flags As NativeEnums.SymbolicLinkFlags
) As <MarshalAs(UnmanagedType.I1)> Boolean
End Function
''' <summary>
''' Prevents a default instance of the <see cref="NativeMethods"/> class from being created.
''' </summary>
Private Sub New()
End Sub
End Class
Public NotInheritable Class NativeEnums
''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Indicates whether a symbolic link is a file or is a directory.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
''' <remarks>
''' <see href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa363866%28v=vs.85%29.aspx"/>
''' </remarks>
''' ----------------------------------------------------------------------------------------------------
Public Enum SymbolicLinkFlags As Integer
''' <summary>
''' The link target is a file.
''' </summary>
''' <summary>
''' The link target is a directory.
''' </summary>
Directory = &H1
End Enum
''' <summary>
''' Prevents a default instance of the <see cref="NativeEnums"/> class from being created.
''' </summary>
Private Sub New()
End Sub
End Class
Nota: Recuerda que esta función de la API de Windows, como muchas otras, tiene una versión ANSI y otra Unicode (
CreateSymbolicLinkA,
CreateSymbolicLinkW) en caso de que necesites usar alguna en específico por el motivo que sea.
Lo que te comentó por encima el compañero @
NEBIRE, consistiría en colocar el archivo.dll en uno de los directorios en el que el sistema operativo intentará buscar de forma automática las dependencias de tu executable. Es otra buena opción, pero yo lo recomendaría en otro tipo de circunstancias. Al estar hablando de una aplicación administrada, el cargador de dependencias de .NET lo más probable es que te diese problemas al intentar resolver la ubicación de una dependencia administrada que esté ubicada fuera del directorio de inicio de tu app, aunque la coloques en el directorio del sistema. Si descartas la opción de crear un enlace simbólico, entonces en lugar de esto lo que deberías hacer es registrar la dependencia en el GAC de Windows, pero bueno, te explicaré esta metodología por si quieres probar a ver si en tus circunstancias te funciona bien... o simplemente para que sepas algo más.
El orden de búsqueda de dependencias para aplicaciones de escritorio es el siguiente (el orden variará en el caso de que tengas activado el valor de registro
SafeDllSearch):
- 1. El directorio de inicio de la aplicación {startup dir}. Donde está alojada la aplicación.
- 2. El directorio de trabajo actual de la aplicación {working dir}.
- 3. Los directorios de sistema de 32 y 64 Bits.
C:\Windows\SysWOW64\
C:\Windows\System32\
- 4. El directorio de sistema de 16 Bits.
C:\Windows\System\
- 5. El directorio de Windows
C:\Windows\
- 6. Los directorios que estén listados en las variables de entorno PATH.
HKCU\Environment PATH
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment PATH
En la MSDN tienes toda la info que necesites conocer al respecto (para variar):
¡Saludos!