C# [程序加壳] 运行内嵌程序 - 调用嵌入资源的EXE文件运行

本文介绍的是程序内嵌,如果需要实现窗体内嵌(捕捉程序外部窗体到自己控件上显示),可参考本人发表的文章:https://blog.csdn.net/lzl_li/article/details/117120335

本文介绍如何在程序中内嵌其它exe程序文件并调取运行,修正了网上写的代码。
(主要修正了资源文件的读取、EXE文件中Main(string [])函数参数传递代码)
1.先建立一个测试项目test,编译输出test.exe
2.再建立一个加壳项目AppPacker
3.在项目AppPacker中找到 “properties\resources.resx”,双击Resources.resx打开,在里面添加test.exe文件为本项目的资源:
在这里插入图片描述
在这里插入图片描述
4.打开Program.cs文件,主函数Main中添加如下代码:

static void Main(string []args)
        {
            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());//因调用的是带窗体程序,如果此处调用窗体将导致方法1报错。

            string[] str;
            if (args != null && args.Length > 0)
                str = args;
            else
                str = new string[] { "没有获得参数,程序中定义的字符串。" };
            
            byte[] fileBytes = Properties.Resources.test;//资源中获取数据(“test”是作为文件资源提前加入到了本工程的资源文件“properties\resources.resx”)
            
            /*上面的方法获取资源文件简单有效,下面是网上使用的方法,过于复杂而且容易出错,本人测试不通过,不知道哪里的问题
            String projectName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name.ToString();
            System.IO.Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(projectName + ".test.exe");
            byte[] fileBytes = new byte[stream.Length];
            stream.Read(fileBytes, 0, (int)stream.Length);
            */

            //【方法1】进程内部调用代码执行:同一进程只能打开一个主窗体,否则会报错。【如果本进程已经开了主窗体,调用的代码中也有主窗体会报错】
            System.Reflection.Assembly asm = System.Reflection.Assembly.Load(fileBytes);//对加载的APP有要求,C#类型程序一般可以(.NET平台编译的托管代码应该也可以),其它编译的程序测试了很多都不可以
            System.Reflection.MethodInfo info = asm.EntryPoint;
            System.Reflection.ParameterInfo[] parameters = info.GetParameters();            
            if ((parameters != null) && (parameters.Length > 0))
                //info.Invoke(null,(object[])str);  //网上错误的参数传递(错误在于参数列表变成一个个字符串,而非main函数要求的字符串数组),下面是修正后的调用
                info.Invoke(null, new object[] { str });//参数1是方法的对象,因为主主函数为静态函数没有对象所以为null;参数2是方法的参数对象列表,主函数一般是只有1个string[]参数对象
            else
                info.Invoke(null, null);

            //【方法2】进程外部启动新进程(将资源文件存储到磁盘并启动新进程),不受编译平台限制,所有类型APP文件都可以
            string fileName = System.IO.Path.GetTempPath();
            if (fileName.EndsWith("\\"))
                fileName = fileName + "test.exe";
            else
                fileName = fileName + "\\test.exe";
            System.IO.BinaryWriter bw = new System.IO.BinaryWriter(new System.IO.FileStream(fileName, System.IO.FileMode.Create));
            bw.Write(fileBytes);
            bw.Flush();
            bw.Dispose();
            System.Diagnostics.Process myPro = System.Diagnostics.Process.Start(fileName, str[0]);
            
            //上面2种方式,都可以在资源文件数据进行加密操作,先将文件加密再加入资源当中,读取时再进行解密,然后执行后续操作。
        }

源代码下载

本文中的代码参考了以下文章,并对其中的2个关键点进行了修正:

https://www.cnblogs.com/huangcong/archive/2010/03/23/1693293.html
https://www.cnblogs.com/xlw1219/archive/2012/11/29/2795069.html

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzl_li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值