2012-07-05 3 views
12

내 목표는 내 프로그램에서 외부 실행 파일을 실행하는 것입니다. 첫째, 나는 system() 함수를 사용했지만, 콘솔을 사용자에게 보이고 싶지는 않습니다. 그래서, 조금 검색하고 CreateProcess() 기능을 찾았습니다. 그러나 매개 변수를 전달하려고 할 때 이유를 알지 못하고 실패합니다. MSDN에서이 코드를 가져 와서 조금 바꿨습니다.CreateProcess()가 액세스 위반으로 실패합니다.

#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) 
     L"c:\\users\\e\\desktop\\mspaint.exe",  // 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); 
} 

그러나이 코드는 어떻게 든 액세스 위반을 작성했습니다. 사용자에게 콘솔을 보여주지 않고 mspaint를 실행할 수 있습니까?

대단히 감사합니다.

+2

,'CreateProcess'는 (있는 경우)의 두 번째 매개 변수는 const가 아닌 문자열이 될 것을 요구한다. 이것이 실제로 문제가되는지는 확실치 않지만 완벽을 기하기 위해 언급하고 싶습니다. – reuben

+0

... 그렇지 않으면 어디에서 AV가 발생합니까? 통화 스택이 있습니까? – reuben

+0

@reuben Uhm ... 잘 모르겠지만 호출 스택의 출력이라고 생각합니다 :'kernel32.dll! 76da70ac() \t \t [아래 프레임은 올바르지 않을 수도 있고 없거나, 심볼이로드되지 않았을 수도 있습니다 KERNEL32.DLL] \t > \t msvcr100d.dll에! _nh_malloc_dbg (서명 INT n 크기, INT nhFlag, INT nBlockUse, const를 숯불 * szFileName, INT의 nLine) 라인 (302) + \t C 바이트 0x1d ++' –

답변

7

시도해보십시오. 작동해야합니다. 이 코드

TCHAR lpszClientPath[500]= TEXT("c:\\users\\e\\desktop\\mspaint.exe"); 
if(!CreateProcess(NULL, lpszClientPath, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS|CREATE_NEW_CONSOLE|CREATE_UNICODE_ENVIRONMENT,NULL, NULL, &si, &pi)) 
      { 
    printf("CreateProcess failed (%d).\n", GetLastError()); 
     return; 
      } 
... 
... 
18

두 번째 인수는 LPTSTR, 즉 const가 아닌 char 배열에 대한 포인터입니다. docs 특히 말 :

이 파라미터는 읽기 전용

리터럴 스트링을 전달하는 이유는 문제가있다 (예 CONST 변수 또는 리터럴 스트링으로) 메모리 포인터 수 없습니다

시스템은 인수와 파일 이름을 구분하기 위해 명령 줄 문자열에 종결 null 문자를 추가합니다. 이렇게하면 원래 문자열을 내부 처리를위한 두 개의 문자열로 나눕니다.

귀하의 경우에는 읽기 전용 메모리를 변경하려고합니다. 따라서 충돌이 발생합니다.

+0

내가 중 하나 LPTSTR을 할당 할 수 없습니다 . "c : \ users \ e \ desktop \"에있는 mspaint를 실행하기 위해 두 번째 논점을 물어봐야합니까? 고맙습니다. –

+2

@JohnDoe :'wchar_t path [] = L "C : \\ 사용자 \\ e \\ 바탕 화면 \\"' – hmjd

+0

'wchar_t 경로 [] = L "C : \\ blahblah"는'LPWSTR path = L "C : \\ blahblah"'와 동일하지만'wchar_t * path = L "C : \\ blahblah"'와 동일합니다. @hmjd가 제안한 것을 사용하거나'LPWSTR path'를 정의한 다음이 var에 메모리를 할당하고 경로를 복사해야합니다. –

0

변경 당신은 : 한 가지를 들어

#include <windows.h> 
#include <stdio.h> 
#include <tchar.h> 

void _tmain(int argc, TCHAR *argv[]) 
{ 
    TCHAR ProcessName[256]; 
    STARTUPINFO si; 
    PROCESS_INFORMATION pi; 

    wcscpy(ProcessName,L"c:\\users\\e\\desktop\\mspaint.exe"); 
    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) 
     ProcessName,  // 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); 
} 
관련 문제