Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/131.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用清单的DLL重定向_C++_Windows_Dll_Manifest - Fatal编程技术网

C++ 使用清单的DLL重定向

C++ 使用清单的DLL重定向,c++,windows,dll,manifest,C++,Windows,Dll,Manifest,我需要可靠地重定向特定DLL的应用程序查找。使用app.exe.local方法不起作用,因为如果应用程序具有清单(嵌入或单独的文件),则会忽略本地文件。因此,我试图通过在清单中将DLL定义为私有程序集来执行DLL重定向 我有一个测试应用程序LoadDll.exe,它只调用 LoadLibrary("C:\\EmptyDll.dll"); LoadDll.exe具有清单(作为单独的文件LoadDll.exe.manifest) 包含LoadDll.exe(不是c:\)的应用程序文件夹包含带有

我需要可靠地重定向特定DLL的应用程序查找。使用app.exe.local方法不起作用,因为如果应用程序具有清单(嵌入或单独的文件),则会忽略本地文件。因此,我试图通过在清单中将DLL定义为私有程序集来执行DLL重定向

我有一个测试应用程序LoadDll.exe,它只调用

LoadLibrary("C:\\EmptyDll.dll");
LoadDll.exe具有清单(作为单独的文件LoadDll.exe.manifest)


包含LoadDll.exe(不是c:\)的应用程序文件夹包含带有嵌入清单的EmptyDll.dll

<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<assemblyIdentity
      type="win32"
      name="EmptyDll"
   version="1.0.0.1"
      processorArchitecture="x86"
    />    
</assembly>

但是,LoadDll.exe会继续加载C:\EmptyDll.dll,而不是应用程序文件夹中的EmptyDll.dll

如果您破坏任一清单(例如更改EmptyDll.dll清单标识中的版本号),LoadDll.exe不会加载,因此windows正在读取和处理清单文件,但只是忽略了这些文件

有人有什么想法吗

谢谢


托比

好的,你需要这样设置:

  • c:\apppath\testapp.exe
    -您的测试应用程序exe文件
  • c:\apppath\testapp.exe.manifest
    -可能嵌入的应用程序清单文件
  • c:\apppath\EmptyAssm\EmptyAssm.manifest
    -描述新程序集的清单
  • c:\apppath\EmptyAssm\empty.dll
    -程序集dll
  • c:\apppath\EmptyAssm\empty.dll.2.manifest
    -dll中嵌入的清单
因此,您的测试应用程序包含一个应用程序清单:其中包含应用程序的依赖程序集引用,包括添加到自定义dll程序集的引用

在应用程序文件夹的应用程序文件夹assm子文件夹中,有“EmptyAsm”程序集的程序集清单,其中包含引用实际dll“empty.dll”的文件节点

empty.dll嵌入自己的清单,其中包含它所需的任何公共或私有程序集上的依赖程序集引用

这是重要的一点:“EmptyAsm”程序集清单和“empty”dll清单可能不同。不能嵌入(“EmptyAsm”)程序集的清单文件,但如果选择按dll名称命名清单,则可能会共享dll清单名称

现在,当加载程序加载您的EXE时,它将加载您的EXE清单并将其添加到激活上下文中。处理EXE的导入表或调用LoadLibrary时,加载程序首先在激活上下文中搜索具有匹配文件节点的程序集清单。如果找到匹配的程序集,则从程序集位置(包含assemblies.manifest的文件夹)处理并加载dll。此时,如果dll中没有嵌入清单,并且dll和清单具有相同的名称,则可以重用相同的清单文件来设置dll的激活上下文

如果要将“EmptyAsm”清单和dll放在应用程序文件夹的其他文件夹中,并且目标是Windows Server 2008、Windows 7或更高版本,则可以为应用程序添加配置文件:-

  • c:\apppath\testapp.exe.config
    -应用程序配置文件
app config文件可以在
assemblyBinding
节点下包含一个探测节点(配置文件看起来很像清单文件),带有
privatePath=“some relative path”
。在这种情况下,将在相对文件夹中搜索程序集


我在这里的最后一个响应包含示例文件,其中介绍了从dll创建程序集并从exe引用程序集的过程:-


我想澄清一下: win32程序集是(最简单的)描述程序集的清单文件和dll。 在此模型中,它们始终位于同一文件夹中,因此清单的文件节点根本不能包含任何路径信息—仅包含dll的名称

程序集可以共享—方法是为它们提供一个强版本(和一些数字签名),并将它们安装在Windows\WinSxS或private中

Windows 5.1之前的版本(Win XP)根本不会搜索程序集,因为这项技术只是在XP中添加的。 Windows 5.1至6.0(XP和Vista)将仅在具有活动激活上下文的对象文件夹中搜索专用程序集:-如果某个exe引用某个程序集,则包含该exe的文件夹。如果dll中的代码引用程序集,则会搜索dll的文件夹

如果要将dll存储在多个应用程序共享的专用位置(例如),则必须满足Windows 7或更高版本的要求:-

Windows 6.1版(也称为Windows Server 2008或Windows 7)及更高版本将在模块文件夹之外,搜索指定为应用程序配置文件中探测元素的privatePath元素的路径。 应用程序配置文件始终与exe或dll位于同一文件夹中,并命名为:

.exe.config
.dll.2.config


(使用.2.的原因是可能有大量清单和配置嵌入为资源,加载程序保留资源id的1…15。在磁盘上搜索配置文件的清单时,如果嵌入资源的资源id为1,则该id将被忽略,但任何其他数字表示它将成为文件名的一部分).

您可以使用包装
LoadLibrary
来解决此问题。
LoadLibrary包装器将能够识别加载DLL的尝试并适当重写路径。

因此,似乎不可能使用清单将调用重定向到具有绝对路径的LoadLibrary

在对清单进行了大量的处理之后,似乎一旦您克服了所有糟糕的文档清单,它实际上是非常简单的

基本上,当加载可执行文件时,windows会收集链接到u的所有相关清单
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<assemblyIdentity
      type="win32"
      name="EmptyDll"
   version="1.0.0.1"
      processorArchitecture="x86"
    />    
</assembly>
'name attribute of file element' -> 'absolute path of manifest file' + 'name attribute of file element'