Office.Interop.Powerpoint import - c#

I am having trouble with PowerPoint conversion to HTML.
Here is code
Microsoft.Office.Interop.PowerPoint.Application oApplication = new Microsoft.Office.Interop.PowerPoint.Application();
Microsoft.Office.Interop.PowerPoint.Presentation oPresentation = oApplication.Presentations.Open(sourceFileName);
oPresentation.SaveAs(destFileName, Microsoft.Office.Interop.PowerPoint.PpSaveAsFileType.ppSaveAsHTML);
oPresentation.Close();
oApplication.Quit();
I get the following error
System.Runtime.InteropServices.COMException (0x80048240):
Presentations (unknown member) : Invalid request. The PowerPoint Frame
window does not exist. at
Microsoft.Office.Interop.PowerPoint.Presentations.Open(String
FileName, MsoTriState ReadOnly, MsoTriState Untitled, MsoTriState
WithWindow) at
SmartBoard_V2.Section.Admin.Areas.DersEditor.DersEdit.convertPowerPoint(String
fennKod) in c:\Users\Kamandar\Documents\Visual Studio
2012\Projects\SmartBoard_V2\SmartBoard_V2\Section\Admin\Areas\DersEditor\DersEdit.aspx.cs:line 163

Note that if you're automating PPT 2013 (or presumably later), this won't work. As of 2013, PowerPoint no longer has a SaveAsHTML method.

I suspect that you need to set the application to visible before you try and save it.
To do this simply add the following code before declaring the oPresentation object.
oApplication .Visible = Office.MsoTriState.msoTrue;
Edit: Just noticed you are using ASP.NET, Although it is not recommended, you can check here for a similar problem.

Related

Unable to set SlideSize property while using powerpoint interop

We are trying to convert PPT file to PDF using Powerpoint Office Interop. We are using ExportAsFixedFormat() to do the conversion as shown in the below code snippet:
public static void ConvertPowerPointToPdf(string inputFile)
{
string outputFileName = #"C:\All format files\PPT2PDF.pdf";
Microsoft.Office.Interop.PowerPoint.Application powerPointApp =
new Microsoft.Office.Interop.PowerPoint.Application();
Presentation presentation = null;
Presentations presentations = null;
try
{
presentations = powerPointApp.Presentations;
presentation = presentations.Open(inputFile, MsoTriState.msoFalse, MsoTriState.msoFalse,
MsoTriState.msoFalse);
presentation.PageSetup.SlideSize = PpSlideSizeType.ppSlideSizeA4Paper; //It throws the exception here
presentation.ExportAsFixedFormat(outputFileName, PpFixedFormatType.ppFixedFormatTypePDF,
PpFixedFormatIntent.ppFixedFormatIntentPrint);
}
catch (Exception)
{
throw;
}
}
The above code works fine if we don't set the SlideSize property. The moment we try to set SlideSize property, the exception is thrown as "PageSetup (unknown member) : Failed." Screenshot of the error message is shown below:
The version of Microsoft.Office.Interop.PowerPoint is 15.0.0.0 and Microsoft Office 15.0 Object Library is used as the Office core library. My PC in Windows 8.1 and I am using Microsoft Office 2013. Since we need custom output format, we need to setup SlideSize property which is currently throwing exception.
The code you have is correct. I was able to recreate your error exactly with with the presentation being marked as 'Final'. Try adding:
presentation.Final = false;
Add it before you resize. Hope it helps. Good Luck.

Invalid Cast Exception, Unable to Cast COM object to Excel

