步骤
- 1、编写32位控制台程序
- 2、实现字符串传参
- 3、封装Process类库
- 4、获取进程调用的返回值
在实际的项目中经常使用一些第三方C/C++库,于历史原因,有的C库是32位的,由于没有源代码,所以一般很难修改为64位的类库,但又需要调用,怎么办呢,在参考了一些大神的博客后,总结出了一个独立进程访问的方法,来调取第三方库,获取返回值
1、编写32位控制台程序
编写一个32位的控制台程序,用于被主程调用
public class Program
{public static void Main(string[] args){if(args.Length > 0 && !string.IsNullOrEmpty(args[0])){string paramStr = args[0];//获取传递过来的参数//调用三方C/C++库逻辑/*...................................*///将指定的字符串值(后跟当前行终止符)写入标准输出流。Console.WriteLine(result);}}
}
2、实现字符串传参
由于Main函数进程传参的参数类型只能是字符串,所以需要把C/C++库函数所需的byte[]类型参数转换成字符串类型,互转方法参数选择16进制字符串,代码如下:
// byte[]转16进制字符串
StringBuilder sb = new StringBuilder();
foreach (byte b in msgbuf)
{//{0:X2} 大写方式sb.AppendFormat("{0:x2}", b);
}
string argsStr = sb.ToString();// 16进制字符串转byte[]
var msgbuf = new byte[hexStr.Length / 2];
for (var x = 0; x < msgbuf.Length; x++)
{var i = Convert.ToInt32(hexStr.Substring(x * 2, 2), 16);msgbuf[x] = (byte)i;
}
3、封装Process类库
封装一个简洁的ProcessCommandBase 帮助类来调用exe封装的第三方库进程,且可以返回被封装C库函数的返回值
public class ProcessCommandBase : IDisposable
{//程序名public string programe;//参数StringBuilder parameter = new StringBuilder();Process process = null;public ProcessCommandBase(string programe){this.programe = programe;}public ProcessCommandBase AddParameter(string para){parameter.Append($" {para} ");return this;}public string Exec(bool waitForExit = false){//var baseDir = AppDomain.CurrentDomain.BaseDirectory;process = new Process();process.StartInfo.FileName = programe;process.StartInfo.Arguments = parameter.ToString();process.StartInfo.CreateNoWindow = true;process.StartInfo.UseShellExecute = false;//重定向标准输输出、标准错误流process.StartInfo.RedirectStandardError = true;process.StartInfo.RedirectStandardOutput = true;process.ErrorDataReceived += Process_ErrorDataReceived;process.Exited += Process_Exited;process.OutputDataReceived += Process_OutputDataReceived;Trace.WriteLine($"Exe:{programe}");Trace.WriteLine($"Parameter:{parameter.ToString()}");process.Start();process.BeginErrorReadLine();//process.BeginOutputReadLine();if (waitForExit){string result = process.StandardOutput.ReadToEnd();process.WaitForExit();return result;}return string.Empty;}public void Process_OutputDataReceived(object sender, DataReceivedEventArgs e){Trace.WriteLine(e.Data ?? string.Empty);}public void Process_Exited(object sender, EventArgs e){}public void Process_ErrorDataReceived(object sender, DataReceivedEventArgs e){Trace.WriteLine(e.Data ?? string.Empty);}public void ClearParameter(){parameter.Clear();}public void Close(){process?.Close();process = null;}public void Kill(){process?.Kill();process?.Close();process = null;}public void Dispose(){Kill();}
}
4、获取进程调用的返回值
调用执行封装后的控制台程序后,需要获取被封装C库的返回值
var exec = new ProcessCommandBase("test.exe");
exec.AddParameter("xxxxxxxxxxxx");
var result = exec.Exec(true);