C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[60426] Re:SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요.
장성호 [nasilso] 3006 읽음    2010-03-11 17:16
음..
핵심 키워드
AnsiString 은 RefCount가 0 이면 자동으로 free됩니다.


코딩 실수한 부분
다음 코드가 실수하신 코드인데요
ExVal.lpDirectory = AnsiString(ExtractFilePath(Application->ExeName)).c_str();


원인은?

AnsiString은 같은 내용을 여러군데 대입하더라도 내용이 완전히 복사되지 않고
내부적으로 포인터(address)가 copy되고 RefCount가 증가합니다.

AnsiString이 free 될때는 내용을 완전히 삭제하는것이 아니라 RefCount를  하나 감소시킵니다.

이때 만약 RefCount가 0(제로)가 되면 완전히 힙에 잡혀있는 내용이 free되구요
위 코드에서 AnsiStirng을 사용하셨지만
ExtractFilePath 의 결과를 받는 AnsiString 이 없습니다.

즉  AnsiStirng.c_str(); 함수가 호출된뒤에
ExtractFilePath의 결과인 AnsiString은 RefCount가 0 이기 때문에 자동 free됩니다.

그런후에 lpDirectory 에 담긴 address만 가지고  그 위치에 접근하면
accessviolation이 나거나 쓰레기 값이 그 위치에 들어있겠죠

님 pc에서 에러가 발생하지 않는것은 행운입니다.

dis-assembler 화면




SHELLEXECUTEINFO  구조체의 lpDirectory  변수는 address만 가지고 있지
문자열 전체를 가지고 있지 않습니다.

그런데 위 그림에서 본것처럼
ExVal.lpDirectory = AnsiString(ExtractFilePath(Application->ExeName)).c_str();
위 문장에서 address.만 copy하고 실제 문자열이 담긴 AnsiString은  free되어버렸습니다.

그런다음에 ShellExecuteEx 를 호출하기 때문에 문제가 발생하는것 입니다.

해결방법
1. ExtractFilePath의 결과를 다른 AnsiString 에 담아두고..
2. 담아둔 AnsiString.c_str()을 lpDirectory 에 설정합니다.
3. 그런후에  ShellExecuteEx 를 호출하구요


주의사항
ExtractFilePath의 결과를 다른 AnsiString은 반드시  ShellExecuteEx  가 호출된후에 소멸되어야 합니다.
(블럭안에서 AnsiString을 선언하면 함수종료전에 AnsiString이 소멸될수가 있습니다.)

그럼..



이영섭 님이 쓰신 글 :
: void __fastcall TfrmVersion::OpenFile()
: {
:
:         SHELLEXECUTEINFO ExVal;
:     ExVal.cbSize = sizeof(SHELLEXECUTEINFO);
:     ExVal.fMask = NULL;
:     ExVal.hwnd = NULL;
:     ExVal.lpVerb = NULL;
:     ExVal.lpFile = "TEST.exe";
:     ExVal.lpDirectory = AnsiString(ExtractFilePath(Application->ExeName)).c_str();
:     ExVal.nShow = SW_SHOWNORMAL;
:     ExVal.hInstApp = NULL;
:
:         Application->ProcessMessages();
:         if(!ShellExecuteEx(&ExVal))
:                 ShowMessage("실패"); 
:          Close();
: }
:
:
: 이렇게 놓고 실행을 시켰는데, 제 컴퓨터에서는 잘 작동하는데 다른 컴퓨터에 옮기니까 되는게 있고 안되는데가 있습니다. 도대체 원인을 모르겠네요.
:
:  제 컴퓨터에서 되길레 옆 컴퓨터에 배포했는데, 똑같이 xp라 아무 문제 없을줄알았는데 그게 아니더라구요.
:  제쪽에서는 이상없이 test.exe파일을 실행하는데,  딴 컴퓨터에서는 test.exe파일을 못찾는다고 나오더라구요.
:
:
:  혹시 이런 증상을 보신적이 있나요?

+ -

관련 글 리스트
60425 SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요. 이영섭 2810 2010/03/11
60426     Re:SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요. 장성호 3006 2010/03/11
60431         Re:Re:SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요. 이영섭 3853 2010/03/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.