现有一exe后台程序server.exe(后台程序有配置文件,配置文件与可执行文件在同一目录下)
如:
../server.exe
../logs/
../Sessions/
../debug.log
../hnet_server.conf
../panic.log
怎样在mfc中调用CreateProcess|WinExec|ShellExec来正确执行server.exe调用时,没有读取配置文件,而是使用了在server.exe中写好的默认设置。。
求教
这个与主程序的运行目录有关吗?

解决方案 »

  1.   

    主程序的运行目录是什么?如果是程序所在目录,那么无关;如果是工作路径,那么在你没有指定server.exe的绝对路径,默认会以当前工作路径为基准。STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    BOOL bCreate = ::CreateProcess(NULL, _T("D:\\server.exe"), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
    if (!bCreate)
    {
      // 失败处理
    }
    ::CloseHandle(pi.hThread);
    ::CloseHandle(pi.hProcess);
      

  2.   

    GetModuleFileName();得到当前运行的exe程序的绝对路径,然后修改拼装成server.exe的路径,最后CreateProcess启动不行吗?
      

  3.   


    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    memset(&si,0,sizeof(si));
    si.cb=sizeof(STARTUPINFO);
    si.dwFlags=STARTF_USESHOWWINDOW;

    BOOL ret=CreateProcess(
    _T("D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\nt_i386_vc90d\\Sever\\server.exe"),
    _T("server.exe"),
    NULL,
    NULL,
    FALSE,
    0,
    NULL,
    NULL,
    &si,
    &pi);
    if(!ret)...我是这样写的server.exe没有读取配置文件,,,
      

  4.   


    #include <windows.h>
    #include <stdio.h>
    #include <tchar.h>void _tmain( int argc, TCHAR *argv[] )
    {
        STARTUPINFO si;
        PROCESS_INFORMATION pi;    ZeroMemory( &si, sizeof(si) );
        si.cb = sizeof(si);
        ZeroMemory( &pi, sizeof(pi) );    if( argc != 2 )
        {
            printf("Usage: %s [cmdline]\n", argv[0]);
            return;
        }    // Start the child process. 
        if( !CreateProcess( NULL,   // No module name (use command line)
            argv[1],        // 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.
        WaitForSingleObject( pi.hProcess, INFINITE );    // Close process and thread handles. 
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
    }如果是通过获取自己路径 来进行创建的话
    应该是木问题
      

  5.   

    你的server.exe程序中是怎么读取配置文件的呢?路径用的是相对路径??
      

  6.   

    和主程序的运行目录无关
    但是你传入的server.exe的路径最好是绝对路径,并且调用CreateProcess函数时,LPCTSTR lpCurrentDirectory参数必须设置,否则在server.exe中获得当前路径可能不正确
      

  7.   

    不行我试过了。
    当前运行程序的目录与/Server是在同一目录
    server.exe与其配置文件放在/Server/下
      

  8.   

    建议还是通过获取自身路径的方法来做 你这么写的是绝对路径
    一旦exe不在那个指定的目录
    进程不会创建成功的
      

  9.   


    求写一个
    server.exe的路径
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\\nt_i386_vc90d\\Sever\\server.exe
    配置文件的路径
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\\nt_i386_vc90d\\Sever
    主程序的路径
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\\nt_i386_vc90d
      

  10.   

    你主程序调用一下代码,启动server.exe
     
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    memset(&si,0,sizeof(si));
    si.cb=sizeof(STARTUPINFO);
        
    CreateProcess(
            _T("D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\nt_i386_vc90d\\Sever\\server.exe"),
            NULL,
            NULL,
            NULL,
            FALSE,
            0,
            NULL,
            _T("D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\nt_i386_vc90d\\Sever\\"),,
            &si,
            &pi);
    配置文件是由主程序读还是由server.exe读?
      

  11.   

    那你在server.exe里面GetModuleFileName获得路径,
    格式大概是这样的:
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\nt_i386_vc90d\\Sever\\server.exe
    通过字符串函数获得目录路径:
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\nt_i386_vc90d\\Sever然后再通过字符串函数获得配置文件路径:
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\nt_i386_vc90d\\Sever\\你的配置文件名
    然后就可以读取配置文件并分析了
      

  12.   

    GetCurrentDirectory(); SetCurrentDirectory() 获取和设置其所在的当前驱动器和目录。
          _chdir在内部调用SetCurrentDirectory(),但还会调用SetEnvironmentVariable(),从而使不同驱动器的当前目录得以保留。
      

  13.   

    你改用绝对路径,先得到当前exe的绝对路径,然后拼装出你需要的文件绝对路径,不知道这么说你理解不?
      

  14.   


    server.exe是别人给的程序。没法修改。。
    只能通过写配置文件来控件它。
    我单独运行server.exe时,它能读取我写的配置文件。
      

  15.   


    int pos;
    //应用程序全路径+文件名
    TCHAR cur_exe[MVO_BUFFER_SIZE];
    GetModuleFileName(NULL,cur_exe,MVO_BUFFER_SIZE);
    //应用程序路径
    CString cur_path=_T("");

    cur_path=(CString)cur_exe;
    pos=cur_path.ReverseFind('\\');
    cur_path=cur_path.Left(pos+1); CString server=cur_path+CString("Server\\server.exe");这样?这样与写绝对路径有差别么???
      

  16.   

    也就是说server.exe是固定读一个和自己相同目录下的配置文件,并且这个程序是你不能改的?server.exe的路径
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\\nt_i386_vc90d\\Sever\\server.exe
    配置文件的路径
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\\nt_i386_vc90d\\Sever
    主程序的路径
    D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\\nt_i386_vc90d那么在主程序中
    CString strPath;
    ::GetModuleFileName(NULL, strPath.GetBuffer(MAX_PATH), MAX_PATH);
    strPath.ReleaseBuffer();
    strPath = strPath.Left(strPath.ReverseFind('\\'));
    strPath += _T("\\Server");
    ::SetCurrentDirectory(strPath);
    strPath += _T("server.exe"); STARTUPINFO si = { sizeof(si) };
    PROCESS_INFORMATION pi;
    BOOL bCreate = ::CreateProcess(NULL, strPath, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
    if (!bCreate)
    {
      // 失败处理
    }
    ::CloseHandle(pi.hThread);
    ::CloseHandle(pi.hProcess);
      

  17.   

    server.exe中如何获得配置文件路径的?
    一般在CreateProcess启动进程时设置了当前目录这个参数,就应该没有问题了
      

  18.   


    错了一点,strPath += _T("server.exe");改为strPath += _T("\\server.exe");
      

  19.   



    非常感谢你这么热心
    但是我发现server.exe竟然不运行
    CreateProcess失败。
      

  20.   

    刚才拼server.exe的绝对路径时忘了加“\\”,你重新试一下
      

  21.   

    还是不行
    我写绝对路径还能运行
    只是读不到配置文件
    strPath="D:\\Program Files\\HOOPS-1700_VS_NET_2008\\bin\\nt_i386_vc90d\\Sever\\server.exe";
    而下面根本不会执行
    CString strPath;
        ::GetModuleFileName(NULL, strPath.GetBuffer(MAX_PATH), MAX_PATH);
        strPath.ReleaseBuffer();
        strPath = strPath.Left(strPath.ReverseFind('\\'));
        strPath += _T("\\Server\\");
        ::SetCurrentDirectory(strPath);
        strPath += _T("server.exe");


    STARTUPINFO si = { sizeof(si) };
        PROCESS_INFORMATION pi;

        BOOL bCreate = ::CreateProcess(NULL, strPath.GetBuffer(MAX_PATH), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
      

  22.   

    先使用cmd命令直接执行你所谓的server.exe,后面跟所谓的配置项文件,因为我觉得你现在的问题是server.exe如何读取配置项的问题,你server.exe后面直接跟配置项这样的读取方式未必正确,先看在cmd命令行下是否可以执行,如何可以,你再使用上面大家已经说过的方法,不管你是使用绝对还是相对路径,因为绝对路径和相对路径,在你刚才实验的时候已经可以看出来了
      

  23.   


    用cmd命令可行。
    但是不知道怎么加到程序中去。
      

  24.   

    看CreateProcess的说明
    http://baike.baidu.com/view/697167.htm
    第八个参数lpCurrentDirectory
    这个参数用来指定子进程的工作路径
    如果程序内部寻找配置文件使用相对路径则在这个路径的基础上进行查找
    所以你需要设置这个参数来指定你的配置文件的位置
      

  25.   

        CString strPath;
        ::GetModuleFileName(NULL, strPath.GetBuffer(MAX_PATH), MAX_PATH);
        strPath.ReleaseBuffer();
        strPath = strPath.Left(strPath.ReverseFind('\\'));
        strPath += _T("\\Server\\");
        ShellExecute(NULL,_T("open"),_T("server.exe"),NULL,strPath,SW_HIDE); 
    上面这样是可以的
    可以通过strPath设置路径
    而且可以读到配置文件
    运行正确而用createprocess不行。
    不知道问题出在哪但是shellexecute不能获得进程句柄,我无法随时关闭它。