home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 June / Chip_2001-06_cd1.bin / zkuste / vbasic / Data / Utility / MSISDK15.msi / MsiMerg.cpp < prev    next >
C/C++ Source or Header  |  2000-10-05  |  6KB  |  198 lines

  1. #if 0  // makefile definitions
  2. DESCRIPTION = Merge Database Utility
  3. MODULENAME = MsiMerg
  4. SUBSYSTEM = console
  5. FILEVERSION = Msi
  6. LINKLIBS = OLE32.lib
  7. !include "..\TOOLS\MsiTool.mak"
  8. !if 0  #nmake skips the rest of this file
  9. #endif // end of makefile definitions
  10.  
  11. //+-------------------------------------------------------------------------
  12. //
  13. //  Microsoft Windows
  14. //
  15. //  Copyright (C) Microsoft Corporation, 1997 - 2000
  16. //
  17. //  File:       msimerg.cpp
  18. //
  19. //--------------------------------------------------------------------------
  20.  
  21. //-----------------------------------------------------------------------------------------
  22. //
  23. // BUILD Instructions
  24. //
  25. // notes:
  26. //    - SDK represents the full path to the install location of the
  27. //     Windows Installer SDK
  28. //
  29. // Using NMake:
  30. //        %vcbin%\nmake -f msimerg.cpp include="%include;SDK\Include" lib="%lib%;SDK\Lib"
  31. //
  32. // Using MsDev:
  33. //        1. Create a new Win32 Console Application project
  34. //      2. Add msimerg.cpp to the project
  35. //      3. Add SDK\Include and SDK\Lib directories on the Tools\Options Directories tab
  36. //      4. Add msi.lib to the library list in the Project Settings dialog
  37. //          (in addition to the standard libs included by MsDev)
  38. //
  39. //------------------------------------------------------------------------------------------
  40.  
  41. #define W32DOWS_LEAN_AND_MEAN  // faster compile
  42. #define W32
  43. #define MSI
  44.  
  45. #include <windows.h>
  46. #ifndef RC_INVOKED    // start of source code
  47. #include <tchar.h>    // define UNICODE=1 on nmake command line to build UNICODE
  48. #include <stdio.h>
  49. #include "MsiQuery.h" // MSI API
  50.  
  51. //________________________________________________________________________________
  52. //
  53. // Constants and globals
  54. //________________________________________________________________________________
  55.  
  56. const TCHAR szHelp[] = TEXT("Copyright (C) Microsoft Corporation, 1997-2000.  All rights reserved.\nMsi Merge Tool --- Merge Two Databases\n\nMsiMerg(d).exe {base db} {ref db}\n");
  57. const TCHAR szTable[] = TEXT("_MergeErrors");
  58.  
  59. const int cchDisplayBuf = 4096;                                        
  60. HANDLE g_hStdOut;
  61. TCHAR g_rgchBuffer[4096];
  62.  
  63. //________________________________________________________________________________
  64. //
  65. // Function prototypes
  66. //________________________________________________________________________________
  67.  
  68. void Display(LPCTSTR szMessage);
  69. void ErrorExit(UINT iError, LPCTSTR szMessage);
  70. void CheckError(UINT iError, LPCTSTR szMessage);
  71. void Merge(TCHAR* szBaseDb, TCHAR* szRefDb);
  72.  
  73. //_____________________________________________________________________________________________________
  74. //
  75. // main 
  76. //_____________________________________________________________________________________________________
  77.  
  78. extern "C" int __cdecl _tmain(int argc, TCHAR* argv[])
  79. {
  80.     // Determine handle
  81.     g_hStdOut = ::GetStdHandle(STD_OUTPUT_HANDLE);
  82.     if (g_hStdOut == INVALID_HANDLE_VALUE)
  83.         g_hStdOut = 0;  // non-zero if stdout redirected or piped
  84.     
  85.     if (argc == 2 && ((_tcscmp(argv[1], TEXT("-?")) == 0) || (_tcscmp(argv[1], TEXT("/?")) == 0)))
  86.         ErrorExit( 0, szHelp);
  87.  
  88.     // Check for enough arguments and valid options
  89.     CheckError(argc != 3, TEXT("msimerg(d).exe {base db} {ref db}"));
  90.     Merge(argv[1], argv[2]);
  91.     ErrorExit(0, TEXT("Done"));
  92.     return 0;
  93. }
  94.  
  95.  
  96. //________________________________________________________________________________
  97. //
  98. // Merge function
  99. //    Merge(...);
  100. //________________________________________________________________________________
  101.  
  102. void Merge(TCHAR* szBaseDb, TCHAR* szRefDb)
  103. {
  104.     PMSIHANDLE hBaseDb = 0;
  105.     PMSIHANDLE hRefDb = 0;
  106.  
  107.     CheckError(MSI::MsiOpenDatabase(szBaseDb, MSIDBOPEN_TRANSACT, &hBaseDb), TEXT("Error Opening Base Database"));
  108.     CheckError(MSI::MsiOpenDatabase(szRefDb, MSIDBOPEN_READONLY, &hRefDb), TEXT("Error Opening Reference Databaes"));
  109.     UINT uiError = MSI::MsiDatabaseMerge(hBaseDb, hRefDb, szTable);
  110.     CheckError(MSI::MsiDatabaseCommit(hBaseDb), TEXT("Error Saving Database"));
  111.     CheckError(uiError, TEXT("Error Merging Database, Check _MergeErrors Table for Merge conflicts"));
  112. }
  113.  
  114. //________________________________________________________________________________
  115. //
  116. // Error handling and Display functions:
  117. //    Display(...);
  118. //       ErrorExit(...);
  119. //    CheckError(...);
  120. //
  121. //________________________________________________________________________________
  122.  
  123. void Display(LPCTSTR szMessage)
  124. {
  125.     if (szMessage)
  126.     {
  127.         int cbOut = _tcsclen(szMessage);;
  128.         if (g_hStdOut)
  129.         {
  130. #ifdef UNICODE
  131.             char rgchTemp[cchDisplayBuf];
  132.             if (W32::GetFileType(g_hStdOut) == FILE_TYPE_CHAR)
  133.             {
  134.                 W32::WideCharToMultiByte(CP_ACP, 0, szMessage, cbOut, rgchTemp, sizeof(rgchTemp), 0, 0);
  135.                 szMessage = (LPCWSTR)rgchTemp;
  136.             }
  137.             else
  138.                 cbOut *= sizeof(TCHAR);   // write Unicode if not console device
  139. #endif
  140.             DWORD cbWritten;
  141.             W32::WriteFile(g_hStdOut, szMessage, cbOut, &cbWritten, 0);
  142.         }
  143.         else
  144.             W32::MessageBox(0, szMessage, W32::GetCommandLine(), MB_OK);
  145.     }
  146. }
  147.  
  148.  
  149. void ErrorExit(UINT iError, LPCTSTR szMessage)
  150. {
  151.     if (szMessage)
  152.     {
  153.         int cbOut;
  154.         TCHAR szBuffer[256];  // errors only, not used for display output
  155.         if (iError == 0)
  156.             cbOut = lstrlen(szMessage);
  157.         else
  158.         {
  159.             LPCTSTR szTemplate = (iError & 0x80000000L)
  160.                                         ? TEXT("Error 0x%X. %s\n")
  161.                                         : TEXT("Error %i. %s\n");
  162.             cbOut = _stprintf(szBuffer, szTemplate, iError, szMessage);
  163.             szMessage = szBuffer;
  164.         }
  165.         if (g_hStdOut)
  166.         {
  167. #ifdef UNICODE
  168.             char rgchTemp[cchDisplayBuf];
  169.             if (W32::GetFileType(g_hStdOut) == FILE_TYPE_CHAR)
  170.             {
  171.                 W32::WideCharToMultiByte(CP_ACP, 0, szMessage, cbOut, rgchTemp, sizeof(rgchTemp), 0, 0);
  172.                 szMessage = (LPCWSTR)rgchTemp;
  173.             }
  174.             else
  175.                 cbOut *= sizeof(TCHAR);   // write Unicode if not console device
  176. #endif // UNICODE
  177.             DWORD cbWritten;
  178.             W32::WriteFile(g_hStdOut, szMessage, cbOut, &cbWritten, 0);
  179.         }
  180.         else
  181.             W32::MessageBox(0, szMessage, W32::GetCommandLine(), MB_OK);
  182.     }
  183.     MSI::MsiCloseAllHandles();
  184.     W32::ExitProcess(szMessage != 0);
  185. }
  186.  
  187. void CheckError(UINT iError, LPCTSTR szMessage)
  188. {
  189.     if (iError != ERROR_SUCCESS)
  190.         ErrorExit(iError, szMessage);
  191. }
  192.  
  193. #else // RC_INVOKED, end of source code, start of resources
  194. #endif // RC_INVOKED
  195. #if 0 
  196. !endif // makefile terminator
  197. #endif
  198.