// Add a command to DevStudio // Creates a toolbar button for the command also. // 'MethodName' is the name of the method specified in the .odl file // 'StrResId' the resource id of the descriptive string // 'GlyphIndex' the image index into the command buttons bitmap // Return true on success // bool CDSAddIn::AddCommand (IApplication* pApp, char* MethodName, char* CmdName, UINT StrResId, UINT GlyphIndex, VARIANT_BOOL bFirstTime) { CString CmdString; CString CmdText; CmdText.LoadString (StrResId); CmdString = CmdName; CmdString += CmdText; CComBSTR bszCmdString (CmdString); CComBSTR bszMethod (MethodName); CComBSTR bszCmdName (CmdName); // (see stdafx.h for the definition of VERIFY_OK) VARIANT_BOOL bRet; VERIFY_OK (pApp->AddCommand (bszCmdString, bszMethod, GlyphIndex, m_dwCookie, &bRet)); if (bRet == VARIANT_FALSE) { // AddCommand failed because a command with this name already exists. ReportInternalError ("IApplication::AddCommand"); return FALSE; } // Add toolbar buttons only if this is the first time the add-in // is being loaded. Toolbar buttons are automatically remembered // by Developer Studio from session to session, so we should only // add the toolbar buttons once. if (bFirstTime == VARIANT_TRUE) VERIFY_OK (pApp->AddCommandBarButton (dsGlyph, bszCmdName, m_dwCookie)); return TRUE; }
STDMETHODIMP CCommands::UpdateVersionCommand() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: Replace this with the actual code to execute this command // Use m_pApplication to access the Developer Studio Application object, // and VERIFY_OK to see error strings in DEBUG builds of your add-in // (see stdafx.h) VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE)); m_dlgOption.DoModal(); VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE)); return S_OK; }
void CCommands::UnadviseFromEvents () { ASSERT (m_pApplicationEventsObj != NULL); if (m_pApplicationEventsObj) { m_pApplicationEventsObj->Disconnect (m_pApplication); m_pApplicationEventsObj->Release (); m_pApplicationEventsObj = NULL; } #ifdef NEVER if (m_pDebuggerEventsObj) { // Since we were able to connect to the Debugger events, we // should be able to access the Debugger object again to // unadvise from its events (thus the VERIFY_OK below--see // stdafx.h). CComPtr < IDispatch > pDebugger; VERIFY_OK (m_pApplication->get_Debugger (&pDebugger)); ASSERT (pDebugger != NULL); m_pDebuggerEventsObj->Disconnect (pDebugger); m_pDebuggerEventsObj->Release (); m_pDebuggerEventsObj = NULL; } #endif }
//------------------------------------------------------------------------------ // This function launches the ModelBuild GUI. //------------------------------------------------------------------------------ void CCommands::StartCodeRover(const char *projectName, const char *projectFileName) { char homeName[2048]; DWORD result = GetEnvironmentVariable("CODE_ROVER_HOME", homeName, sizeof(homeName)); if(result == 0) { VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE)); ::MessageBox(NULL, "Enviroment variable CODE_ROVER_HOME is not set.", "Code Rover Addin", MB_OK | MB_ICONINFORMATION); VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE)); return; } STARTUPINFO sInfo; memset(&sInfo, 0, sizeof(sInfo)); sInfo.cb = sizeof(sInfo); PROCESS_INFORMATION pInfo; memset(&pInfo,0,sizeof(PROCESS_INFORMATION)); CString commandLine; if(projectName != NULL) commandLine += "-projectName \"" + CString(projectName) + "\""; if(projectFileName != NULL) commandLine += " -projectFile \"" + CString(projectFileName) + "\""; char *commandLineBuf = new char[commandLine.GetLength() + 2]; strcpy(commandLineBuf, commandLine); char callString[2048]; strcpy(callString,"\""); strcat(callString,homeName); strcat(callString,"\\bin\\mbdriver.exe\" "); strcat(callString," "); strcat(callString,commandLineBuf); sInfo.wShowWindow =SW_HIDE; sInfo.dwFlags = STARTF_USESHOWWINDOW; if(!::CreateProcess(NULL, callString, NULL, NULL, TRUE, 0, NULL, NULL, &sInfo, &pInfo)) { free(commandLineBuf); CString msg; msg.Format("Unable to start %s\\bin\\mbdriver.exe", homeName); VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE)); ::MessageBox(NULL, msg, "Code Rover Addin", MB_OK | MB_ICONINFORMATION); VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE)); return; } free(commandLineBuf); }
STDMETHODIMP CCommands::ZipFolderCommand() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // TODO: Replace this with the actual code to execute this command // Use m_pApplication to access the Developer Studio Application object, // and VERIFY_OK to see error strings in DEBUG builds of your add-in // (see stdafx.h) VERIFY_OK(m_pApplication->EnableModeless(VARIANT_FALSE)); #ifdef _DEBUG m_dlgZipProj.DoModal(); #else MessageBox(NULL, "此功能未完成!", "Error", MB_OK | MB_ICONERROR); #endif // _DEBUG VERIFY_OK(m_pApplication->EnableModeless(VARIANT_TRUE)); return S_OK; }
// This is called when the user first loads the add-in, and on start-up // of each subsequent Developer Studio session STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime, long dwCookie, VARIANT_BOOL* OnConnection) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Store info passed to us IApplication* pApplication = NULL; if (FAILED(pApp->QueryInterface(IID_IApplication, (void**) &pApplication)) || pApplication == NULL) { *OnConnection = VARIANT_FALSE; return S_OK; } m_dwCookie = dwCookie; // Create command dispatch, send info back to DevStudio CCommandsObj::CreateInstance(&m_pCommands); m_pCommands->AddRef(); // The QueryInterface above AddRef'd the Application object. It will // be Release'd in CCommand's destructor. m_pCommands->SetApplicationObject(pApplication); // (see stdafx.h for the definition of VERIFY_OK) VERIFY_OK(pApplication->SetAddInInfo((long) AfxGetInstanceHandle(), (LPDISPATCH) m_pCommands, IDR_TOOLBAR_MEDIUM, IDR_TOOLBAR_LARGE, m_dwCookie)); // Inform DevStudio of the commands we implement // TODO: Replace the AddCommand call below with a series of calls, // one for each command your add-in will add. // The command name should not be localized to other languages. The // tooltip, command description, and other strings related to this // command are stored in the string table (IDS_CMD_STRING) and should // be localized. LPCTSTR szCommand = _T("ShowGroupsAddinCommand"); VARIANT_BOOL bRet; CString strCmdString; strCmdString.LoadString(IDS_CMD_STRING); strCmdString = szCommand + strCmdString; CComBSTR bszCmdString(strCmdString); CComBSTR bszMethod(_T("ShowGroupsAddinCommandMethod")); CComBSTR bszCmdName(szCommand); VERIFY_OK(pApplication->AddCommand(bszCmdString, bszMethod, 0, m_dwCookie, &bRet)); if (bRet == VARIANT_FALSE) { // AddCommand failed because a command with this name already // exists. You may try adding your command under a different name. // Or, you can fail to load as we will do here. *OnConnection = VARIANT_FALSE; return S_OK; } // Add toolbar buttons only if this is the first time the add-in // is being loaded. Toolbar buttons are automatically remembered // by Developer Studio from session to session, so we should only // add the toolbar buttons once. if (bFirstTime == VARIANT_TRUE) { VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, bszCmdName, m_dwCookie)); } // Create the WWhizInterface. g_wwhizInterface = WWhizInterface2Create(AfxGetInstanceHandle(), pApplication); *OnConnection = VARIANT_TRUE; return S_OK; }
/* * Alternate version of dvmResolveMethod(). * * Doesn't throw exceptions, and checks access on every lookup. * * On failure, returns NULL, and sets *pFailure if pFailure is not NULL. */ Method* dvmOptResolveMethod(ClassObject* referrer, u4 methodIdx, MethodType methodType, VerifyError* pFailure) { DvmDex* pDvmDex = referrer->pDvmDex; Method* resMethod; assert(methodType == METHOD_DIRECT || methodType == METHOD_VIRTUAL || methodType == METHOD_STATIC); LOGVV("--- resolving method %u (referrer=%s)", methodIdx, referrer->descriptor); resMethod = dvmDexGetResolvedMethod(pDvmDex, methodIdx); if (resMethod == NULL) { const DexMethodId* pMethodId; ClassObject* resClass; pMethodId = dexGetMethodId(pDvmDex->pDexFile, methodIdx); resClass = dvmOptResolveClass(referrer, pMethodId->classIdx, pFailure); if (resClass == NULL) { /* * Can't find the class that the method is a part of, or don't * have permission to access the class. */ ALOGV("DexOpt: can't find called method's class (?.%s)", dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx)); if (pFailure != NULL) { assert(!VERIFY_OK(*pFailure)); } return NULL; } if (dvmIsInterfaceClass(resClass)) { /* method is part of an interface; this is wrong method for that */ ALOGW("DexOpt: method is in an interface"); if (pFailure != NULL) *pFailure = VERIFY_ERROR_GENERIC; return NULL; } /* * We need to chase up the class hierarchy to find methods defined * in super-classes. (We only want to check the current class * if we're looking for a constructor.) */ DexProto proto; dexProtoSetFromMethodId(&proto, pDvmDex->pDexFile, pMethodId); if (methodType == METHOD_DIRECT) { resMethod = dvmFindDirectMethod(resClass, dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx), &proto); } else { /* METHOD_STATIC or METHOD_VIRTUAL */ resMethod = dvmFindMethodHier(resClass, dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx), &proto); } if (resMethod == NULL) { ALOGV("DexOpt: couldn't find method '%s'", dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx)); if (pFailure != NULL) *pFailure = VERIFY_ERROR_NO_METHOD; return NULL; } if (methodType == METHOD_STATIC) { if (!dvmIsStaticMethod(resMethod)) { ALOGD("DexOpt: wanted static, got instance for method %s.%s", resClass->descriptor, resMethod->name); if (pFailure != NULL) *pFailure = VERIFY_ERROR_CLASS_CHANGE; return NULL; } } else if (methodType == METHOD_VIRTUAL) { if (dvmIsStaticMethod(resMethod)) { ALOGD("DexOpt: wanted instance, got static for method %s.%s", resClass->descriptor, resMethod->name); if (pFailure != NULL) *pFailure = VERIFY_ERROR_CLASS_CHANGE; return NULL; } } /* see if this is a pure-abstract method */ if (dvmIsAbstractMethod(resMethod) && !dvmIsAbstractClass(resClass)) { ALOGW("DexOpt: pure-abstract method '%s' in %s", dexStringById(pDvmDex->pDexFile, pMethodId->nameIdx), resClass->descriptor); if (pFailure != NULL) *pFailure = VERIFY_ERROR_GENERIC; return NULL; } /* * Add it to the resolved table so we're faster on the next lookup. * * We can only do this for static methods if we're not in "dexopt", * because the presence of a valid value in the resolution table * implies that the class containing the static field has been * initialized. */ if (methodType != METHOD_STATIC || gDvm.optimizing) dvmDexSetResolvedMethod(pDvmDex, methodIdx, resMethod); } LOGVV("--- found method %d (%s.%s)", methodIdx, resMethod->clazz->descriptor, resMethod->name); /* access allowed? */ tweakLoader(referrer, resMethod->clazz); bool allowed = dvmCheckMethodAccess(referrer, resMethod); untweakLoader(referrer, resMethod->clazz); if (!allowed) { IF_ALOGI() { char* desc = dexProtoCopyMethodDescriptor(&resMethod->prototype); ALOGI("DexOpt: illegal method access (call %s.%s %s from %s)", resMethod->clazz->descriptor, resMethod->name, desc, referrer->descriptor); free(desc); }
/* * Alternate version of dvmResolveStaticField(). * * Does not force initialization of the resolved field's class. * * On failure, returns NULL, and sets *pFailure if pFailure is not NULL. */ StaticField* dvmOptResolveStaticField(ClassObject* referrer, u4 sfieldIdx, VerifyError* pFailure) { DvmDex* pDvmDex = referrer->pDvmDex; StaticField* resField; resField = (StaticField*)dvmDexGetResolvedField(pDvmDex, sfieldIdx); if (resField == NULL) { const DexFieldId* pFieldId; ClassObject* resClass; pFieldId = dexGetFieldId(pDvmDex->pDexFile, sfieldIdx); /* * Find the field's class. */ resClass = dvmOptResolveClass(referrer, pFieldId->classIdx, pFailure); if (resClass == NULL) { //dvmClearOptException(dvmThreadSelf()); assert(!dvmCheckException(dvmThreadSelf())); if (pFailure != NULL) { assert(!VERIFY_OK(*pFailure)); } return NULL; } const char* fieldName = dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx); resField = (StaticField*)dvmFindFieldHier(resClass, fieldName, dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->typeIdx)); if (resField == NULL) { ALOGD("DexOpt: couldn't find static field %s.%s", resClass->descriptor, fieldName); if (pFailure != NULL) *pFailure = VERIFY_ERROR_NO_FIELD; return NULL; } if (!dvmIsStaticField(resField)) { ALOGD("DexOpt: wanted static, got instance for field %s.%s", resClass->descriptor, fieldName); if (pFailure != NULL) *pFailure = VERIFY_ERROR_CLASS_CHANGE; return NULL; } /* * Add it to the resolved table so we're faster on the next lookup. * * We can only do this if we're in "dexopt", because the presence * of a valid value in the resolution table implies that the class * containing the static field has been initialized. */ if (gDvm.optimizing) dvmDexSetResolvedField(pDvmDex, sfieldIdx, (Field*) resField); } /* access allowed? */ tweakLoader(referrer, resField->clazz); bool allowed = dvmCheckFieldAccess(referrer, (Field*)resField); untweakLoader(referrer, resField->clazz); if (!allowed) { ALOGI("DexOpt: access denied from %s to field %s.%s", referrer->descriptor, resField->clazz->descriptor, resField->name); if (pFailure != NULL) *pFailure = VERIFY_ERROR_ACCESS_FIELD; return NULL; } return resField; }
/* * Alternate version of dvmResolveInstField(). * * On failure, returns NULL, and sets *pFailure if pFailure is not NULL. */ InstField* dvmOptResolveInstField(ClassObject* referrer, u4 ifieldIdx, VerifyError* pFailure) { DvmDex* pDvmDex = referrer->pDvmDex; InstField* resField; resField = (InstField*) dvmDexGetResolvedField(pDvmDex, ifieldIdx); if (resField == NULL) { const DexFieldId* pFieldId; ClassObject* resClass; pFieldId = dexGetFieldId(pDvmDex->pDexFile, ifieldIdx); /* * Find the field's class. */ resClass = dvmOptResolveClass(referrer, pFieldId->classIdx, pFailure); if (resClass == NULL) { //dvmClearOptException(dvmThreadSelf()); assert(!dvmCheckException(dvmThreadSelf())); if (pFailure != NULL) { assert(!VERIFY_OK(*pFailure)); } return NULL; } resField = (InstField*)dvmFindFieldHier(resClass, dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx), dexStringByTypeIdx(pDvmDex->pDexFile, pFieldId->typeIdx)); if (resField == NULL) { ALOGD("DexOpt: couldn't find field %s.%s", resClass->descriptor, dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx)); if (pFailure != NULL) *pFailure = VERIFY_ERROR_NO_FIELD; return NULL; } if (dvmIsStaticField(resField)) { ALOGD("DexOpt: wanted instance, got static for field %s.%s", resClass->descriptor, dexStringById(pDvmDex->pDexFile, pFieldId->nameIdx)); if (pFailure != NULL) *pFailure = VERIFY_ERROR_CLASS_CHANGE; return NULL; } /* * Add it to the resolved table so we're faster on the next lookup. */ dvmDexSetResolvedField(pDvmDex, ifieldIdx, (Field*) resField); } /* access allowed? */ tweakLoader(referrer, resField->clazz); bool allowed = dvmCheckFieldAccess(referrer, (Field*)resField); untweakLoader(referrer, resField->clazz); if (!allowed) { ALOGI("DexOpt: access denied from %s to field %s.%s", referrer->descriptor, resField->clazz->descriptor, resField->name); if (pFailure != NULL) *pFailure = VERIFY_ERROR_ACCESS_FIELD; return NULL; } return resField; }
// Refresh the projects list. bool WorkspaceInfo::Refresh(void) { // If the internal project integrity is good, then no refresh is needed. if (CheckIntegrity()) return true; // Delete everything. RemoveAll(); // First, get a pointer to the dispatch for the Projects collection CComPtr<IDispatch> pDispProjects; VERIFY_OK(m_pApplication->get_Projects(&pDispProjects)); CComQIPtr<IProjects, &IID_IProjects> pProjects(pDispProjects); // Get the number of projects in the collection long projectCount; VERIFY_OK(pProjects->get_Count(&projectCount)); // Iterate all the projects. for (long i = 1; i < projectCount + 1; i++) { CComVariant Vari = i; // Get the next project CComPtr<IGenericProject> pGenProject; VERIFY_OK(pProjects->Item(Vari, &pGenProject)); CComQIPtr<IGenericProject, &IID_IGenericProject> pProject(pGenProject); // Get the project name. CComBSTR bszStr; VERIFY_OK(pProject->get_FullName(&bszStr)); CString projectName = bszStr; Add(projectName); } // Rename a misnamed add-on file. CString oldFilename = m_workspaceLocation + "ExtraFiles.PFO"; CString wuFilename = GetExtraFilename(); rename(oldFilename, wuFilename); // Is there an add-on file? CStdioFile file; if (file.Open(wuFilename, CFile::modeRead) == TRUE) { CString line; // Count the number of extra projects. while (1) { // Read in a project name. if (!file.ReadString(line)) break; // Check the integrity. Add(line); } // Close the file. file.Close(); } // Build the file array. m_fileList.Sort(); // Rebuilt stuff. return false; }
// CheckIntegrity() returns false if the internally stored projects // don't match the Visual Studio projects. bool WorkspaceInfo::CheckIntegrity(void) { // If there are no projects to compare against, then fail the integrity check. if (m_projects.GetCount() == 0) { // AfxMessageBox("Refresh: No projects."); return false; } // Is there an add-on file? int numAddOnProjects = 0; CStdioFile file; if (file.Open(GetExtraFilename(), CFile::modeRead) == TRUE) { CString line; // Count the number of extra projects. while (1) { // Read in a project name. if (!file.ReadString(line)) break; // Check the integrity. if (!CheckProjectIntegrity(line)) return false; // Increment the number of add-on projects. numAddOnProjects++; } // Close the file. file.Close(); } // Now run all projects with workspace parents (which means they were added // indirectly through a .dsw file). POSITION pos = m_projects.GetHeadPosition(); while (pos != NULL) { // Get the project. Project& prj = m_projects.GetNext(pos); // Does it have a parent? if (prj.m_parent) { // Yes, so it is a project added indirectly from a .dsw file. if (!CheckProjectIntegrity(prj.GetName())) return false; // Add it to the number of add-on projects. numAddOnProjects++; } } // First, get a pointer to the dispatch for the Projects collection CComPtr<IDispatch> pDispProjects; VERIFY_OK(m_pApplication->get_Projects(&pDispProjects)); CComQIPtr<IProjects, &IID_IProjects> pProjects(pDispProjects); // Get the number of projects in the collection long workspaceProjectCount; VERIFY_OK(pProjects->get_Count(&workspaceProjectCount)); // If the number of projects reported by Visual Studio is not the same // number as our local project list, then refresh everything. if (workspaceProjectCount + numAddOnProjects != m_projects.GetCount()) { // AfxMessageBox("Refresh: Project counts differ."); return false; } // Check for non-matching project names. for (long i = 1; i < workspaceProjectCount + 1; i++) { CComVariant Vari = i; // Get the next project CComPtr<IGenericProject> pGenProject; VERIFY_OK(pProjects->Item(Vari, &pGenProject)); CComQIPtr<IGenericProject, &IID_IGenericProject> pProject(pGenProject); CComBSTR bszStr; VERIFY_OK(pProject->get_FullName(&bszStr)); CString projectName = bszStr; // Check the project integrity. if (!CheckProjectIntegrity(projectName)) return false; } // end for [1..workspaceProjectCount] return true; }
HRESULT CCommands::XApplicationEvents::BuildFinish(long nNumErrors, long nNumWarnings) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); if (nNumErrors == 0) { CComPtr<IGenericProject> pProjectItem = NULL; IApplication* pApplication; CComPtr<IConfiguration> pConfig = NULL; CComBSTR bsBuildName; CString strBuildName; pApplication = m_pCommands->GetApplicationObject(); VERIFY_OK(pApplication->get_ActiveProject((IDispatch **)&pProjectItem)); VERIFY_OK(pApplication->get_ActiveConfiguration((IDispatch **)&pConfig)); pConfig->get_Name(&bsBuildName); strBuildName = bsBuildName; if (!pProjectItem) { return S_OK; } CComBSTR bsFullName, bsName; CString strProjectFullName, strProjectPath, strConfigName, strProjectName; UINT uSvnVersion = 0; pProjectItem->get_FullName(&bsFullName); pProjectItem->get_Name(&bsName); strProjectFullName = bsFullName; strProjectName = bsName; TCHAR sDrive[_MAX_DRIVE] = {0}; TCHAR sDir[_MAX_DIR] = {0}; TCHAR sFname[_MAX_FNAME] = {0}; TCHAR sExt[_MAX_EXT] = {0}; _tsplitpath(strProjectFullName, sDrive, sDir, sFname, sExt); strProjectPath = CString(sDrive) + CString(sDir); strConfigName = CString(sDrive) + CString(sDir) + CString(sFname) + CString(_T(".ini")); CONFIG config; COptionDlg::GetConfig(config, strConfigName); if (config.bPdbAutoCommit && -1 != config.strCommitList.Find(strBuildName + '#')) { CString strPdbPath, strOutputDir, strReg, strOutPut, strOutData, strData; const TCHAR sReg[] = _T("IF[ ]+\"\\$\\(CFG\\)\" == \"%s\"([^!]+)"); const TCHAR sRegOutputDir[] = _T("^.+PROP Output_Dir[ ]+\"(.+)\"$"); const TCHAR sRegPdbPath[] = _T("^# ADD LINK32(?:.+/pdb:\"(?<PDB>[^\"]+)\".+/debug)|(?:.+(?<PDB>/debug))"); const TCHAR sRegOutPut[] = _T("^# ADD LINK32(?:.+/out:\"(?<OUT>[^\"]+)\")"); strReg.Format(sReg, strBuildName); // Get PDB File Path GetFileData(strProjectFullName, strOutData); if (strOutData.IsEmpty()) { return S_OK; } strData = GetRegexpData(strOutData, strReg, MULTILINE | IGNORECASE); strOutputDir = GetRegexpData(strData, sRegOutputDir, MULTILINE | IGNORECASE); strPdbPath = GetRegexpData(strData, sRegPdbPath, MULTILINE | IGNORECASE, "PDB"); strOutPut = GetRegexpData(strData, sRegOutPut, MULTILINE | IGNORECASE, "OUT"); if (strPdbPath.IsEmpty()) { pApplication->PrintToOutputWindow(CComBSTR("Not Find Pdb File Path So Can't Auto Commit PDB\r\n")); return S_OK; } if (!strPdbPath.CompareNoCase(_T("/debug"))) { if (strOutPut.IsEmpty()) { strPdbPath = strOutputDir + '\\' + strProjectName + ".pdb"; } else { TCHAR ssFname[_MAX_FNAME] = {0}; _tsplitpath(strOutPut, NULL, NULL, ssFname, NULL); strPdbPath = strOutputDir + '\\' + ssFname + ".pdb"; } } // Commit PDB File To Server MANUALBACKUP ManualBackup = {0}; ManualBackup.dwMaxSingleFileSize = -1; ManualBackup.dwUserData = (DWORD)m_pCommands; ManualBackup.pfnCallBackProc = ManualCallBackProc; strcpy(ManualBackup.szExtName, "*.pdb"); ManualBackup.pFileName = new ANSIPATH[1]; strcpy(ManualBackup.pFileName[0], strProjectPath + strPdbPath); ManualBackup.uFileCount = 1; strcpy(ManualBackup.szServerIP, config.strPdbServer); strcpy(ManualBackup.szReason, _T("PDB:")); ManualBackupToServer(&ManualBackup); delete []ManualBackup.pFileName; } } return S_OK; }
HRESULT CCommands::XApplicationEvents::BeforeBuildStart() { AFX_MANAGE_STATE(AfxGetStaticModuleState()); IApplication* pApplication; pApplication = m_pCommands->GetApplicationObject(); CComPtr<IProjects> pIProjects = NULL; pApplication->get_Projects((IDispatch **)&pIProjects); long lProjects = 0; CComVariant varProject ; VERIFY_OK( pIProjects->get_Count( &lProjects ) ); for ( long lProject = 1 ; lProject < lProjects + 1 ; lProject++ ) { varProject = lProject; CComPtr< IGenericProject > pIGenericProject; VERIFY_OK( pIProjects->Item(varProject, &pIGenericProject)); if (pIGenericProject) { CComBSTR bType; CString strType; pIGenericProject->get_Type(&bType); strType = bType; if (strType.CompareNoCase(DS_BUILD_PROJECT) != 0) continue; CComBSTR bStr; pIGenericProject->get_FullName(&bStr); CString strProjectName = bStr; CString strProjectPath, strRcName, strConfigName; UINT uSvnVersion = 0; TCHAR sDrive[_MAX_DRIVE] = {0}; TCHAR sDir[_MAX_DIR] = {0}; TCHAR sFname[_MAX_FNAME] = {0}; TCHAR sExt[_MAX_EXT] = {0}; _tsplitpath(strProjectName, sDrive, sDir, sFname, sExt); strProjectPath = CString(sDrive) + CString(sDir); strConfigName = CString(sDrive) + CString(sDir) + CString(sFname) + CString(_T(".ini")); // 得到配置信息 CONFIG config; COptionDlg::GetConfig(config, strConfigName); if (config.bCheckSvn && !config.bCheckSelfUpdata) { // const svn_version_t *ver = svn_wc_version(); uSvnVersion = GetWorkSvnVersion(strProjectPath, config.iSvnVersionPath); if (uSvnVersion == 0) { return S_OK; } } CString Data; GetFileData(strProjectName, Data); if (Data.IsEmpty()) { return S_OK; } strRcName = GetRegexpData(Data, _T("SOURCE=(?<SCR>.+\\.rc)$|SOURCE=\"(?<SCR>.+\\.rc)\""), MULTILINE | IGNORECASE, "SCR"); if (strRcName.IsEmpty()) { return S_OK; } CString strFileVersion, strFileVersionDescribe, strVersion, strVersionDescribe, RcData; UINT uFileVer[4], uFileVerDesc[4]; BOOL bUpdata = FALSE; GetFileData(strProjectPath + strRcName, RcData); if (RcData.IsEmpty()) { return S_OK; } // 进行 版本信息 更新 strVersion = GetRegexpData(RcData, _T(".+VALUE.+\"FileVersion\",.+\"(.+)\""), MULTILINE | IGNORECASE); if (!strVersion.IsEmpty()) { sscanf(strVersion, "%d, %d, %d, %d", &uFileVer[0], &uFileVer[1], &uFileVer[2], &uFileVer[3]); UpdataVersionInfo(uFileVer, config, uSvnVersion); strFileVersion.Format(_T("$1%d, %d, %d, %d\\0$2"), uFileVer[0], uFileVer[1], uFileVer[2], uFileVer[3]); if (-1 == strFileVersion.Find(strVersion)) { RcData = ReplaceRegexpData( RcData, _T("(.+VALUE.+\"FileVersion\",.+\").+(\")"), MULTILINE | IGNORECASE, strFileVersion); bUpdata = TRUE; } } strVersion = GetRegexpData(RcData, _T(".+VALUE.+\"ProductVersion\",.+\"(.+)\""), MULTILINE | IGNORECASE); if (!strVersion.IsEmpty()) { sscanf(strVersion, "%d, %d, %d, %d", &uFileVer[0], &uFileVer[1], &uFileVer[2], &uFileVer[3]); UpdataVersionInfo(uFileVer, config, uSvnVersion); strFileVersion.Format(_T("$1%d, %d, %d, %d\\0$2"), uFileVer[0], uFileVer[1], uFileVer[2], uFileVer[3]); if (-1 == strFileVersion.Find(strVersion)) { RcData = ReplaceRegexpData( RcData, _T("(.+VALUE.+\"ProductVersion\",.+\").+(\")"), MULTILINE | IGNORECASE, strFileVersion); bUpdata = TRUE; } } strVersionDescribe = GetRegexpData(RcData, _T(".+FILEVERSION[ ]+(.+)"), MULTILINE | IGNORECASE); if (!strVersionDescribe.IsEmpty()) { sscanf(strVersionDescribe, "%d,%d,%d,%d", &uFileVerDesc[0], &uFileVerDesc[1], &uFileVerDesc[2], &uFileVerDesc[3]); UpdataVersionInfo(uFileVerDesc, config, uSvnVersion); strFileVersionDescribe.Format(_T("$1%d,%d,%d,%d"), uFileVerDesc[0], uFileVerDesc[1], uFileVerDesc[2], uFileVerDesc[3]); if (-1 == strFileVersionDescribe.Find(strVersionDescribe)) { RcData = ReplaceRegexpData( RcData, _T("(.+FILEVERSION[ ]+).+"), MULTILINE | IGNORECASE, strFileVersionDescribe); bUpdata = TRUE; } } strVersionDescribe = GetRegexpData(RcData, _T(".+ProductVersion[ ]+(.+)"), MULTILINE | IGNORECASE); if (!strVersionDescribe.IsEmpty()) { sscanf(strVersionDescribe, "%d,%d,%d,%d", &uFileVerDesc[0], &uFileVerDesc[1], &uFileVerDesc[2], &uFileVerDesc[3]); UpdataVersionInfo(uFileVerDesc, config, uSvnVersion); strFileVersionDescribe.Format(_T("$1%d,%d,%d,%d"), uFileVerDesc[0], uFileVerDesc[1], uFileVerDesc[2], uFileVerDesc[3]); if (-1 == strFileVersionDescribe.Find(strVersionDescribe)) { RcData = ReplaceRegexpData( RcData, _T("(.+ProductVersion[ ]+).+"), MULTILINE | IGNORECASE, strFileVersionDescribe); bUpdata = TRUE; } } if (bUpdata) { SetFileData(strProjectPath + strRcName, RcData); } } } return S_OK; }
// Dieser Code wird beim ersten Laden des Add-Ins und beim Starten der Anwendung aufgerufen // jeder nachfolgenden Developer Studio-Sitzung STDMETHODIMP CDSAddIn::OnConnection(IApplication* pApp, VARIANT_BOOL bFirstTime, long dwCookie, VARIANT_BOOL* OnConnection) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // An uns übergebene Info speichern IApplication* pApplication = NULL; if (FAILED(pApp->QueryInterface(IID_IApplication, (void**) &pApplication)) || pApplication == NULL) { *OnConnection = VARIANT_FALSE; return S_OK; } m_dwCookie = dwCookie; // Befehlsverteilung erzeugen, Rückmeldung an DevStudio CCommandsObj::CreateInstance(&m_pCommands); m_pCommands->AddRef(); // Das obige QueryInterface hat AddRef auf das Objekt Application angewendet. Es // wird im Destruktor von CCommand freigegeben. m_pCommands->SetApplicationObject(pApplication); // (siehe Definition von VERIFY_OK in stdafx.h) VERIFY_OK(pApplication->SetAddInInfo((long) AfxGetInstanceHandle(), (LPDISPATCH) m_pCommands, IDR_TOOLBAR_MEDIUM, IDR_TOOLBAR_LARGE, m_dwCookie)); // DevStudio über die implementierten Befehle informieren VARIANT_BOOL bRet; CString strCmdString; LPCTSTR szNewQtProject = _T("New Qt Project"); strCmdString.LoadString(IDS_NEWQTPROJECT_STRING); VERIFY_OK(pApplication->AddCommand(CComBSTR(szNewQtProject + strCmdString), CComBSTR(_T("QMsDevNewQtProject")), 0, m_dwCookie, &bRet)); #if 1 LPCTSTR szGenerateQtProject = _T("Generate Qt Project"); strCmdString.LoadString(IDS_GENERATEQTPROJECT_STRING); VERIFY_OK(pApplication->AddCommand(CComBSTR(szGenerateQtProject + strCmdString), CComBSTR(_T("QMsDevGenerateQtProject")), 1, m_dwCookie, &bRet)); #endif LPCTSTR szNewQtDialog = _T("New Qt Dialog"); strCmdString.LoadString(IDS_NEWQTDIALOG_STRING); VERIFY_OK(pApplication->AddCommand(CComBSTR(szNewQtDialog + strCmdString), CComBSTR(_T("QMsDevNewQtDialog")), 2, m_dwCookie, &bRet)); LPCTSTR szOpenDesigner = _T("Open Qt GUI Designer"); strCmdString.LoadString(IDS_OPENDESIGNER_STRING); VERIFY_OK(pApplication->AddCommand(CComBSTR(szOpenDesigner + strCmdString), CComBSTR(_T("QMsDevStartDesigner")), 3, m_dwCookie, &bRet)); LPCTSTR szUseQt = _T("Use Qt"); strCmdString.LoadString(IDS_USEQT_STRING); VERIFY_OK(pApplication->AddCommand(CComBSTR(szUseQt + strCmdString), CComBSTR(_T("QMsDevUseQt")), 4, m_dwCookie, &bRet)); LPCTSTR szAddMOCStep = _T("Add MOC step"); strCmdString.LoadString(IDS_ADDMOCSTEP_STRING); VERIFY_OK(pApplication->AddCommand(CComBSTR(szAddMOCStep + strCmdString), CComBSTR(_T("QMsDevAddMOCStep")), 5, m_dwCookie, &bRet)); LPCTSTR szAddUICStep = _T("Add UIC step"); strCmdString.LoadString(IDS_ADDUICSTEP_STRING); VERIFY_OK(pApplication->AddCommand(CComBSTR(szAddUICStep + strCmdString), CComBSTR(_T("QMsDevAddUICStep")), 6, m_dwCookie, &bRet)); if (bRet == VARIANT_FALSE) { *OnConnection = VARIANT_FALSE; return S_OK; } if (bFirstTime == VARIANT_TRUE) { VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, CComBSTR(szNewQtProject), m_dwCookie)); #if 1 VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, CComBSTR(szGenerateQtProject), m_dwCookie)); #endif VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, CComBSTR(szNewQtDialog), m_dwCookie)); VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, CComBSTR(szOpenDesigner), m_dwCookie)); VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, CComBSTR(szUseQt), m_dwCookie)); VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, CComBSTR(szAddMOCStep), m_dwCookie)); VERIFY_OK(pApplication-> AddCommandBarButton(dsGlyph, CComBSTR(szAddUICStep), m_dwCookie)); } *OnConnection = VARIANT_TRUE; return S_OK; }