Click here to Skip to main content
15,887,135 members
Articles / Desktop Programming / ATL

Increment File and Product Version Number - Multiple IDE

Rate me:
Please Sign up or sign in to vote.
4.58/5 (32 votes)
21 Oct 2008CPOL12 min read 290.8K   1.2K   134  
An add-in to automatically increment the FileVersion and ProductVersion fields in your application's resource file. Works in VC6 and VS2005, and probably all versions in between.
/**
 * \file AddIn.cpp
 *
 * \brief Implementation file for class CAddIn
 *
 * $Id: AddIn.cpp, v1.1.1.1 2006/09/24 23:12:29 mgh Exp $
 *
 *
 * Copyright (C) 2006 Michael G. Herstine <sp1ff@pobox.com>
 *
 * Permission to use, copy, or modify this source code is hereby granted
 * free of charge, provided that this copyright notice appear on all
 * copies and on all source code derived from this code.  No
 * representation is made regarding the suitability of this software for
 * any purpose.  It is provided "as is" without express or implied
 * warranty.
 *
 *
 */

////////////////////////////////////////////////////////////////////////////
// Modified by Jordan Walters, 01.03.2008 for multi-IDE version increment //
////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"             // Pre-compiled header for this project
#include "AddIn.h"              // Class CAddIn
#include "DSAddIn.h"            // Class CDSAddIn
#include "DTEAddIn.h"           // Class DTEAddIn
#include "ConfigDlg.h"          // Class CConfigDlg
#include "Increment.h"

//#include "../JLogging/Logging.h"

////////////////////////////////////////////////////////////////////////

HRESULT CIncVersionModule::AddCommonRGSReplacements(IRegistrarBase* pRegistrar)
{
	USES_CONVERSION_EX;

	HRESULT hr = CAtlDllModuleT<CIncVersionModule>::AddCommonRGSReplacements(pRegistrar);

	if (FAILED(hr)) return hr;

	// We're going to add a new replacement parameter: MODULE_PATH:
	HINSTANCE hInstance = _AtlBaseModule.GetModuleInstance();

	wchar_t lpszModule[MAX_PATH];
	DWORD dwLen = ::GetModuleFileNameW(hInstance, lpszModule, MAX_PATH);

	if (0 == dwLen)
	{
		return AtlHresultFromLastError();
	}
	else if (MAX_PATH == dwLen)
	{
		return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
	}

	if (!::PathRemoveFileSpecW(lpszModule))
	{
		return AtlHresultFromLastError();
	}

	LPOLESTR lpszPath;
	lpszPath = W2OLE_EX(lpszModule, _ATL_SAFE_ALLOCA_DEF_THRESHOLD);

	return pRegistrar->AddReplacement(OLESTR("MODULE_PATH"), lpszPath);
}

////////////////////////////////////////////////////////////////////////
// Class CAddIn

CAddIn::CAddIn()
{
}

/**
 * \brief ATL-defined initialization routine
 *
 *
 * \return S_OK on success, a failed HRESULT on failure to abort
 * instance creation
 *
 *
 * Here is where we aggregate our sub-objects.
 *
 *
 * \todo Move to some sort of cached scheme to avoid instantiating an
 * instance of, say, CoDTEAddIn when we're loaded into DevStudio...
 *
 *
 */
HRESULT CAddIn::FinalConstruct()
{
	std::wstring strFunction = std::wstring(CT2W(__FUNCTION__)) + L"\n";
	ATLTRACE2(atlTraceCOM, 2, strFunction.c_str());

	HRESULT hr = S_OK;
	IUnknown *pOuterUnk = GetControllingUnknown();

	hr = CreateInstanceWithParamItf(pOuterUnk, this, &m_pDSAddIn,
		(CComAggObject<CDSAddIn>**)NULL);
	if (FAILED(hr)) return hr;

	hr = CreateInstanceWithParamItf(pOuterUnk, this, &m_pDTEAddIn,
		(CComAggObject<CDTEAddIn>**)NULL);
	if (FAILED(hr)) return hr;

	return S_OK;
}

/**
 * \brief ATL-defined cleanup routine
 *
 *
 * \note We release our references on our aggregates in this routine
 *
 *
 */
