我用一个已发布的方法编写了一个C++dll,它只需用定义的参数启动另一个程序。此方法是从C#WinForms应用程序中调用的。
发布的方法是通过单击按钮从C#应用程序触发的。第二个应用程序正在按预期启动,但另外一个Windows控制台窗口正在打开,该窗口不输出任何内容。
我想抑制控制台窗口,但我不知道如何做到这一点。当我运行的应用程序终止时,控制台窗口也会终止。
这就是我的标题和C++dll的来源:
发射器.h
#pragma once
#ifdef ILJ16_EXPORTS
#define LAUNCHER_EXPORT __declspec(dllexport)
#else
#define LAUNCHER_EXPORT __declspec(dllimport)
#endif // ILJ16_EXPORTS
const char* startParam = "--Q7t0elSDASCrpHQ";
extern "C" LAUNCHER_EXPORT void startProcess();
启动器.cpp
#include "pch.h"
#include "launcher.h"
#include <process.h>
#include <stdio.h>
void startProcess()
{
char command[256 + 1];
snprintf(command, sizeof(command), "Test.exe %s", startParam); //Test.exe is the application which has to be started
int retCode = system(command);
}
在我的C#WinForms项目中,我编写了以下代码
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
[DllImport("ilj16.dll", EntryPoint = "startProcess")]
public static extern void startProcess();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
startProcess();
}
}
}
考虑使用CreateProcess
而不是startprocess
,STARTUPINFO.wShowWindow
设置为SW_HIDE
。
CreateProcess
创建一个新进程及其主线程。新进程在调用进程的安全上下文中运行
从阅读windows文档中可以看出,system(const char*)
调用打开cmd.exe提示符,然后执行字符串。
系统文档
系统函数将命令传递给命令解释器,命令解释器将字符串作为操作系统命令执行。系统使用COMSPEC和PATH环境变量来定位命令解释器文件CMD.exe。如果命令为NULL,该函数只检查命令解释器是否存在。
从快速谷歌中,解决此问题的最佳方法似乎是使用_popen、CreateProcessA,或者您可以尝试使用类似的方法隐藏/关闭cmd.exe。
此外,如果你的C++dll只是打开另一个程序,你可以消除对dll的需要,并用这个C#类在C#中完成所有操作。在该链接的第一个示例中,有一个简单的解决方案:
using (Process myProcess = new Process())
{
myProcess.StartInfo.UseShellExecute = false;
// You can start any process, HelloWorld is a do-nothing example.
myProcess.StartInfo.FileName = "C:\HelloWorld.exe";
myProcess.StartInfo.CreateNoWindow = true;
myProcess.Start();
// This code assumes the process you are starting will terminate itself.
// Given that is is started without a window so you cannot terminate it
// on the desktop, it must terminate itself or you can do it programmatically
// from this application using the Kill method.
}