Similar questions have been asked before, but I want to try and refine it to my situation.
I am downloading a legacy file type (Excel 2003 (.xls)) and I need to strip the data from the file. The problem is I get :
{"Unable to cast COM object of type 'Microsoft.Office.Interop.Excel.ApplicationClass'
to interface type 'Microsoft.Office.Interop.Excel._Application'. This operation failed
because the QueryInterface call on the COM component for the interface
I am currently trying to get this working on my machine before I send the app to production, which will/does have excel on the server.
I have tried reinstalling office, but that did not work. I think the problem lies more in the fact that I have office 2013 on my box and I am attempting to run a decade old file type through it.
I tried to use this:
public void Convert(String file)
{
var app = new Application();
var wb = app.Workbooks.Open(file);
wb.SaveAs(file + "x", XlFileFormat.xlOpenXMLWorkbook);
wb.Close();
app.Quit();
}
That still causes the same problem, because the file will not open.
Any suggestions?
UPDATE
Here is the full method I am using
public Worksheet GetExcelBy(string url)
{
var fileName = #"C:\temp\tempfile.xls";
var webClient = new WebClient();
webClient.DownloadFile(url, fileName);
Convert(fileName);
var excel = new Application();
var workbook = excel.Workbooks.Open(fileName);
return (Worksheet)workbook.Worksheets["Data 6"];
}
this is the URL:
http://tonto.eia.doe.gov/dnav/pet/xls/pet_pri_spt_s1_d.xls
I presume the line with var excel = new Application(); is the line where the exception is raised. From my experience in the matter, as I also tried to follow other advice found on the internet, the solution I accidentally found was to explicitly define the non use of 32 bit access mode for the interop dll.
For doing so in visual studio, I had to tick and then untick the box "Prefer 32-bit" in the build section of the project configuration, which added <Prefer32Bit>false</Prefer32Bit> in the .csproj file.

IVsInvisibleEditorManager not placing document within Running Document Table

I'm working on a Visual Studio package and I seem to be running into an issue with IVsInvisibleEditorManager and the Running Document Table (RDT).
To start, I have a file opened within a normal Visual Studio editor. Next, I register an IVsInvisibleEditor for this same file via:
IVsInvisibleEditor invisibleEditor;
ErrorHandler.ThrowOnFailure(this._InvisibleEditorManager.RegisterInvisibleEditor(
filePath
, pProject: null
, dwFlags: (uint)_EDITORREGFLAGS.RIEF_ENABLECACHING
, pFactory: null
, ppEditor: out invisibleEditor));
When I modify the file and close the primary Visual Studio editor, I am prompted with a message to save my document. My understanding is that this should not be the case as I still have access to this file within my invisible editor. Visual Studio then cleans up some of the resources associated with this file, which breaks my invisible editor.
I suspect this is because RegisterInvisibleEditor() is not correctly registering my document within the RDT.
The documentation for RegisterInvisibleEditor() states the following for dwFlags when using _EDITORREGFLAGS.RIEF_ENABLECACHING:
This allows the document to stay in the RDT in the scenario where a
document is open in a visible editor, and closed by the user while an
invisible editor is registered for that document.
This describes my problem exactly. The visible editor is being closed, but I'd like the document to remain in the RDT.
Does anyone know how to make my document persists within the RDT?
Is the RDT project specific? Does the fact that I'm passing in null for both pProject and pFactory cause any problems for the RDT?
Edit: I just tested the above code out, but passed in the appropriate IVsProject and there was no change. It still appears the RDT is not changed when registering an invisible editor.
It doesn't appear as though I can convince the IVsInvisibleEditorManager to add a lock to the document. Unfortunately, RegisterInvisibleEditor() is a COM method, which means I can't decompile and peek at what it's doing (at least to my limited knowledge).
However, I've come up with a workaround in which I manually manage entries within the RDT.
var rdt =
(IVsRunningDocumentTable)GetService(typeof(SVsRunningDocumentTable));
//Retrieve the appropriate IVsHierarchy. I've assumed there's only
//one project within this solution.
var solutionService = (IVsSolution)GetService(typeof(SVsSolution));
IVsProject project = null;
Guid guid = Guid.Empty;
solutionService.GetProjectEnum((uint)__VSENUMPROJFLAGS.EPF_LOADEDINSOLUTION, ref guid, out enumerator);
var hierarchy = new IVsHierarchy[1] { null };
uint fetched = 0;
for((enumerator.Reset(); enumerator.Next(1, hierarchy, out fetched) == VSConstants.S_OK && fetched == 1;)
hierarchy = hierarchyArray[0]
//Then when creating the IVsInvisibleEditor, find and lock the document
uint itemID;
IntPtr docData;
uint docCookie;
var result = rdt.FindAndLockDocument(
dwRDTLockType: (uint)_VSRDTFLAGS.RDT_ReadLock
, pszMkDocument: filePath
, ppHier: out hierarchy
, pitemid: out itemID
, ppunkDocData: out docData
, pdwCookie: out docCookie
);
At some point you'll be finished with your IVsInvisibleEditor, at which point you should unlock the document from the RDT.
runningDocTable.UnlockDocument((uint)_VSRDTFLAGS.RDT_ReadLock, docCookie);

microsoft.interop.selection text

Before asking my question I would like to describe briefly background of my problem: I'm developing ms word COM addin on C# and I need to handle user's text selections. Now I'm able to catch selection event - it's look like
Microsoft.Interop.Word._Application app;
app = (Word._Application )Application; // Application object comes on addin's connection
app.Application.WindowSelectionChange+=
new Word.ApplicationEvents4_WindowSelectionChangeEventHandler(selChange);
///
void selChange(Word.Selection selection){
MessageBox.Show(selection.Text); // this is my problem, Text property is not available
}
// property Text doesn't exist,but documentation tells that it exists. I suspect, that this property is not available for ms word 2007 - in the documentation only 2003,2010 versions are mentioned. But how I can do something like selection.getSelectedText()? I tryed to play with selection.Rows, selection.Rows[0],selection.Words,selection.Words[0] - no success.
According to the documentation, the Selection.Text property should be available for Word 2007 as well. I made a small sample implementation of your case to test it, and I cannot make it fail on Word 2010 and 2013 at least:
var wordApplication = new Application() { Visible = true };
wordApplication.Documents.Add();
wordApplication.WindowSelectionChange += delegate(Selection mySelection) { Console.WriteLine(mySelection.Text); };
So, I suggest you check that you have included the right namespaces and that the Selection interface you are using are actually the one from the Microsoft.Office.Interop.Word namespace.

Screenshot of VBA editor in debug mode in terminal, or use Excel DOM to find error line and desc in VBA editor?

An Excel workbook is called by a command line, which itself is launched from c# (3.5). The workbook runs, but there is an error in the VBA. For example, a column is missing in a pivot and Excel prompts the user with an error message, with the option to "debug".
From the process in C#, we can detect that the error window is open, and we take a screenshot of the error message, and then we close the error box.
If this was an interactive session, Excel would then present the VBA editor, in debug mode, with the line where the error occurred highlighted.
However, because this is running in an unattended terminal session, we are then unable to take a screenshot of the VBA editor (the screenshot is a black screen).
We are then able to close the excel program, using the windows PID.
The questions is: how do we either get a screenshot of the VBA editor, or how do we bind (with COM or interop) with the Excel in debug mode, and traverse the dom to find the error line, and possibly error message?
(1) If you have authoring control of the Excel workbook(s), you can insert line numbers and a error handler to write to file Err.Number, Err.Description, Err.Source, Erl.
(2) If (1) is not an option, but you can set Macro Security on the host to allow programmatic control of the Visual Basic project, then you can get the active line number:
Dim xl As excel.Application
Dim StartLine As Long, StartColumn As Long, EndLine As Long, EndColumn As Long
Set xl = GetObject(, "Excel.Application")
xl.VBE.ActiveCodePane.GetSelection StartLine, StartColumn, EndLine, EndColumn
Debug.Print StartLine, StartColumn, EndLine, EndColumn
(3) If neither (1) nor (2) is an option, it is a bit hairy, but you can copy out the bitmap contents of the window: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183402%28v=vs.85%29.aspx
The simplest solution if you have access to modify the VBA code might be to use On Error GoTo and a line label. This will stop the Debug message from popping up and instead, when a runtime error occurs, execution will jump to the specified label at which point you can access the information available in the global Err object. VBA does not have the concept of a try/catch block so this is pretty much the nearest proximally.
Sub Main()
On Error GoTo Catch
' Code that may trigger errors here...
GoTo Finally
Catch:
' Log Err info, etc...
Debug.Print "Error " & Err.Number & " - " & Err.Description
Finally:
' This is always reached last (error or no error)
End Sub
Snapshot of data structures, VBA excel
It sounds a lot like the question above in which I suggested to write the state of your code to a separate txt file (in the example, using a FileSystemObject) where you can afterwards analyze where you got stuck:
booleans on conditions / instantiation of objects, number on succesful loops, values contained in variables, well - whatever you want...).
In combination with an error handler (as suggested before) you can see where the code stopped + code / description of the error.
A copy-paste for your sake:
dim sFile As string
Dim FSO As FileSystemObject
Dim FSOFile As TextStream
sFile = "U:/Log.txt"
Set FSO = New FileSystemObject
Set FSOFile = FSO.OpenTextFile(sFile, 2, True)
FSOFile.writeline (<Descriptions+Property/variable value>)
FSOFile.Close set FSO = nothing
I agree that it is a more work, but you'll know where to find the bug.
All depends on how hard and often you need this, in combination with how long the code is that you need to describe. Since I am not aware of your situation, I cannot judge on that.
In the end, it seems a lot of work, but actually it's quite easy since it's just describing the code that is already there.
Hope it helps.

Categories