tft每日頭條

 > 生活

 > dll注冊命令是什麼

dll注冊命令是什麼

生活 更新时间:2025-03-01 12:09:37

dll注冊命令是什麼?如果你是一個程序員就會知道,編程都是需要使用函數庫(library)或類庫的,也就是說,通常庫是程序的有機部分,可以靜态鍊接(.lib,在使用.lib之前,要在程序源代碼中引用lib對應的頭文件.h并在編譯時直接加到源文件中)或動态鍊接(DLL,Dynamic Linked Library,程序運行時加載)成為程序的一部分,我來為大家科普一下關于dll注冊命令是什麼?下面希望有你要的答案,我們一起來看看吧!

dll注冊命令是什麼(DLL基本原理及為何需要注冊)1

dll注冊命令是什麼

1 程序的模塊化

如果你是一個程序員就會知道,編程都是需要使用函數庫(library)或類庫的,也就是說,通常庫是程序的有機部分,可以靜态鍊接(.lib,在使用.lib之前,要在程序源代碼中引用lib對應的頭文件.h并在編譯時直接加到源文件中)或動态鍊接(DLL,Dynamic Linked Library,程序運行時加載)成為程序的一部分。

在windows中,許多應用程序并不是一個完整的可執行文件,它們被分割成一些相對獨立的動态鍊接庫,即DLL文件,放置于系統中。當我們執行某一個程序時,相應的DLL文件就會被調用。一個應用程序可使用多個DLL文件,一個DLL文件也可能被不同的應用程序使用,這樣的DLL文件被稱為共享DLL文件。如在 Windows操作系統中,每個程序都可以使用該 DLL 中包含的功能來實現“打開”對話框。這有助于促進代碼重用和内存的有效使用。

通過使用 DLL,程序可以實現模塊化,由相對獨立的組件組成。

MS把所有的API函數是放在幾個大的*.LIB中,另外還提供一對應的幾個*.inc,實際上它如同*.h頭文件,起到聲明API函數的目的。

DLL是Dynamic Link Library的縮寫,意為動态鍊接庫。在Windows中,許多應用程序并不是一個完整的可執行文件,它們被分割成一些相對獨立的動态鍊接庫,即DLL文件,放置于系統中。當我們執行某一個程序時,相應的DLL文件就會被調用。一個應用程序可有多個DLL文件,一個DLL文件也可能被幾個應用程序所共用,這樣的DLL文件被稱為共享DLL文件。DLL文件一般被存放在C:\\Windows\\System目錄下。

DLL文件中存放的是各類程序的函數(子過程)實現過程,當程序需要調用函數時需要先載入DLL,然後取得函數的地址,最後進行調用。使用DLL文件的好處是程序不需要在運行之初加載所有代碼,隻有在程序需要某個函數的時候才從DLL中取出。另外,使用DLL文件還可以減小程序的體積。

Windows系統平台上,你可以将獨立的程序模塊創建為較小的DLL(Dynamic Linkable Library)文件,并可對它們單獨編譯和測試。在運行時,隻有當EXE程序确實要調用這些DLL模塊的情況下,系統才會将它們裝載到内存空間中。這種方式不僅減少了EXE文件的大小和對内存空間的需求,而且使這些DLL模塊可以同時被多個應用程序使用。Microsoft Windows自己就将一些主要的系統功能以DLL模塊的形式實現。例如IE中的一些基本功能就是由DLL文件實現的,它可以被其它應用程序調用和集成。一般來說,DLL是一種磁盤文件(通常帶有DLL擴展名,是标準win32可執行文件-“PE”格式),它由全局數據、服務函數和資源組成,在運行時被系統加載到進程的虛拟空間中,成為調用進程的一部分,進程中所有線程都可以調用其中的函數。如果與其它DLL之間沒有沖突,該文件通常映射到進程虛拟空間的同一地址上。DLL模塊中包含各種導出函數,用于向外界提供服務。Windows在加載DLL模塊時将進程函數調用與DLL文件的導出函數相匹配。

系統的組策略和注冊表中,我們可以修改一些鍵值來優化我們的系統,并加強操作系統的安全性。可是,對于限制下載、禁止删除文件等功能,我們無法通過上述的操作來完成,這隻有通過修改系統DLL文件來實現。目前,我們通過修改系統的DLL文件,可以實現禁止删除文件、禁止IE下載、禁止IE另存為、禁止文件打開方式等功能。

2 為什麼要用DLL

