However, when execute the following code, I get the error "The process
cannot access the file 'myFile.tif'" (File name has been shortened).
Here is the code I am using:
-- BEGIN CODE --
public class OCRUtil : IDisposable
{
const string FILENAME = "myFile.tif";
private MODI.Document doc = null;
/// <summary>
/// Initializes a new instance of the OCRUtil class.
/// </summary>
public OCRUtil(string filePath)
{
doc = new MODI.Document();
doc.Create(filePath);
doc.OCR(MODI.MiLANGUAGES.miLANG_SYSDEFAULT, true,
true);
// Using SaveAs() rather than Save() so that if other
classes
// wish to use the same file, we don't have to worry
about a
// contention.
doc.SaveAs(FILENAME,
MODI.MiFILE_FORMAT.miFILE_FORMAT_TIFF,
MODI.MiCOMP_LEVEL.miCOMP_LEVEL_HIGH);
}
public int GetImageCount()
{
return doc.Images.Count;
}
public void Dispose()
{
doc.Close(false);
doc = null;
GC.Collect();
if (File.Exists(FILENAME))
{
File.Delete(FILENAME);
}
}
}
[TestFixture]
public class OCRUtilTests
{
private string _filePath = @"..\..\2PageJournalFax.tif";
[Test]
public void TestOCRCount()
{
OCRUtil ocr = new OCRUtil(_filePath);
Assert.AreEqual(2, ocr.GetImageCount());
ocr.Dispose();
}
}
-- END CODE --
Here is the whole error message:
-- BEGIN ERROR MESSAGE --
TestCase 'Kahuna.OCR.Tests.OCRUtilTests.TestOCRRead'
failed: System.IO.IOException : The process cannot access the file
'D:\_Code\_Applications\KahunaOCR\Kahuna.OCR.Tests\bin\Debug\myFile.tif'
because it is being used by another process.
at System.IO.__Error.WinIOError(Int32 errorCode, String
maybeFullPath)
at System.IO.File.Delete(String path)
D:\_Code\_Applications\KahunaOCR\Kahuna.OCR\OCRUtil.cs(47,0):
at
Kahuna.OCR.OCRUtil.Dispose()
D:\_Code\_Applications\KahunaOCR\Kahuna.OCR.Tests\OCRUtilTests.cs(21,0):
at Kahuna.OCR.Tests.OCRUtilTests.TestOCRRead()
-- END ERROR MESSAGE --
Any ideas on how I can get the Document object to release its evil grip
on my defenseless file?
Thank you for your time.
Tod Birdsall, MCSD for .NET
blog: http://tod1d.net
> return doc.Images.Count;
> }
>
>
> public void Dispose()
> {
> doc.Close(false);
try this
Marshal.ReleaseComObject(doc);
> doc = null;
> GC.Collect();
> if (File.Exists(FILENAME))
> {
> File.Delete(FILENAME);
> }
> }
if that does not work, you should open the file using the winAPI CreateFile
(see http://www.pinvoke.net/ ) and one of the flags should be 'delete after
close'.
I am not sure that I understand your repsponse. At what point in my
code would I attempt to create "myFile.tif" using pinvoke? Would you
please provide an example?
Thank you.
Tod Birdsall, MCSD for .NET
blog: http://tod1d.net
I've the experience, that deleting the file just at the destructor gives
problems, especially in .NET.
Who creates the file? Do you create it or does the COM object do it?
If the COM object does it,
use Marshal.ReleaseComObject() as I suggested and try -then- to delete the
file!
If you do create it you can use the API directly.
http://www.pinvoke.net/default.aspx/kernel32/CreateFile.html
for the file flags, give this option.
FILE_FLAG_DELETE_ON_CLOSE
The miracle will happen, as soon as you close this file, it will be
destroyed from disk.
Thank you very much for your help.
I missed your suggestion about adding Marshal.ReleaseComObject() to my
code, in your first reply. Which teaches me to pay more attention to
detail.
The COM object creates the file when I call doc.SaveAs(). I tried
adding both Marshal.ReleaseComObject() and
Marshal.FinalReleaseComObject() at the point you suggested. But neither
when I tried to delete the file at the end of the Dispose() call.
However, the good news is that I was able to reuse the "myFile.tif"
file now. Before adding FinalReleaseComObject() to the Dispose() call,
I was unable to do this. So, rather than delete the file, I can now
safely reuse it.
Here is what my Dispose method looks like now:
-- BEGIN CODE --
public void Dispose()
{
doc.Close(false);
System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc);
doc = null;
GC.Collect();
}
-- END CODE --
And here is what my new test looks like:
-- BEGIN CODE --
/// <summary>
/// Tests that multiple OCR reads are successful.
/// </summary>
[Test]
public void TestMultiReads()
{
for (int i = 0; i < 5; i++)
{
OCRUtil ocr = new OCRUtil(_filePath);
Assert.AreEqual(2, ocr.GetImageCount());
string mySTring = ocr.GetImageText(0);
ocr.Dispose();
ocr = null;
Assert.IsTrue(mySTring.Contains("107"));
}
}
-- END CODE --