- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
一位用户提示我的 cmd 应用程序在特定 GUI 设置中调用时闪现命令行窗口。
为了他的缘故,我将该应用程序制作成一个图形用户界面应用程序并连接到控制台。从 powershell 调用它时,除了光标问题外,效果很好。
最大的问题是输出现在不再被调用 Qt 应用程序(QProcess::MergedChannels
和 readAll
)捕获,因为 cmd 应用程序直接将其输出到包含控制台窗口而不是调用 Qt 应用程序。
有没有比调用 AttachConsole
更好的方法,或者我应该向应用程序添加一个特殊的命令行选项以防止攻击?
编辑:附件代码 https://github.com/Snorenotify/Snoretoast/blob/master/src/main.cpp#L209
最佳答案
我在使用 Inkscape 时遇到了一个非常相似的问题。当 GUI 应用程序在控制台(类似于 Unix)中运行时,从它获得命令行输出的最佳方式是拥有两个可执行文件。
program.exe
是一个窗口应用程序。program.com
是一个辅助控制台应用程序,它生成 program.exe
并将控制台输入和输出传送给它。请注意,它与 DOS 中的 COM 可执行文件无关 - 它只是重命名为 .com
的标准 PE 可执行文件。由于 cmd
shell 中可执行扩展的默认优先顺序是 .com
在 .exe
之前,键入 program
在 shell 中将执行 program.com
,而不是 program.exe
。
有关工作示例,请参阅此文件: http://bazaar.launchpad.net/~inkscape.dev/inkscape/trunk/view/head:/src/winconsole.cpp - 为方便起见粘贴在下方。
/**
* \file
* Command-line wrapper for Windows.
*
* Windows has two types of executables: GUI and console.
* The GUI executables detach immediately when run from the command
* prompt (cmd.exe), and whatever you write to standard output
* disappears into a black hole. Console executables
* do display standard output and take standard input from the console,
* but when you run them from the GUI, an extra console window appears.
* It's possible to hide it, but it still flashes for a fraction
* of a second.
*
* To provide an Unix-like experience, where the application will behave
* correctly in command line mode and at the same time won't create
* the ugly console window when run from the GUI, we have to have two
* executables. The first one, inkscape.exe, is the GUI application.
* Its entry points are in main.cpp and winmain.cpp. The second one,
* called inkscape.com, is a small helper application contained in
* this file. It spawns the GUI application and redirects its output
* to the console.
*
* Note that inkscape.com has nothing to do with "compact executables"
* from DOS. It's a normal PE executable renamed to .com. The trick
* is that cmd.exe picks .com over .exe when both are present in PATH,
* so when you type "inkscape" into the command prompt, inkscape.com
* gets run. The Windows program loader does not inspect the extension,
* just like an Unix program loader; it determines the binary format
* based on the contents of the file.
*
*//*
* Authors:
* Jos Hirth <jh@kaioa.com>
* Krzysztof Kosinski <tweenk.pl@gmail.com>
*
* Copyright (C) 2008-2010 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#ifdef WIN32
#undef DATADIR
#include <windows.h>
struct echo_thread_info {
HANDLE echo_read;
HANDLE echo_write;
unsigned buffer_size;
};
// thread function for echoing from one file handle to another
DWORD WINAPI echo_thread(void *info_void)
{
echo_thread_info *info = static_cast<echo_thread_info*>(info_void);
char *buffer = reinterpret_cast<char *>(LocalAlloc(LMEM_FIXED, info->buffer_size));
DWORD bytes_read, bytes_written;
while(true){
if (!ReadFile(info->echo_read, buffer, info->buffer_size, &bytes_read, NULL) || bytes_read == 0)
if (GetLastError() == ERROR_BROKEN_PIPE)
break;
if (!WriteFile(info->echo_write, buffer, bytes_read, &bytes_written, NULL)) {
if (GetLastError() == ERROR_NO_DATA)
break;
}
}
LocalFree(reinterpret_cast<HLOCAL>(buffer));
CloseHandle(info->echo_read);
CloseHandle(info->echo_write);
return 1;
}
int main()
{
// structs that will store information for our I/O threads
echo_thread_info stdin = {NULL, NULL, 4096};
echo_thread_info stdout = {NULL, NULL, 4096};
echo_thread_info stderr = {NULL, NULL, 4096};
// handles we'll pass to inkscape.exe
HANDLE inkscape_stdin, inkscape_stdout, inkscape_stderr;
HANDLE stdin_thread, stdout_thread, stderr_thread;
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
// Determine the path to the Inkscape executable.
// Do this by looking up the name of this one and redacting the extension to ".exe"
const int pathbuf = 2048;
WCHAR *inkscape = reinterpret_cast<WCHAR*>(LocalAlloc(LMEM_FIXED, pathbuf * sizeof(WCHAR)));
GetModuleFileNameW(NULL, inkscape, pathbuf);
WCHAR *dot_index = wcsrchr(inkscape, L'.');
wcsncpy(dot_index, L".exe", 4);
// we simply reuse our own command line for inkscape.exe
// it guarantees perfect behavior w.r.t. quoting
WCHAR *cmd = GetCommandLineW();
// set up the pipes and handles
stdin.echo_read = GetStdHandle(STD_INPUT_HANDLE);
stdout.echo_write = GetStdHandle(STD_OUTPUT_HANDLE);
stderr.echo_write = GetStdHandle(STD_ERROR_HANDLE);
CreatePipe(&inkscape_stdin, &stdin.echo_write, &sa, 0);
CreatePipe(&stdout.echo_read, &inkscape_stdout, &sa, 0);
CreatePipe(&stderr.echo_read, &inkscape_stderr, &sa, 0);
// fill in standard IO handles to be used by the process
PROCESS_INFORMATION pi;
STARTUPINFOW si;
ZeroMemory(&si,sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdInput = inkscape_stdin;
si.hStdOutput = inkscape_stdout;
si.hStdError = inkscape_stderr;
// spawn inkscape.exe
CreateProcessW(inkscape, // path to inkscape.exe
cmd, // command line as a single string
NULL, // process security attributes - unused
NULL, // thread security attributes - unused
TRUE, // inherit handles
0, // flags
NULL, // environment - NULL = inherit from us
NULL, // working directory - NULL = inherit ours
&si, // startup info - see above
&pi); // information about the created process - unused
// clean up a bit
LocalFree(reinterpret_cast<HLOCAL>(inkscape));
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
CloseHandle(inkscape_stdin);
CloseHandle(inkscape_stdout);
CloseHandle(inkscape_stderr);
// create IO echo threads
DWORD unused;
stdin_thread = CreateThread(NULL, 0, echo_thread, (void*) &stdin, 0, &unused);
stdout_thread = CreateThread(NULL, 0, echo_thread, (void*) &stdout, 0, &unused);
stderr_thread = CreateThread(NULL, 0, echo_thread, (void*) &stderr, 0, &unused);
// wait until the standard output thread terminates
WaitForSingleObject(stdout_thread, INFINITE);
return 0;
}
#endif
总而言之:助手应用程序创建了三个管道。它使用 CreateProcess
生成窗口应用程序,将适当的管道末端作为标准输入、输出和错误句柄。最后,它创建三个线程,将数据从管道复制到辅助应用程序的标准输入、输出和错误。
关于c++ - AttachConsole 和 QProcess::readAll(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32137019/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!