DLL為什麼封裝成函數,就能成為系統中大量使用DLL的理由呢?

① 擴展應用程序

由于DLL能被應用程序動态載入内存。所以,應用程序可以在需要時才将DLL載入到内存中,這讓程序的可維護性變得很高。比如QQ的視頻功能需要升級,那麼負責編寫QQ的程序員不必将QQ所有代碼都重寫,隻需将視頻功能相關的DLL文件重寫即可。

② 便于程序員合作

這個和最終用戶關系不大,僅供了解。大家都知道編程工具有很多,比如VB、VC、Delphi等,如果好幾個人合作來編寫一個大的程序,那麼可能有的人用VB,有的人用VC,每人負責的部分所使用的編程語言都不同,究竟放在哪個編譯器中進行編譯呢?這就好比一群來自各個國家的人在共同編寫一篇文章,如果他們所使用的語言都不同,寫出來的文章怎麼可能湊到一起呢?而有了DLL後,可以讓VC程序員寫一個DLL,然後VB程序員在程序中調用,無需為怎麼将它們都編譯為一個單獨的EXE而發愁了。

③ 節省内存

如果多個應用程序調用的是同一個動态鍊接庫,那麼這個DLL文件不會被重複多次裝入内存中,而是由這些應用程序共享同一個已載入内存的DLL。就好比一個辦公室中,很少會為每一個員工配置一台飲水機的,而是在一個公共位置放上一個飲水機,所有需要喝水的職員都可以共用這台飲水機,降低了成本又節約了空間。

④ 共享程序資源

包括剛才提到過的通用文件對話框在内,DLL文件提供了應用程序間共享資源的可能。資源可以是程序對話框、字符串、圖标,或者聲音文件等。

⑤ 解決應用程序本地化問題

在下載了某個程序的漢化包後,打開漢化說明,經常可以看到用下載包中的DLL文件覆蓋掉程序原來的DLL,漢化就完成了。這些程序都是将執行代碼和應用程序界面分開編寫了,所以漢化者隻需簡單地将其中和程序界面相關的DLL漢化并發布即可。

3 隐式鍊接和顯式鍊接

應用程序導入函數與DLL文件中的導出函數進行鍊接有兩種方式:隐式鍊接和顯式鍊接。

隐式鍊接(load-time dynamic linking)是指在應用程序中不需指明DLL文件的實際存儲路徑,程序員不需關心DLL文件的實際裝載(由編譯器自動完成地址分配)。采用隐式鍊接方式,程序員在建立一個DLL文件時,鍊接程序會自動生成一個與之對應的LIB導入文件。該文件包含了每一個DLL導出函數的符号名和可選的标識号,但是并不含有實際的代碼。LIB文件作為DLL的替代文件被編譯到應用程序項目中。當程序員通過靜态鍊接方式編譯生成應用程序時,應用程序中的調用函數與LIB文件中導出符号相匹配,這些符号或标識号進入到生成的EXE文件中。LIB文件中也包含了對應的DLL文件名(但不是完全的路徑名),鍊接程序将其存儲在EXE文件内部。當應用程序運行過程中需要加載DLL文件時,Windows根據這些信息發現并加載DLL,然後通過符号名或标識号實現對DLL函數的動态鍊接。我們使用的大部分系統Dll就是通過這樣的方式鍊接的。若找不到需要的Dll則會給出一個Dll缺少的錯誤消息。

顯式鍊接(run-time dynamic linking)與此相反。用戶程序在編譯的時候并沒有指明需要哪些Dll,而是在運行起來之後調用Win32 的LoadLibary()函數,去裝載Dll。若沒有找到Dll則這個函數就會返回一個錯誤。在用LoadLibary()函數裝載Dll之後,應用程序還需要用GetProcAdress()函數去獲得Dll輸出函數的地址。顯式鍊接方式對于集成化的開發語言比較适合。有了顯式鍊接,程序員就不必再使用導入文件,而是直接調用Win32 的LoadLibary()函數,并指定DLL的路徑作為參數。還要說明一點的就是Known Dlls就是保證在通過LoadLibary()去裝載系統Dll的時候,隻從特定的系統目錄去裝載,防止裝載錯。裝載的時候會去看注冊表下是否有一樣的注冊表鍵名。

應用程序怎樣找到DLL文件

如果應用程序使用LoadLibrary顯式鍊接,那麼在這個函數的參數中可以指定DLL文件的完整路徑。如果不指定路徑,或是進行隐式鍊接,Windows将遵循下面的搜索順序來定位DLL:

