在記憶體中裝載並執行程式或程式集
最近單位一直很忙很忙,前段時間也忙著寫些公司申請專利相關的文件,並整合通用MIS框架,所以沒有太多閒暇寫自己的部落格。今天又看了看反射的東西,忽然發現Assembly類的內容真是豐富啊!!而且,發現了之前我並沒有過多關注的方法,但是,卻是非常的實用和強大!我們以一個示例來闡述之。
眾所周知,副檔名為EXE的檔案在Windows下為二進位制可執行檔案,一旦這個可執行檔案處於執行狀態,作業系統會把這個二進位制檔案對映到記憶體中去,並將其加以鎖定。一般情況下,包括作業系統在內的任何程式都無法將這個處於執行狀態的可執行檔案移動、更名或刪除。不過,在.Net下利用Assembly類,我們對此就有了完美的解決方案。我們可以在記憶體中裝載程式集並執行之,而好處就是我們可以隨意移動、更名和刪除這個處於執行中的程式或程式集檔案。當然,該解決方案僅針對.Net程式或程式集。
示例方案中有兩個窗體程式,WindowsFormsApplication1.exe 和 WindowsFormsApplication2.exe,第一個程式的窗體上會有個button,用於在記憶體中裝載第二個程式,當第二個程式的主窗體顯示後,我們便可以輕鬆的將 WindowsFormsApplication2.exe 移動、更名和刪除,Windows 根本不會提示什麼"檔案正在使用,無法...."之類的提示了。
首先,為了動態的在記憶體中裝載程式或程式集,我們以檔案流的方式讀取二進位制檔案,並將其以位元組的形式儲存在陣列中,程式碼如下:
FileStream fs = new FileStream(Application.StartupPath+
"\\WindowsFormsApplication2.exe", FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length));
fs.Close();
br.Close();
然後,利用 Assembly 類的 Load 過載方法,以陣列的形式載入該程式集。程式碼如下:
Assembly a = Assembly.Load(bin);
隨後我們需要獲得程式集的入口點,並將其以 MethodInfo 型別儲存下來,程式碼如下:
method = a.EntryPoint; //獲得記憶體中可執行檔案的入口點
C++程式設計師都清楚,所謂程式入口點其實就是main函式的記憶體地址,有了程式的main方法的地址,我們只要呼叫即可了。程式碼如下:
if (method != null)
{
method.Invoke(null, null);
}
上述程式碼編譯時會100%正確,但是程式執行到 method.Invoke(null, null); 時會出現異常,經過反覆測試後發現,我們必須在一個新的執行緒上來執行對main方法的呼叫!
System.Threading.Thread thd;
System.Threading.ThreadStart ts; //線上程上執行特定的方法
ts = new System.Threading.ThreadStart(RunNewApp);
thd = new System.Threading.Thread(ts);
thd.Start();
詳細程式碼參見示例程式。該示例在Windows XP3 + Visual Studio 2008 SP1 下編譯除錯透過。
眾所周知,副檔名為EXE的檔案在Windows下為二進位制可執行檔案,一旦這個可執行檔案處於執行狀態,作業系統會把這個二進位制檔案對映到記憶體中去,並將其加以鎖定。一般情況下,包括作業系統在內的任何程式都無法將這個處於執行狀態的可執行檔案移動、更名或刪除。不過,在.Net下利用Assembly類,我們對此就有了完美的解決方案。我們可以在記憶體中裝載程式集並執行之,而好處就是我們可以隨意移動、更名和刪除這個處於執行中的程式或程式集檔案。當然,該解決方案僅針對.Net程式或程式集。
示例方案中有兩個窗體程式,WindowsFormsApplication1.exe 和 WindowsFormsApplication2.exe,第一個程式的窗體上會有個button,用於在記憶體中裝載第二個程式,當第二個程式的主窗體顯示後,我們便可以輕鬆的將 WindowsFormsApplication2.exe 移動、更名和刪除,Windows 根本不會提示什麼"檔案正在使用,無法...."之類的提示了。
首先,為了動態的在記憶體中裝載程式或程式集,我們以檔案流的方式讀取二進位制檔案,並將其以位元組的形式儲存在陣列中,程式碼如下:
FileStream fs = new FileStream(Application.StartupPath+
"\\WindowsFormsApplication2.exe", FileMode.Open);
BinaryReader br = new BinaryReader(fs);
byte[] bin = br.ReadBytes(Convert.ToInt32(fs.Length));
fs.Close();
br.Close();
然後,利用 Assembly 類的 Load 過載方法,以陣列的形式載入該程式集。程式碼如下:
Assembly a = Assembly.Load(bin);
隨後我們需要獲得程式集的入口點,並將其以 MethodInfo 型別儲存下來,程式碼如下:
method = a.EntryPoint; //獲得記憶體中可執行檔案的入口點
C++程式設計師都清楚,所謂程式入口點其實就是main函式的記憶體地址,有了程式的main方法的地址,我們只要呼叫即可了。程式碼如下:
if (method != null)
{
method.Invoke(null, null);
}
上述程式碼編譯時會100%正確,但是程式執行到 method.Invoke(null, null); 時會出現異常,經過反覆測試後發現,我們必須在一個新的執行緒上來執行對main方法的呼叫!
System.Threading.Thread thd;
System.Threading.ThreadStart ts; //線上程上執行特定的方法
ts = new System.Threading.ThreadStart(RunNewApp);
thd = new System.Threading.Thread(ts);
thd.Start();
詳細程式碼參見示例程式。該示例在Windows XP3 + Visual Studio 2008 SP1 下編譯除錯透過。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/14325734/viewspace-573385/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 程式執行過程中的記憶體活動記憶體
- Java程式執行記憶體機制Java記憶體
- 記憶體池、程式池、執行緒池記憶體執行緒
- Linux上執行記憶體中的指令碼和程式Linux記憶體指令碼
- Java中記憶體中的Heap、Stack與程式執行的關係Java記憶體
- 程式執行過程記憶體分析詳解記憶體
- C程式執行時記憶體結構分析C程式記憶體
- 在oracle 叢集多例項中執行並行操作Oracle並行
- 程式執行時的記憶體空間分佈記憶體
- 圖解JVM記憶體模型及JAVA程式執行原理圖解JVM記憶體模型Java
- 在LINUX下編寫程式並執行Linux
- 通過 HelloWorld 瞭解 Java 程式執行過程以及執行時記憶體Java記憶體
- 關於在DOS下可執行檔案中裝入或執行一些程式 (2千字)
- 在終端中執行 Swift 程式Swift
- Java 執行過程中的記憶體模型Java記憶體模型
- 剖析記憶體中的程式之祕記憶體
- PHP 獲取程式碼執行時間和消耗的記憶體PHP記憶體
- 共享記憶體對映(linux程式與執行緒學習筆記)記憶體Linux執行緒筆記
- Java應用程式中的記憶體洩漏及記憶體管理Java記憶體
- Java程式碼執行記憶體溢位詳解及解決方案Java記憶體溢位
- 關於C、Java、Python程式執行耗時及記憶體用量JavaPython記憶體
- 在Docker中執行SpringBoot程式DockerSpring Boot
- Java在不同執行緒中執行程式碼Java執行緒行程
- 在共享記憶體中進行執行緒間的同步是確保多執行緒程式正確執行的關鍵,以下是幾種常見的方法記憶體執行緒
- Java 執行緒記憶體模型Java執行緒記憶體模型
- 設定SQLserver執行記憶體SQLServer記憶體
- Spark程式碼在叢集上執行過程理解Spark
- 程式的記憶體模型記憶體模型
- 序列SPI NOR快閃記憶體VS並行NOR快閃記憶體記憶體並行
- 小程式記憶體問題–圖片懶載入記憶體
- 第二十篇:在子程式中裝載新的程式
- PHP獲取程式碼段執行的毫秒時間和消耗記憶體PHP記憶體
- 測量Linux程式執行時間和佔用記憶體的方法Linux記憶體
- 監控 Python 記憶體使用情況和程式碼執行時間!Python記憶體
- 其他資訊: 混合模式程式集是針對“v2.0.50727”版的執行時生成的,在沒有配置其他資訊的情況下,無法在 4.0 執行時中載入該程式集模式
- 在html檔案中執行php程式碼HTMLPHP
- win10執行記憶體多大才夠用?windows10需要多大執行記憶體Win10記憶體Windows
- JavaScript 程式中記憶體洩漏深入理解JavaScript記憶體