IDispatchPtr ExcelControllerImpl08::DoOpenDocument(const CStdString& sDocumentPath, bool bReadOnly)
{  
   if(sDocumentPath.IsEmpty())
      throw Workshare::ArgumentException(_T("sDocumentPath"), _T("An empty filename is not allowed."));

   if(!::PathFileExists(sDocumentPath))
      throw Workshare::System::IO::FileNotFoundException(sDocumentPath, _T("Expected an existing excel workbook filename to open."));
   
   //TODO: (EW/WS) Refer to CloseDocument for a description of a latent defect which may be caused by the following line.
   SetScreenUpdating(false);
   Excel::_WorkbookPtr spDocument = FindOpenDocument(sDocumentPath);
   if(spDocument)
   {
      if (!bReadOnly)
      {
         if (spDocument->ReadOnly)
            throw Workshare::Com::ComException(_T("Failed to open a READ-ONLY document for write access."), E_FAIL);

         if (!spDocument->Saved)
            spDocument->Save();			
      }
   }
   else		
   {
      Excel::_ApplicationPtr spApplication = GetApplication();
	  spApplication->EnableEvents = VARIANT_FALSE;	//The events are on by default, so no need to store the original value
      LONG_PTR nNewDocumentCount = spApplication->Workbooks->Count + 1;
      try
      {
         _variant_t vtReadOnly = bReadOnly;         
         _variant_t vtUpdateLinks(false);
         spDocument = spApplication->Workbooks->Open(sDocumentPath.c_str(), vtUpdateLinks, vtReadOnly);

         WaitForWorkbookOpened(sDocumentPath);
      }
      catch (const Workshare::Com::ComException&)
      {
         if(nNewDocumentCount != spApplication->Workbooks->Count)
            throw;

         _variant_t vtCount(static_cast<long>(nNewDocumentCount));
         spDocument = spApplication->Workbooks->GetItem(&vtCount);
      }
   }

   DisableUnwantedOptions();
   spDocument->put_Saved(LocaleHelper::GetLocaleIDForInstalledExcel(spDocument), VARIANT_TRUE);

   return spDocument;   
}
void PublishExcelToPDFWithWorkBook(Excel::_WorkbookPtr spWorkbook, const CStdString& sOutputFile, int from, int to)
{
	LOG_WS_FUNCTION_SCOPE();

	CStdString restrictionLevel = c_sNoRestriction;
	CStdString classification = c_sNoClassification;

	try
	{
		_variant_t vSaved = spWorkbook->Saved;
		restrictionLevel = GetRestrictionLevel(spWorkbook);
		classification = GetClassification(spWorkbook);

		// TODO: Switch off Excel's attempt to match the printer's paper size
		// by temporarily setting spWorkbook->Application->MapPaperSize = VARIANT_FALSE.
		// But that option isn't available in the Excel 2000 API that we're using.
		bool bIsNotExcel97 = (atof(spWorkbook->Application->Version) > 8.0);

		if( !PDFConverterController::UseExcelPrintArea() )
		{
			for (int iIndex = 1; iIndex <= spWorkbook->Worksheets->Count; iIndex++)
			{
				Excel::_WorksheetPtr spWorksheet = spWorkbook->Worksheets->Item[ iIndex ];
				spWorksheet->PageSetup->PrintArea = _T("");
			}
		}

		PDFConverterController pdfConverter;
		pdfConverter.InitialisePDFConverterUseFileName(sOutputFile, VARIANT_TRUE);
		_variant_t vtPrintToFile(false);
		_variant_t vtActivePrinter(c_sPDFDriverName);
		_variant_t vtOutputFile(sOutputFile);
		_variant_t vtFrom(vtMissing);
		_variant_t vtTo(vtMissing);

		if (from != 0 || to != 0)
		{
			vtFrom = from;
			vtTo = to;
		}

		if(bIsNotExcel97)
		{
			//60.18: This msg loop is to prevent the 'known' issue with Workshare events from crashing. 
			DoEvents();

			spWorkbook->PrintOut(&vtFrom, &vtTo, &vtMissing, &vtMissing, &vtActivePrinter, &vtPrintToFile, &vtMissing, &vtOutputFile);
		}
		else
		{
			if (::PathFileExists(sOutputFile) && !::DeleteFile(sOutputFile))
			{
				CStdString sMsg;
				sMsg.Format(_T("Failed to overwrite file %s"), sOutputFile.c_str());
				throw Workshare::System::IO::IOException(sMsg);
			}

			DismissPrintDialog(sOutputFile);

			_variant_t vtResult;
			IDispatchPtr spDispDocument = spWorkbook;
			HRESULT hr = CCOMDispatchHelper::AutoWrap(DISPATCH_METHOD, &vtResult, spDispDocument, L"PrintOut", 7,
				vtMissing, vtPrintToFile, vtActivePrinter, vtMissing, vtMissing, vtMissing, vtMissing);
			if (FAILED(hr))
				throw Workshare::Com::ComException(_T("Failed to invoke PrintOut method"), hr, spDispDocument);
		}
		pdfConverter.UnInitialisePDFConverter();

		// Setting the following property fixes an issue in the Office - iManage integration, 
		// in which iManage appears to query the Saved flag on Close and pops up a dialog, 
		// even though we have specified to Close with no Save:
		LCID lCid = LocaleHelper::GetLocaleIDForInstalledExcel(spWorkbook);
		spWorkbook->put_Saved(lCid, vSaved);


		if(c_sNoRestriction != restrictionLevel)
			SetPdfRestrictionLevel(sOutputFile, restrictionLevel);

		if (c_sNoClassification != classification)
			SetPdfClassification(sOutputFile, classification);
	}
	catch(const Workshare::Exception&)
	{
		throw;
	}
	catch(...)
	{
		unexpected(); 
	}
}