I 包含EXE文件的目錄,

II 進程的當前工作目錄,

III Windows系統目錄,

IV Windows目錄,

V 列在Path環境變量中的一系列目錄。

在Windows上有個注冊表鍵值決定了Dll的搜索順序:HKLM\System\CurrentControlSet\SessionManager\SafeDllSearchMode。在windows 7,server2003,xp sp2中這個值為1,在xp,2000 sp4中為0。

1值時的搜素順序為:1.可執行文件所在目錄,2.系統目錄windows\system32\,3. 16位系統目錄,4.windows目錄,5.當前進程目錄。6.環境變量PATH中的目錄。

0值時的搜素順序為:1.可執行文件所在目錄,2. 當前進程目錄。3.系統目錄windows\system32\,4. 16位系統目錄,5.windows目錄,6.環境變量PATH中的目錄。

4 DLL的加載與連接

Windows DLL裝入(除ntdll.dll外)和連接是通過ntdll.dll中一個函數LdrInitializeThunk實現的。先對LdrInitializeThunk()這個函數名作些解釋“Ldr顯然是“Loader”的縮寫。而“Thunk”意為“翻譯”、“轉換”、或者某種起着“橋梁”作用的東西。這個詞在一般的字典中是查不到的,但卻是個常見于微軟的資料、文檔中術語。這個術語起源于編譯技術,表示一小片旨在獲取某個地址的代碼,最初用于函數調用時“形參”和“實參”結合。後來這個術語有了不少新的特殊含義和使用,但是DLL的動态連接與函數調用時“形實結合”确實有着本質的相似。

DLL文件中包含一個導出函數表。這些導出函數由它們的符号名和稱為标識号的整數與外界聯系起來。函數表中還包含了DLL中函數的地址。當應用程序加載DLL模塊時時,它并不知道調用函數的實際地址,但它知道函數的符号名和标識号。動态鍊接過程在加載的DLL模塊時動态建立一個函數調用與函數地址的對應表。如果重新編譯和重建DLL文件,并不需要修改應用程序,除非你改變了導出函數的符号名和參數序列。

5 DLL注冊及為什麼需要注冊?

在系統故障中,有很多都是由于DLL文件丢失、損壞或沒有注冊造成的,比如Windows XP的壓縮文件夾功能出現故障就很有可能是系統目錄中的zipfldr.dll沒有注冊造成的,這類故障的解決方法也大多是下載一個對應的DLL并運行如下命令:

for%1 in (%windir%\system32\*.dll)do regsvr32.exe /s %1

很多人不理解為什麼要這麼做,是不是所有的DLL都能這樣做呢?

其實系統中有兩種DLL,一種是不需注冊即可使用的,另一種則是必須經過注冊才能使用的。就好像一個臨時工,和一個記錄在員工名單上的長期合同工的區别一樣。如何才能區分這兩種DLL呢?方法很簡單,可以用一個工具(如 Dependency Walker)打開這個DLL,看函數輸出表,如果其中包含以下兩個函數(前者是注冊DLL,後者是反注冊DLL),那麼就一定是需要注冊才能使用的DLL了。

DllRegisterServer

DllUnregisterServer

而regsvr32這個命令,實際上就是調用DLL中的這兩個函數(“regsvr32 /u DLL文件名”調用的即為DllUnregisterServer反注冊函數)。

注冊與不注冊,.dll文件都在system32下面。不同的是,注冊了會在注冊表中有相應信息,同時載入到了dll緩存,沒有注冊信息和進緩存就不能使用(開機時操作系統的一些核心功能再加載到了内存,并開始在後台運行,程序、數據、模塊都需要進入内存才能被訪問。)。

文件注冊前和注冊後都沒有變化,隻是通過命令把相應的信息添加到了注冊表中。

注冊文件的命令行是 regsrv32

regsrv32 xxx.dll regsrv32 xxx.dll /u regsvr32 [/u] [/s] [/n] [/i[:cmdline]] dllname 參數說明: /u - 解除服務器注冊 /s - 無聲;不顯示消息框 /i - 調用 DllInstall,給其傳遞一個可選 [cmdline];跟 /u 一起使用時,卸載 dll /n - 不要調用 DllRegisterServer;這個選項必須跟 /i 一起使用

-End-

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2025 - www.tftnews.com All Rights Reserved