我在管道式应用程序中拥有许多进程。每次启动应用程序时,组成管道的进程数量和顺序都会有所不同。
我的目的是通过主批处理文件启动它们,但是我想在没有控制台窗口的情况下运行它们。我可以为批处理设置一个控制台,但我不想让 9 个以上的不同控制台窗口扰乱用户体验。
有没有办法在不安装服务的情况下实现这一点?或者也许有一个临时服务(如果可能的话)?
谢谢!
答案1
嗯,我认为你必须进行一些开发。你可以制作一个没有窗口的启动器应用程序(关于这个主题有很多信息)。
在启动器应用中,您将调用 CreateProcess Windows API 的一些变体。您可以考虑使用 CreateProcess 的 dwCreationFlags 参数中的 CREATE_NO_WINDOW 标志。请阅读 MSDN 中的文档以了解限制。
这是我在网上找到的一些 VC++ 代码,我还没有测试过,但是大概意思就是那样:
//-------------------------------------------------------------
//
// File: Launcher.cpp
//
// Copyright 2005 (c) by Euphonix, Inc.
//
// Description:
//
// Simple shell application for XPE. Reads a registry entry
// (set via target designer) to find an init file. Reads the
// init file to find an app to launch and working dir to use.
// Launches the app and waits for the launched process to
// terminate.
//
// If failure occurs anywhere along the way, launches an XP
// command window as a failsafe.
//
// Author: Fritz Mueller
//
// Creation Date: 8/3/05
//
// Implementation Notes:
//
//-------------------------------------------------------------
#define WINVER 0x0501
#include <afxwin.h>
#include <tchar.h>
#include <sstream>
using namespace std;
typedef basic_ostringstream<TCHAR> tostringstream;
typedef basic_string<TCHAR> tstring;
class LauncherErr
{
public:
LauncherErr(DWORD iCode, const tstring &iDesc) : mCode(iCode), mDesc(iDesc)
{}
DWORD mCode;
tstring mDesc;
};
DWORD SpawnProcess(
const tstring &cmdline,
const tstring &workingdir,
DWORD creationFlags)
{
DWORD result;
BOOL success;
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
PROCESS_INFORMATION pi;
success = CreateProcess(
NULL, (LPTSTR)cmdline.c_str(), NULL, NULL, FALSE, creationFlags, NULL,
workingdir.empty() ? NULL : workingdir.c_str(), &si, &pi
);
if (!success) throw LauncherErr(GetLastError(), _T("Could not create
process."));
result = WaitForSingleObject(pi.hProcess, INFINITE);
if (result == WAIT_FAILED) throw LauncherErr(GetLastError(), _T("Process
wait failed."));
DWORD exitcode;
success = GetExitCodeProcess(pi.hProcess, &exitcode);
if (!success) throw LauncherErr(GetLastError(), _T("Could not retrieve
process exit code."));
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return exitcode;
}
int APIENTRY _tWinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
DWORD result;
try {
HKEY key;
result = RegOpenKey(HKEY_LOCAL_MACHINE,
_T("Software\\Euphonix\\LauncherShell\\"), &key);
if (result != ERROR_SUCCESS) throw LauncherErr(GetLastError(), _T("Could
not open launcher registry key."));
DWORD valuetype;
TCHAR initpath[MAX_PATH];
DWORD initpathsize = sizeof(initpath);
result = RegQueryValueEx(key, _T("InitFile"), NULL, &valuetype,
(LPBYTE)initpath, &initpathsize);
if (result != ERROR_SUCCESS) throw LauncherErr(GetLastError(), _T("Could
not retrieve init file registry value."));
TCHAR cmdline[MAX_PATH];
DWORD cmdlinesize = MAX_PATH;
cmdlinesize = GetPrivateProfileString(_T("application"), _T("cmdline"),
NULL, cmdline, cmdlinesize, initpath);
if (cmdlinesize == 0) throw LauncherErr(GetLastError(), _T("Could not
retrieve command."));
TCHAR workingdir[MAX_PATH];
DWORD workingdirsize = MAX_PATH;
workingdirsize = GetPrivateProfileString(_T("application"),
_T("workingdir"), _T(""), workingdir, workingdirsize, initpath);
result = SpawnProcess(cmdline, workingdir, DETACHED_PROCESS);
}
catch(const LauncherErr &err) {
tostringstream str;
str << _T("cmd /k echo Euphonix Launcher Error (") << err.mCode << _T("):
") << err.mDesc << endl;
result = SpawnProcess(str.str(), _T(""), CREATE_NEW_CONSOLE);
}
return (result == ERROR_SUCCESS) ? 0 : -1;
}
希望这可以帮助。
答案2
如果这是在批处理文件中完成的,你不能使用吗START /B
?