I am using the below code to get a running instance of MS Word.
I now have a compile problem with 'Use of unassigned local variable "oWord"'
here is my code:
Microsoft.Office.Interop.Word._Application oWord ;
try
{
// Is Word running?
oWord = Marshal.GetActiveObject("Word.Application") as Microsoft.Office.Interop.Word.Application; // ApplicationClass;
}
catch (COMException ce)
{
if (ce.ErrorCode == unchecked((int)0x800401E3))
// No, Word not in ROT, start a new instance
oWord = new Microsoft.Office.Interop.Word.Application();
}
// Use instance referened by _WordApp
oWord.ScreenUpdating = false; // < PROBLEM HERE
object objDefaultBehaviorWord8 = WdDefaultTableBehavior.wdWord8TableBehavior;
object objAutoFitFixed = WdAutoFitBehavior.wdAutoFitFixed;
//MAKING THE APPLICATION VISIBLE
oWord.Visible = Properties.Settings.Default.DebugMode;
oWord.DisplayAlerts = WdAlertLevel.wdAlertsNone;
but to my mind oWord is assigned, I'm guessing that the the compiler is looking at my Try..Catch block and saying I have unassigned oWord
So what's the correct way to assign this?
It might never get assigned if the Marshal.GetActiveObject
call fails, but the error code is something other than unchecked((int)0x800401E3)
.
You need to set oWord
to something when you first declare it:
Microsoft.Office.Interop.Word._Application oWord = null;
or
Microsoft.Office.Interop.Word._Application oWord = new Microsoft.Office.Interop.Word.Application();
I'd probably do the latter. That also removes the need for null checks further down the line, which right now you really should have since you're not fully aborting if there's an exception caught in that try/catch block.
(Having said that, if doing that will actually start Word if it's not already running, go with the first option and then make sure oWord
isn't still null after the try/catch.)
Just assign it a default null
value:
Microsoft.Office.Interop.Word._Application oWord = null;
This is necessary because the code currently assigns it a value in the if statement
of the catch {} block, so it's possible that oWord
never gets a value without the initial/default value.
Microsoft.Office.Interop.Word._Application oWord;
try
{
oWord = Marshal.GetActiveObject("Word.Application") as
Microsoft.Office.Interop.Word.Application;
}
catch (COMException ce)
{
if (ce.ErrorCode == unchecked((int)0x800401E3))
oWord = new Microsoft.Office.Interop.Word.Application();
}
oWord.ScreenUpdating = false;
Let's try to see why the compiler tells you that oWord
may not be assigned after this code has executed.
try
executes without exception, then oWord
must be assigned.COMException
it will be caught. If the error code is 0x800401E31
then oWord
is assigned.0x800401E3
, then oWord
is never assigned.We can annotate your code to demonstrate this more clearly:
Microsoft.Office.Interop.Word._Application oWord;
try
{
oWord = Marshal.GetActiveObject("Word.Application") as
Microsoft.Office.Interop.Word.Application;
}
catch (COMException ce)
{
// oWord still not initialized ....
if (ce.ErrorCode == unchecked((int)0x800401E3))
oWord = new Microsoft.Office.Interop.Word.Application();
else
; // .... and still not initialized ....
}
oWord.ScreenUpdating = false;
The simplest way to deal with this, in my view, is to re-throw the exception.
Microsoft.Office.Interop.Word._Application oWord;
try
{
oWord = Marshal.GetActiveObject("Word.Application") as
Microsoft.Office.Interop.Word.Application;
}
catch (COMException ce)
{
if (ce.ErrorCode != unchecked((int)0x800401E3))
throw;
oWord = new Microsoft.Office.Interop.Word.Application();
}
oWord.ScreenUpdating = false;
This avoids the need to initialiaze the variable to null
and later test for it still being null
.
What's more it explicitly deals with the error condition that your code fails to handle. Namely a COM error other than MK_E_UNAVAILABLE
.
User contributions licensed under CC BY-SA 3.0