void CAddIn::FinalRelease()
{
	std::wstring strFunction = std::wstring(CT2W(__FUNCTION__)) + L"\n";
	ATLTRACE2(atlTraceCOM, 2, strFunction.c_str());

	m_pDSAddIn  = NULL;           // Release our references
	m_pDTEAddIn = NULL;
}

////////////////////////////////////////////////////////////////////////
// Interface ISupportsErrorInfo

STDMETHODIMP CAddIn::InterfaceSupportsErrorInfo(/*[in]*/ REFIID riid)
{
	static const IID* arr[] = { &IID_IDSAddIn,
		&EnvDTE::IID_IDTCommandTarget,
		&AddInDesignerObjects::IID__IDTExtensibility2,
	};

	for (int i = 0; i < sizeof(arr)/sizeof(arr[0]); ++i)
	{
		if (InlineIsEqualGUID(*arr[i],riid)) return S_OK;
	}

	return S_FALSE;
}


void CAddIn::Configure()
{
	std::wstring strFunction = std::wstring(CT2W(__FUNCTION__)) + L"\n";
	ATLTRACE2(atlTraceCOM, 2, strFunction.c_str());

	CConfigDlg dlg;
	bool bEnabled = DEF_ENABLED;
	bool bActiveProjectOnly = DEF_ACTIVE_PROJ_ONLY;
	bool bIncrementWithErrors = DEF_INCREMENT_WITH_ERRORS;
	bool bIncrementFileVersion = DEF_FILE_VERSION;
	bool bIncrementProductVersion = DEF_PRODUCT_VERSION;
	bool bIncrementPrivateBuild = DEF_PRIVATE_BUILD;
	bool bIncrementSpecialBuild = DEF_SPECIAL_BUILD;
	DWORD dwDigit = DEF_DIGIT;
	bool bResetLowerVersions = DEF_RESET;
	bool bRevertToBuildNumber = DEF_REVERT;
	bool bDisplayWarnings = DEF_DISPLAY_WARNINGS;
	CRegistryFns::getGeneralOptionsFromReg(bEnabled, bActiveProjectOnly, bIncrementWithErrors, bDisplayWarnings);
	CRegistryFns::getCPPOptionsFromReg(bIncrementFileVersion, bIncrementProductVersion, bIncrementPrivateBuild, bIncrementSpecialBuild,
		dwDigit, bResetLowerVersions, bRevertToBuildNumber);
	dlg.setDigit(dwDigit);
	dlg.setResetLowerVersions(bResetLowerVersions);
	dlg.setRevertToBuildNumber(bRevertToBuildNumber);
	dlg.setDisplayWarnings(bDisplayWarnings);
	if (IDOK == dlg.DoModal())
	{
		CRegistryFns::setGeneralOptionsToReg(dlg.getEnabled(), dlg.getActiveProjectOnly(), dlg.getIncrementWithErrors(), dlg.getDisplayWarnings());
		CRegistryFns::setCPPOptionsToReg(dlg.getIncrementFileVersion(), dlg.getIncrementProductVersion(), dlg.getIncrementPrivateBuild(), dlg.getIncrementSpecialBuild(),
			dlg.getDigit(), dlg.getResetLowerVersions(), dlg.getRevertToBuildNumber());
	}
}

// Local Variables:
// fill-column: 72
// indent-tabs-mode: nil
// show-trailing-whitespace: t
// End:

// AddIn.cpp ends here.

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United Kingdom United Kingdom
Ok, it's about time I updated this profile. I still live near 'Beastly' Eastleigh in Hampshire, England. However I have recently been granted a permamant migration visa to Australia - so if you're a potential employer from down under and like the look of me, please get in touch.
Still married - just, still with just a son and daughter. But they are now 8 and 7 resp and when together they have the energy of a nuclear bomb.
I worked at Teleca UK for over 8.5 years (but have now moved to TikitTFB) and have done loads of different things. Heavily involved with MFC, SQL, C#, The latest is ASP.NET with C# and Javascript. Moving away from Trolltech Qt3 and 4.
Jordan.

Comments and Discussions