[英]How to Inject code in c# method calls from a separate app
我很好奇是否有人知道監視.Net應用程序的運行時信息的方法(正在調用什么方法等)
並從單獨的運行進程中注入要在某些方法上運行的額外代碼。
說我有兩個應用程序:
app1.exe,為簡單起見,可以
class Program
{
static void Main(string[] args)
{
while(true){
Somefunc();
}
}
static void Somefunc()
{
Console.WriteLine("Hello World");
}
}
我有第二個應用程序,我希望能夠檢測應用程序1中的Somefunc()何時運行並注入自己的代碼,
class Program
{
static void Main(string[] args)
{
while(true){
if(App1.SomeFuncIsCalled)
InjectCode();
}
}
static void InjectCode()
{
App1.Console.WriteLine("Hello World Injected");
}
}
所以結果將是應用程序將顯示
Hello World
Hello World Injected
我明白它不會那么簡單(通過一個長鏡頭),但我不知道它是否可能,如果它甚至是從哪里開始。
有什么建議么 ?
我在java中看到過類似的做法,但從未在c#中看到過。
編輯:澄清一下,使用這個是將插件系統添加到基於.Net的游戲,我無法訪問源代碼。
可能值得研究Mono.Cecil進行代碼注入。 它不會像您在問題中描述的那樣在線工作,但我相信它可以做你想要的離線(能夠找到給定的方法,添加代碼,並寫出修改后的程序集)。 http://www.codeproject.com/KB/dotnet/MonoCecilChapter1.aspx
您需要使用Profiling API
將第二個程序配置文件作為第一個。 然后,您可以收到任何方法調用的通知。
那么,沒有App1的許可就很難做到這一點。 但假設您實際上想在App1中創建一個擴展點,那么使用某種可擴展性框架來執行您所建議的內容相對簡單。 我建議:
由於我對MEF比較熟悉,所以它的外觀如下:
class Program
{
[ImportMany("AddinContractName", typeof(IRunMe))]
public IEnumerable<IRunMe> ThingsToRun { get; set; }
void SomeFunc()
{
foreach(IRunMe thing in ThingsToRun)
{
thing.Run();
}
/* do whatever else ... */
}
}
通過你在評論中做出的澄清,在我看來,你最好使用ildasm和ilasm進行反匯編和重新組裝。
另一個想法是編寫一個應用程序來改變你想要監控的exe。 它會做類似於分析工具在“檢測”您的應用程序時所執行的操作。 基本上,您使用反射來瀏覽應用程序,然后使用.NET的Emit功能重新創建exe(使用不同的文件名)並同時插入代碼。
當然,如果應用程序嘗試安全地執行操作,則可能不允許此新版本與其他程序集通信。
根據作者打包/構建其應用程序的方式,您可以從自己的項目中添加對其EXE文件的引用,並從您自己的應用程序中執行其代碼。 如果可行的話,那就是在這一點上使用Reflection來獲得你可以插入的有用接口/事件/等(如果它們被標記為私有......否則只是直接使用它們:)。 您可以添加對使用調試或發布版本的默認設置構建的任何EXE的引用,並像使用DLL一樣使用它。
如果這不起作用,你可以使用高級技巧來交換方法調用等,但這超出了本回復的范圍......我建議先嘗試參考。
可以將代碼注入正在運行的應用程序中。 這是一個工作示例,但涉及注入非托管dll。
使用Mono Cecil在程序集中注入代碼
您可以嘗試使用CInject將C#或VB.NET代碼注入程序集
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.