Q&A

  • [질문]window7때문에 돌아버리겠습니다.
고수님들 window7에서 여러가지 문제가 발견되는데 어찌 처리해야할 지
도움 부탁드립니다,.
하나 해결하면 또 하나가 말썽입니다.

두 프로그램간에 메시지를 전달하는데 문자열에 문제가 발생합니다.
exe만들어서 build로 만들어진 exe파일을 구동하면 전혀 문제가 없는데
이 실행파일이 programs Files(X86)밑에 설치되면 문제가 발생합니다.
결론적으로 전달된 문자열이 반으로 잘려버립니다.

프로그램인 exe간에는 그래서 문자전달함수를 아래와 같이 고쳐서 보내니 문제가 없습니다.
윈도우버젼 읽은 함수
function TFuncCommon.GetOS;
var
  OS :TOSVersionInfo;
begin
  ZeroMemory(@OS,SizeOf(OS));
  OS.dwOSVersionInfoSize:=SizeOf(OS);
  GetVersionEx(OS);
  Result:=osUnknown;
  if OS.dwPlatformId=VER_PLATFORM_WIN32_NT then begin
    case OS.dwMajorVersion of
      3: Result:=osNT3;
      4: Result:=osNT4;
      5: Result:=os2K;
    end;
    if (OS.dwMajorVersion=5) and (OS.dwMinorVersion=1) then
      Result:=osXP;
    if (OS.dwMajorVersion=6) and (OS.dwMinorVersion=0) then
      Result:=osVista;
    if (OS.dwMajorVersion=6) and (OS.dwMinorVersion=1) then
      Result:=osWin7;
  end else begin
    if (OS.dwMajorVersion=4) and (OS.dwMinorVersion=0) then begin
      Result:=os95;
      if (Trim(OS.szCSDVersion)='B') then
        Result:=os95OSR2;
    end else
      if (OS.dwMajorVersion=4) and (OS.dwMinorVersion=10) then begin
        Result:=os98;
        if (Trim(OS.szCSDVersion)='A') then
          Result:=os98SE;
      end else
        if (OS.dwMajorVersion=4) and (OS.dwMinorVersion=90) then
          Result:=osME;
  end;
end;

문자열을 보내는 함수
procedure TFuncCommon.SendMsg(AHandel: THandle; AMsg: string);
var
  CDS: TCopyDataStruct;
  S2 : pchar;
  S1 :string;
