2010-07-30 6 views
1

데이터베이스에 연결하는 프로그램을 설치하기 위해 WiX 설치 프로그램을 만듭니다. 이제CustomAction이 개발 컴퓨터에서 성공하고 배포 컴퓨터에서 오류가 발생합니다.

extern "C" UINT __stdcall DBConTest(MSIHANDLE hInstaller) 

{

FILE *fp; 
fp = fopen("dbcontestdll.txt", "w"); 
_ConnectionPtr pCon; 
int iErrCode; 
HRESULT hr; 
UINT rc; 
//init COM 

fwprintf(fp, L"entering dbcontest\n"); 
if(FAILED(hr = CoInitializeEx(NULL,tagCOINIT::COINIT_APARTMENTTHREADED))) 
    return ERROR_INVALID_DATA; 

fwprintf(fp,L"did coinit\n"); 
if(FAILED(hr = pCon.CreateInstance(__uuidof(Connection)))) 
    return ERROR_INVALID_DATA; 

fwprintf(fp,L"created instance of connection\n"); 
TCHAR constr[1024]; 
DWORD constrlen = sizeof(constr); 
rc=MsiGetProperty(hInstaller,TEXT("DBCONNECTIONSTRING"), constr, &constrlen); 

fwprintf(fp, L"dbconstring is: %s\n", constr); 
TCHAR serverstr[1024]; 
DWORD serverstrlen = sizeof(serverstr); 
rc = MsiGetProperty(hInstaller,TEXT("SQLINSTANCE"),serverstr,&serverstrlen); 

fwprintf(fp, L"SQLINSTANCE is: %sl\n",serverstr); 
TCHAR finalconstr[2048]; 
swprintf(finalconstr,L"%s; Data Source=%s;",constr,serverstr); 
try{ 
    hr = pCon->Open(finalconstr,TEXT(""),TEXT(""),adConnectUnspecified); 
} 
catch(_com_error ce){ 

    fwprintf(fp, L"%s\n", msg); 
    ::MessageBox(NULL,msg,NULL,NULL); 
    CoUninitialize(); 
    MsiSetProperty(hInstaller,TEXT("DBCONNECTIONVALID"),TEXT("0")); 
    return ERROR_SUCCESS; 

} 
if(FAILED(hr)){ 
    MsiSetProperty(hInstaller,TEXT("DBCONNECTIONVALID"),TEXT("0")); 
    return ERROR_SUCCESS; 

} 
pCon->Close(); 
CoUninitialize(); 
MsiSetProperty(hInstaller,TEXT("DBCONNECTIONVALID"),TEXT("1")); 
::MessageBox(NULL,TEXT("Successfully connected to the database!"),NULL,NULL); 
fwprintf(fp, L"leaving...\n"); 
fclose(fp); 
return ERROR_SUCCESS; 

}

,이 돕기 위해, 나는 SQL의 특정 인스턴스가 서버에 존재하는지 확인하는 C DLL을 만들었습니다 이 함수를 dll에 빌드하고 내 WiX 프로젝트에 추가하면이 코드는 내 개발 컴퓨터에서 작동합니다 (특히 설치가 성공적으로 끝나고 "dbcontestdll.txt"파일이 존재하며 올바른 데이터가 있음).하지만, "새로 설치"컴퓨터에서 실행하면 설치가 종료 코드 2896으로 실패합니다. "dbcontestdll.txt"가 작성되지 않았습니다.

Windows Installer에서 C++ 재배포 가능 파일과 같은 C 기반 dll을 사용하기위한 전제 조건이 있습니까?

답변

1

사용자 지정 작업의 경우 정적으로 C 런타임에 링크하는 것이 좋습니다. 사용자 지정 aciton DLL은 약간 더 커지 만 사용자 지정 동작 외부의 파일에 대한 종속성은 하나가 낮습니다.

+0

나는이 솔루션을 사용하여 끝났다./MD 스위치 대신/MT 스위치를 사용했습니다. – Davidann

0

예 Visual C 런타임이 필요할 수 있습니다. Dependency Walker은 필요한 dll을 찾는 데 도움이 될 수 있습니다.

이 예제를 보면 use a Bootstrapper입니다. 이렇게하면 msi를 실행하기 전에 런타임을 설치할 수 있습니다.

<BootstrapperFile Include="Microsoft.Visual.C++.9.0.x86"> 
    <ProductName>Visual C++ 2008 Runtime Libraries (x86)</ProductName> 
</BootstrapperFile> 

이 패키지는 일반적으로 C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages\vcredist_x86 디렉토리에 저장됩니다 : 나는 다음과 같은 부트 스트 래퍼 라인을 사용합니다.

2

아마도 사용자 지정 작업을 실행하기 위해 C++ 재시작자를 부트 스트랩해야하는 상황에 들기를 원하지 않을 것입니다. 파일 | 새로운 | WiX와 함께 제공되는 C++ 사용자 정의 액션 이를 사용하여 CA를 스텁 (stub) 한 다음 코드를 복사하여 붙여 넣을 수 있습니다. 이 문제를 피하기 위해 필요한 모든 컴파일러와 링커 설정을 제공해야합니다.

0

이 문제도 발생했습니다. 기본적으로 동적으로 연결되어있는 MFC DLL을 가지고 있으며 패키지에 MSVCR100.DLL을 포함시키는 것을 잊었습니다. 물론 개발 컴퓨터에서 잘 작동했지만 대부분의 고객의 컴퓨터에서도 작동했지만 오래된 Vista PC에서는 실패했습니다. 나는 정적으로 링크를 바꿨다.

관련 문제