【问题标题】:How Do I Compile a C Program to Run Without a Command Box?如何编译 C 程序以在没有命令框的情况下运行?
【发布时间】:2011-04-17 09:03:30
【问题描述】:

我需要一个非常简单的程序来在任何版本的 Windows 上运行,比如说 >= Win 98,而不需要像 dotnet 这样的预安装框架。我认为 C 语言会是一个好主意。

程序应该使用系统命令从父目录启动一个进程。

启动C程序(不可见)>程序启动进程>程序退出

看起来是这样的:

#include <stdio.h>
#include <stdlib.h>

int main() {
    system("..\\someprogram.exe");
    return 0;
}

我从 Flash 投影仪调用这个程序,它只允许在特定的子文件夹“fscommand”中启动程序 - 但我必须启动与投影仪位于同一目录中的进程。

无论如何,它工作正常!但是 C 程序会打开一个命令框,然后启动进程并在进程运行时让命令框保持打开状态。所以这里是它应该如何工作,为了我会如何欣赏它:

  1. 根本不打开命令框(我很喜欢,真的;)
  2. 3) 和 4)
  3. 启动进程后关闭命令框(退出C程序)
  4. 默认打开最小化的命令框

我无法更改 C 可执行文件的任何 Windows 设置或使用快捷方式,因为稍后将直接从 CD 运行。

我使用 Open Watcom 编译我的程序。生成可执行文件(字符模式可执行文件/窗口可执行文件)的两种图像类型(目标选项)具有相同的结果。

【问题讨论】:

  • 你看到了吗? stackoverflow.com/questions/411247/…批处理文件应该可以解决问题。
  • 不幸的是,出于安全原因,Flash 不允许调用带有参数的可执行文件。只有不带参数的 exe 和 bat 调用是可能的。 (这是 Adob​​e 有史以来最伟大的想法之一。)我有一个很好的解决方案,使用批处理文件而不是 C 程序。这在手动启动蝙蝠时有效。但是当从 Flash 调用它时,它只是没有启动该过程。 -.-

标签: c process command-prompt


【解决方案1】:

我用谷歌搜索发现http://www.ntwind.com/software/utilities/hstart.html

您使用的是控制台应用程序,您可以使用 winmain() 将其更改为 Windows 应用程序

您可以使用指向同一文件夹中文件的快捷方式,但不知道为什么要打折该方法。

start 会给你一个 fork,这样你的中间应用程序就可以关闭 - 不确定 win98。

system("start ..\\someprogram.exe");

您可以使用createProcess 代替系统来启动应用程序,这将避免system 命令控制台。

STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pi, sizeof(pi) );

// Start the child process. 
if( !CreateProcess( "..\\someprogram.exe",   // module name 
    NULL,        // Command line
    NULL,           // Process handle not inheritable
    NULL,           // Thread handle not inheritable
    FALSE,          // Set handle inheritance to FALSE
    0,              // No creation flags
    NULL,           // Use parent's environment block
    NULL,           // Use parent's starting directory 
    &si,            // Pointer to STARTUPINFO structure
    &pi )           // Pointer to PROCESS_INFORMATION structure
) 
{
    printf( "CreateProcess failed (%d).\n", GetLastError() );
    return;
}

// Wait until child process exits.  In your case you don't care to wait anyway
// WaitForSingleObject( pi.hProcess, INFINITE );

// Close process and thread handles. 
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );

【讨论】:

  • 使用 WinMain() 听起来合乎逻辑,但仍会产生一个命令框。 :( 添加行:#include &lt;windows.h&gt;int WINAPI WinMain (HINSTANCE hI, HINSTANCE hPrI, PSTR szCmdLine, int iCmdShow)
  • 这个小改动system("start ..\\someprogram.exe"); 符合我列出的#3 行为。 :) 我没有尝试其余的,因为我同时找到了一个更简单的解决方案。
【解决方案2】:

显示控制台窗口是因为您将程序构建为控制台应用程序。我不知道如何在 C 中避免这种情况,但在 Delphi 中,项目文件中有一个简单的{$Console Off} pragma。

GCC 有一个命令行选项-mwindows,我认为可以达到相同的效果,所以你可以往这个方向搜索。

【讨论】:

  • 对我来说听起来不错,虽然我没有找到在 Open Watcom 中做类似事情的方法。 :)
【解决方案3】:

认为_exec 和/或_spawn 函数可以满足您的需求,但我不确定。

如果没有,您可以随时使用CreateProcess,尽管在某些方面可能会更乏味。

【讨论】:

    【解决方案4】:

    您可以(例如)使用 hstart 而不是您自己的程序来启动该 exe。

    (这将导致根本没有黑框。)

    【讨论】:

    • 这很好,但 Flash 不支持应用程序调用的参数(请参阅我上面的评论)。 :(
    【解决方案5】:

    CreateProcessCREATE_NO_WINDOW 标志是你想要的,但我想添加一些东西。要支持没有可执行文件且不能单独传递给CreateProcess 的cmd 样式命令(例如DIRSET、...),您应该调用cmd.exe /C someprogram,其中someprogram 是可执行文件、bat 文件或命令。

    【讨论】:

    • 这不正是system 正在做的事情吗?
    • 没有@Roland。系统还等待创建的进程结束。但是通过 CreateProcess 你可以在主进程中做一些事情,直到新进程运行。
    【解决方案6】:

    一位朋友提出了一个完全不同的解决方案。现在我使用AutoIt 和一个简短的编译脚本来启动这个过程。这非常简单,启动器进程是完全不可见的。 :)

    filename = ..\someprogram.exe
    
    if FileExist(filename) {    
        Run, open %filename%
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-09
      • 2016-06-02
      • 2014-04-05
      • 1970-01-01
      • 2016-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多