begin
  try
    if AMsg = '' then
      exit;
    if AHandel = 0 then
      exit;

    FillChar(CDS,SizeOf(TCopyDataStruct),#0);
    if GetOS = osWin7 then                     //window7의 경우
    begin
      S1 := AMsg + #0;
      CDS.lpData := pChar(S1);
      CDS.cbData := Length(S1)* 2;
    end else
    begin
      S2 := PChar( AMsg );
      CDS.lpData := S2;
      CDS.cbData := Length( S2 ) + 1;
    end;
    SendMessageW(AHandel, WM_COPYDATA, 0, LongInt(@CDS));
  except
    //mmoLog.Lines.Add(Exception(ExceptObject).Message);
  end;
end;

문자열을 받는 exe파일이고요
procedure TUploadMain.WMCopyData(var Msg: TWMCopyData);
var
  Param : String;
Begin
  Param := String(PChar(Msg.CopyDataStruct^.lpData));
  FuncCommon.ExtractCommand(Param);
end;

위와 같이 하면 문제가 전혀 없는데
이 실행파일들을
programs Files(X86)\AAAA\안에 복사하고 실행하면
두 프로그램간에는 문제가 없는데
서버로부터 문자열을 전달받으면 그전과 똑같은 현상이 벌어집니다.
무슨 방법이 없을까요?

programs Files(X86) 아래에 있다고 바뀌는 건지...황당하네요.
고수님들의 도움 부탁드립니다.

참고로 서버에서 login체크하고 결과 보내주는 서버데몬코드입니다.
void *file_send_thread(void *client_sock_arg)
{
        pthread_t tid;
        MYSQL *mysql;
        
        int client_sock;
        int retval;

        char info_buf[BUFSIZE];

        memset(info_buf,                0x00, BUFSIZE);
        
        tid =pthread_self();
        client_sock =(int)client_sock_arg;
        
        //*** DB Connection ***//
        mysql = (MYSQL*)DBConnect();
        if(!mysql)        {
                close(client_sock);
                pthread_exit(NULL);
                
                return;
        }
        else
                sys_msg('S',"[Login] DB Connection");
        
        retval = recvn(client_sock, info_buf, sizeof(LOGIN_DATA_INFO));

        if ( strncmp( info_buf+1, "$_UP_LOGIN_DATA_$", 17 ) )
        {
                if ( strncmp( info_buf+1, "$_DOWN_LOGIN_DATA_$", 19 ) )
                {
                        sys_msg('S',"[Loginload]====== The Wrong Packet! ========");
                        DBColse( mysql );
                        close(client_sock);
                        pthread_exit(NULL);
                        return;
                }        
        }

        //로그인 및 기타 정보 체크
        login_process( mysql, info_buf );

        retval = write(client_sock, info_buf, sizeof(LOGIN_DATA_RTN));
        if(retval == -1)
                sys_msg('E',"[Login] Socket Send Error!");
        else
                sys_msg('S',"[Login] Socket DATA Send");
        
        sys_msg('C',"[Login] Clinet Socket Close!!");
        DBColse( mysql );
        close(client_sock);
        pthread_exit(NULL);

}

6  COMMENTS
  • Profile
    땅콩맨 2010.03.31 19:37
    Naver Window 7 카페에서 찾아보니
    질문중 하나가 Program Files폴더가 2개가 존재하는데 무슨 문제가 있는것 아니냐는 질문이었습니다.
    답변인즉슨 하나는 64bit, 또 나머지 하나는 32bit용이라고 하더라고요...

    위의 내용에 비추어보았을때 32bit, 64bit의 차이로 잘리고 안잘리고의 차이가 아닐런지 짐작해봅니다.
  • Profile
    한윤동 2010.03.31 21:38
    네 그것을 저도 발견했는데요.
    program files(x86)이 32bit여서 그런 것 같습니다,
    문제는 시스템이 받아들이는 문자열이 64bit인데 델파이에서 이를 32bit로 받아들인다는 문제인데
    어떻게 해결해야할지..
    무조건 64비트로 인식할 수동없는게 window7이 32비트도 있고 XP등에서 사용한다면 또 문제가 발생하게 되니깐요
    따라서 델파이안에서 이를 구분할 수 있는 로직이나 함수가 필요할 것 같은데요...
  • Profile
    박정순 2010.03.31 22:30
    CDS.lpData 가 문자열 포인터를 가리키는 것 같은데...정적 배열로 사용하여 문자열을 배열에 복사하는 것은 어떨지...
  • Profile
    땅콩맨 2010.04.01 05:14
    COPYDATASTRUCT cds;

    cds.dwData // 사용목적에 따른 식별값
    cds.cbData; // 전달될 정보 lpData의 크기
    cds.lpData; // 전달될 정보의 포인터
    [출처] COPYDATASTRUCT |작성자 잭켈리

    위의 형식을 보면 lpDate의 크기를 정하는것이 cbData인데
    윤동님이 올려주신 소스에서는 cbData가 lpData이후에 선언되어서
    크기지정없이 값을 부여받아 잘릴수 있지 않을까 생각되는데 어떻게생각하세요?

  • Profile
    한윤동 2010.04.02 07:50
    문제 찾았습니다..님들이 말씀해주신것을 참조해서 디버깅하다보니
    문제가 GETOS 함수에 있네요
    이 함수가 programs Files(x86)안에서 구동되면 win7이 아니라 winXP로 올라오네요..
    그래서 이거를 바꿨더니 되네요...
    그간 답변주셔서 감사합니다.

    FillChar(CDS,SizeOf(TCopyDataStruct),#0);
    {$IFDEF WIN32}
    S1 := AMsg + #0;
    CDS.cbData := Length(S1)* 2;
    CDS.lpData := pChar(S1);
    {$else}
    S2 := PChar( AMsg );
    CDS.cbData := Length( S2 ) + 1;
    CDS.lpData := S2;
    {$ENDIF}
    SendMessageW(AHandel, WM_COPYDATA, 0, LongInt(@CDS));
  • Profile
    땅콩맨 2010.04.03 04:07
    윤동님
    올려주신 리플에 달린 소스를 살펴보니
    lpData와 cbData순서가 바뀌었느데 이것도 문제가 되었었던건지요?
    • lee, js
    • 2010.04.08 02:30
    • 5 COMMENTS
    • /
    • 0 LIKES
    • phono
      2010.04.08 08:16
      WITH구분이 가상테이블을 만들어 다시 셀렉트 하거나, INSERT도 되는 기능을 구현 한것 같은데.. 제가 ...
    • lee, js
      2010.04.08 20:23
      제가 with문을 사용한 것은 phono 님 말대로 sql문의 간소화를 위해 가상의 외상테이블과 현잔액 테이블...
    • phono
      2010.04.09 07:59
      일단 뽑아 낼수 없느냐 있느냐를 떠나.. 일단 이러한 구조가 어떠한 업무를 처리하는데 왜 필요한...
    • 땅콩맨
      2010.04.12 04:52
      lee, js님의 업무에 대한 추가적인 부연설명도 뒷따라야 할것같습니다
    • 성더기
      2010.04.12 20:19
      SQL만 가지고는 해결이 불가능할거 같네요 DBMS가 MS-SQL 이라면 프로시저나 function으로 처리가 가능...
    • Atom
    • 2010.04.06 20:24
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2010.04.06 20:36
      array[0..9] of PChar 는 씨로 말하면 char *가 10개 있는 배열입니다. Info_partNum: array[0..9] of P...
    • 땅콩맨
    • 2010.04.07 08:08
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 송동진
    • 2010.04.06 01:05
    • 8 COMMENTS
    • /
    • 0 LIKES
    • phono
      2010.04.06 01:30
      DB 엔진을 무엇을 쓰느냐에 따라 틀려지지요..
    • 송동진
      2010.04.06 01:52
      DB 는 파이어버드 2.0 입니다.
    • 땅콩맨
      2010.04.06 02:56
      INNER JOIN 방법을 사용하시면 될 듯 싶습니다. INNER JOIN(내부조인)은 각 테이블에서 비교 연사자에...
    • phono
      2010.04.06 08:56
      이너 조인이 아닌 아웃터 조인을 하세요.. 아웃터 조인은 두 테이블중 어느 한테이블에 자료가 존재하...
    • 성더기
      2010.04.07 02:45
      위의 경우라면 아우터 조인이 맞는거 같습니다. 아우터 조인을 하는 문법은 위 phono님께서 설명하신 것...
    • 송동진
      2010.04.07 05:43
      답변 감사합니다. 결과값 이 1 10 20100301 100 1 10 20100302 150 2 20 201...
    • 땅콩맨
      2010.04.07 07:59
      phono님이 위에 적으신대로 table B의 값을 번호별로 그룹핑하여 일자와 단가의 max값을 구하는 과정을 ...
    • • • •
    • 땅콩맨
      2010.04.04 21:07
      DB에서 값 Select하는 부분을 Loop로 돌려서 (이때 Richedit컨트롤을 메모리에 생성해서 Loop돌린갯수만...
    • 김영구
      2010.05.07 13:12
      시작부분이 ASCII 02번 () 이구요. 끝부분이 ASCII 03번 () 이네요. 시작과 끝 사이의 정보가 수신받...
    • 김정은
      2010.05.26 19:35
      (아스키2번 STX : 데이터 시작) ghgghg*^UU (아스키3번 ETX : 데이터 끝) *^UU -> 요 부분은 ...
    • 이용벽
    • 2010.04.03 10:22
    • 2 COMMENTS
    • /
    • 0 LIKES
    • phono
      2010.04.03 18:06
      서버측 프로그램이야 만들기 나름 아닐까요? 본래 서버라는 것은 "제공자"라는 의미로.. 클라이언트...
    • 땅콩맨
      2010.04.04 07:47
      P2P(Peer To Peer) 프로그램처럼 데이터를 받거나 보내는 기능 두가지를 원하시는건가요? 프루나같은 P2...
    • 강동엽
    • 2010.04.03 00:05
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 땅콩맨
      2010.04.03 07:14
      indy 컴포넌트를 설치하면서 버전정보를 인식하는부분에서 조금 다르게 인식한것같습니다. 라이브러리패...
    • 지환부
      2010.04.16 05:44
      indy 컴퍼넌트가 버전별 속성문제 인듯합니다. 버전이 업그레이드 될경우 하위 버전에있던 속성들이 변...
    • 서선영
    • 2010.04.02 21:04
    • 2 COMMENTS
    • /
    • 0 LIKES
    • phono
      2010.04.02 23:55
      1: String 타입으로 하시면 됩니다. 2: 해당데이터셋의 필드 에디터를 이용하셔서 데이터셋에 각각...
    • 땅콩맨
      2010.04.03 05:32
      phono님의 답변에 조금더 몇마디 덧붙이자면 (Dataset.FieldByName('yourDateFieldName) as TDateTimeFi...
    • lee, js
    • 2010.04.02 02:15
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 땅콩맨
      2010.04.02 03:15
      날짜와 날짜간에 금액계산이 연관되어서 계속 이루어져야하기 때문에 마지막 결제일이란 항목도 필요할 ...
    • phono
      2010.04.02 18:29
      많은 분들이 미수금(미지급금) 처리를 위해 입금, 매출(매입)을 분리 해서 처리 하는 경향이 있더군...
    • phono
      2010.04.02 18:40
      그리고 이러한 구조의 테이블 기준으로 해서 거래 이력을 생성해주면.. 사용자로 부터 입력받는 ...
    • 땅콩맨
      2010.04.03 04:12
      와 phono님 명쾌하게 답변을 해주셨네요. phono님 답변에 비추어보면 lee, js님이 설계하신 DB구조는 ...
    • lee, js
    • 2010.04.01 19:22
    • 4 COMMENTS
    • /
    • 0 LIKES
    • phono
      2010.04.01 19:52
      저는 ms-sql 7.0 이라.. 사이즈가 256이 한곈데, 요즘은 varchar가 4000 도 되는군요.. 일단 재고...
    • 땅콩맨
      2010.04.02 03:06
      그럼 phono님은 어떻게 처리하시는데요?
    • phono
      2010.04.02 18:07
      보통 저같은 경우는.. 품목별로 년 마감 테이블을 만들고.. 1년치 데이터는 전표에서 끌어오고 1년...
    • 땅콩맨
      2010.04.03 04:14
      아 테이블을 나눠서 처리가 되는거네요 그렇게되면 데이터관리하거나 처리할때 더 효과적이겠네요.
    • 배성철
    • 2010.04.01 13:54
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 땅콩맨
      2010.04.02 03:05
      예전에 영진출판사에서 발간된 Delphi Programming Bible이란 책이 있습니다. 이 책을 참고하시면 좀...
    • 한윤동
    • 2010.03.31 09:01
    • 6 COMMENTS
    • /
    • 0 LIKES
    • 땅콩맨
      2010.03.31 19:37
      Naver Window 7 카페에서 찾아보니 질문중 하나가 Program Files폴더가 2개가 존재하는데 무슨 문제가 ...
    • 한윤동
      2010.03.31 21:38
      네 그것을 저도 발견했는데요. program files(x86)이 32bit여서 그런 것 같습니다, 문제는 시스템이 받...
    • 박정순
      2010.03.31 22:30
      CDS.lpData 가 문자열 포인터를 가리키는 것 같은데...정적 배열로 사용하여 문자열을 배열에 복사하는 ...
    • 땅콩맨
      2010.04.01 05:14
      COPYDATASTRUCT cds; cds.dwData // 사용목적에 따른 식별값 cds.cbData; // 전달될 정...
    • 한윤동
      2010.04.02 07:50
      문제 찾았습니다..님들이 말씀해주신것을 참조해서 디버깅하다보니 문제가 GETOS 함수에 있네요 이 함...
    • 땅콩맨
      2010.04.03 04:07
      윤동님 올려주신 리플에 달린 소스를 살펴보니 lpData와 cbData순서가 바뀌었느데 이것도 문제가 되었...
    • lee, js
    • 2010.03.30 04:20
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 땅콩맨
      2010.03.30 06:26
      select 일자, 외상금액-입금 as Field2 from tbl order by 일자 desc 로 돌려서 찍어주면 되지 않을까요?
    • phono
      2010.03.30 19:18
      오라클과 MS-SQL을 쓰신다면 row-num과, decode(오라클사용시), case문(ms-sql 사용시) 을 이용하세...
    • shininggem
      2010.03.30 19:18
      설명만으론 쿼리를 구하기가 난해하네요. 테이블 구조를 알아야.... 일단 생각나는 방식은, 현재 잔...
    • phono
      2010.03.30 19:28
      외상금액 누적 처리는 날짜값을 기준으로 서브쿼리와 상관 서브쿼리를 이용하시고.. 이렇게 해서 ...
    • phono
      2010.03.28 21:54
      Screen.Cursor := crSQLWait; ... 쿼리 처리... Screen.Cursor := crDefault;
    • 박성훈
      2010.03.28 23:36
      try Screen.Cursor := crSQLWait; {Code for handling database here...} finally Sc...
    • 땅콩맨
      2010.03.29 02:55
      아, 지나가다 한수배우고 갑니다.
    • 조약돌
      2010.03.29 03:07
      답변 감사합니다. sql모래시계 커서 모양이 마음에 안들어서 윈도우에서 사용하는 모래시계 ...
    • 한윤동
    • 2010.03.28 08:01
    • 9 COMMENTS
    • /
    • 0 LIKES
    • 땅콩맨
      2010.03.28 09:03
      액세스가 거부되었다면 Registry경로가 잘못되었다는 이야기일텐데요? 소스상에 명시된 레지스트리 경로...
    • 한윤동
      2010.03.28 09:12
      경로는 이상이 없거든요.. 이게 XP에서는 전혀 이상이 없어여... Window7에서만 엑서스가 거부되는데요...
    • 땅콩맨
      2010.03.28 09:50
      보통 관리자 권한이 아닐때 발생되긴 하는데... 관리자 권한이 아닐리도 없을테구요 음. Windows7에 파...
    • 한윤동
      2010.03.28 10:24
      답변주셔서 감사합니다. 일단 Activex파일을 잘 열립니다,. openkkey()에서 오류가 나는 건데요... 다...
    • 땅콩맨
      2010.03.29 02:53
      Windows7하고 XP와는 많이 다를것입니다. API함수도 지원하는것도 있고, 다른 이름으로 변경된것도 있을...
    • 한윤동
      2010.03.29 21:17
      procedure TForm1.Button2Click(Sender: TObject); var LocalReg : TRegistry; AppRegPath : stri...
    • 한윤동
      2010.03.29 21:39
      //RootKey := HKEY_LOCAL_MACHINE; 를 풀어 RootKey := HKEY_LOCAL_MACHINE; 로 하면 하나도 안 읽혀여
    • • • •
    • 김선웅
    • 2010.03.27 08:10
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 땅콩맨
      2010.03.28 09:04
      uses 절에 SysConst를 선언해 주심됩니다.
    • 김정국
    • 2010.03.27 01:55
    • 8 COMMENTS
    • /
    • 0 LIKES
    • 김정국
      2010.03.27 02:04
      추가... 어찌어찌 하다가.. Conn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data...
    • 땅콩맨
      2010.03.27 06:42
      파라독스 DB를 MSSQL등의 다른 DB형태로 포팅을 해보시는 방법도 고려해 볼 수 있지 않을까요?
    • phono
      2010.03.27 08:19
      ado를 사용해서 파라독스 db에 접근해야 할텐데요.. 아마 윈도우에서 기본적으로 제공되는 파라독스 db...
    • 김정국
      2010.03.27 17:45
      아...결국 안되는거군요...ㅠㅠ 한번만 열어 보려는건 아니구여...ㅠㅠ view.db에는 계속 적으로 ...
    • phono
      2010.03.27 21:28
      델파이툴에 보믄 데이터 펌프라는게 있습니다. 이걸 어디서 구할수 있다면.., 이걸로 일단 파라독스 ...
    • 땅콩맨
      2010.03.28 08:49
      ado로 해서.. 그 다음은 뭐죠? ㅋㅋ ^^ 정국님, phono님 말씀대로 포팅하는것도 한가지 방법입니다. ...
    • phono
      2010.03.28 10:21
      재개발 한다면 아마 정국님이 vb쪽이나 ms 쪽을 쓰고 있는 것 같으므로 델파이쪽도 ado를 이용해서 개...
    • • • •