Исключение System.AccessViolationException при попытке получить кодеки
Приложение выполняет получение изображений со сканера. При попытке получения кодеков изображений GDI+ возникает исключение:
19.01.2015 12:11:06 - System.TypeInitializationException: Инициализатор типа "GdiPlusLib.Gdip" выдал исключение. ---> System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в System.Drawing.SafeNativeMethods.Gdip.GdipGetImageEncodersSize(Int32& numEncoders, Int32& size) в System.Drawing.Imaging.ImageCodecInfo.GetImageEncoders() в GdiPlusLib.Gdip..cctor() в D:\Ivan\ModuleScanWithSVN\mod_scan\mod_scan\TwainGui\GdiPlusLib.cs:строка 16 --- Конец трассировки внутреннего стека исключений --- в GdiPlusLib.Gdip.SaveDIBAs(String picname, IntPtr bminfo, IntPtr pixdat) в TwainGui.MainFrame.System.Windows.Forms.IMessageFilter.PreFilterMessage(Message& m) в D:\Ivan\ModuleScanWithSVN\mod_scan\mod_scan\TwainGui\MainFrame.cs:строка 464 в System.Windows.Forms.Application.ThreadContext.ProcessFilters(MSG& msg, Boolean& modified) в System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg) в System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG& msg) в System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData) в System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
в System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
в System.Windows.Forms.Application.Run(Form mainForm) в ThreadedSocket.Server.Scan(String tempPathToUse) в D:\Ivan\ModuleScanWithSVN\mod_scan\mod_scan\TwainGui\Server.cs:строка 404 в ThreadedSocket.Server.Main() в D:\Ivan\ModuleScanWithSVN\mod_scan\mod_scan\TwainGui\Server.cs:строка 167
GdiPlusLib.cs 16 строка:
private static ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
.NET Framework 4.5 Win7 x64
Обновление
Вопрос в том, с чем связано исключение "System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.", возникающее при попытке получить кодеки GDI+ следующим образом: ImageCodecInfo.GetImageEncoders();
? Как возможно исправить проблему? Есть два компа с одинаковой ОС Win 7 и одним framework-ом 4.5.1 - на одном есть проблема при выполнении приложения, а на другом нет такой проблемы.
При этом уже используется готовый код библиотеки
C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll
Здесь про подобную проблему пишут - насколько понятно, она в ОС, но где именно неясно.
using System;
using System.IO;
using System.Collections;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
namespace GdiPlusLib
{
public class Gdip
{
private static ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
private static bool GetCodecClsid( string filename, out Guid clsid )
{
clsid = Guid.Empty;
string ext = Path.GetExtension( filename );
if( ext == null )
return false;
ext = "*" + ext.ToUpper();
foreach( ImageCodecInfo codec in codecs )
{
if( codec.FilenameExtension.IndexOf( ext ) >= 0 )
{
clsid = codec.Clsid;
return true;
}
}
return false;
}
public static bool SaveDIBAs( string picname, IntPtr bminfo, IntPtr pixdat )
{
Guid clsid;
if (!GetCodecClsid(picname, out clsid))
{
MessageBox.Show("Unknown picture format for extension " + Path.GetExtension(picname),
"Image Codec", MessageBoxButtons.OK, MessageBoxIcon.Information);
return false;
}
IntPtr img = IntPtr.Zero;
int st = GdipCreateBitmapFromGdiDib(bminfo, pixdat, ref img);
if ((st != 0) || (img == IntPtr.Zero))
return false;
st = GdipSaveImageToFile(img, picname, ref clsid, IntPtr.Zero);
GdipDisposeImage(img);
return st == 0;
}
[DllImport("gdiplus.dll", ExactSpelling=true)]
internal static extern int GdipCreateBitmapFromGdiDib( IntPtr bminfo, IntPtr pixdat, ref IntPtr image );
[DllImport("gdiplus.dll", ExactSpelling=true, CharSet=CharSet.Unicode)]
internal static extern int GdipSaveImageToFile( IntPtr image, string filename, [In] ref Guid clsid, IntPtr encparams );
[DllImport("gdiplus.dll", ExactSpelling=true)]
internal static extern int GdipDisposeImage( IntPtr image );
}
}