1

我正在使用此代码进行扫描,
此代码在 32 位机器上运行良好,但我正在将我的应用程序切换到 64 位机器,但出现错误。我搜索了很多并找到了许多解决方案,
我发现可以编译的常见解决方案应用程序在 32 位机器上,但它不会提高我的应用程序性能,所以我不想在 64 位机器上使用这个解决方案。

错误是:

试图加载格式不正确的程序。(来自 HRESULT 的异常:0x8007000B)

代码是:

namespace TwainLib
{
    public enum TwainCommand
{
    Not = -1,
    Null = 0,
    TransferReady = 1,
    CloseRequest = 2,
    CloseOk = 3,
    DeviceEvent = 4
}

public class Twain
{
    private const short CountryUSA = 1;
    private const short LanguageUSA = 13;

    public Twain()
    {
        appid = new TwIdentity();
        appid.Id = IntPtr.Zero;
        appid.Version.MajorNum = 1;
        appid.Version.MinorNum = 1;
        appid.Version.Language = LanguageUSA;
        appid.Version.Country = CountryUSA;
        appid.Version.Info = "Hack 1";
        appid.ProtocolMajor = TwProtocol.Major;
        appid.ProtocolMinor = TwProtocol.Minor;
        appid.SupportedGroups = (int)(TwDG.Image | TwDG.Control);
        appid.Manufacturer = "NETMaster";
        appid.ProductFamily = "Freeware";
        appid.ProductName = "Hack";

        srcds = new TwIdentity();
        srcds.Id = IntPtr.Zero;

        evtmsg.EventPtr = Marshal.AllocHGlobal(Marshal.SizeOf(winmsg));
    }

    ~Twain()
    {
        Marshal.FreeHGlobal(evtmsg.EventPtr);
    }

    public void Init(IntPtr hwndp)
    {
        Finish();
        TwRC rc = DSMparent(appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.OpenDSM, ref hwndp);
        if (rc == TwRC.Success)
        {
            rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.GetDefault, srcds);
            if (rc == TwRC.Success)
                hwnd = hwndp;
            else
                rc = DSMparent(appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.CloseDSM, ref hwndp);
        }
    }

    public void Select()
    {
        TwRC rc;
        CloseSrc();
        if (appid.Id == IntPtr.Zero)
        {
            Init(hwnd);
            if (appid.Id == IntPtr.Zero)
                return;
        }
        rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.UserSelect, srcds);
    }

    /// <summary>
    /// Returns a list of twain sources
    /// </summary>
    /// <returns></returns>
    public IEnumerable<TwIdentity> GetSources()
    {
        TwRC rc;
        CloseSrc();
        if (appid.Id == IntPtr.Zero)
        {
            Init(hwnd);
            if (appid.Id == IntPtr.Zero)
                return null;
        }
        List<TwIdentity> sources = new List<TwIdentity>();
        TwIdentity identity = new TwIdentity();
        rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.GetFirst, identity);
        while (rc == TwRC.Success)
        {
            sources.Add(identity);
            identity = new TwIdentity();
            rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.GetNext, identity);
        }
        return sources;
    }

    /// <summary>
    /// Sets the source from which images will be acquired
    /// </summary>
    /// <param name="Source_p"></param>
    public void SetSource(TwIdentity Source_p)
    {
        srcds = Source_p;
    }

    public void Acquire()
    {
        TwRC rc;
        CloseSrc();
        if (appid.Id == IntPtr.Zero)
        {
            Init(hwnd);
            if (appid.Id == IntPtr.Zero)
                return;
        }
        rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.OpenDS, srcds);
        if (rc != TwRC.Success)
            return;

        TwCapability cap = new TwCapability(TwCap.XferCount, 1);
        rc = DScap(appid, srcds, TwDG.Control, TwDAT.Capability, TwMSG.Set, cap);
        if (rc != TwRC.Success)
        {
            CloseSrc();
            return;
        }

        TwUserInterface guif = new TwUserInterface();
        guif.ShowUI = 1;
        guif.ModalUI = 1;
        guif.ParentHand = hwnd;
        rc = DSuserif(appid, srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.EnableDS, guif);
        if (rc != TwRC.Success)
        {
            CloseSrc();
            return;
        }
    }

    public List<IntPtr> TransferPictures()
    {
        List<IntPtr> pics = new List<IntPtr>();
        if (srcds.Id == IntPtr.Zero)
            return pics;

        TwRC rc;
        IntPtr hbitmap = IntPtr.Zero;
        TwPendingXfers pxfr = new TwPendingXfers();

        do
        {
            pxfr.Count = 0;
            hbitmap = IntPtr.Zero;

            TwImageInfo iinf = new TwImageInfo();
            rc = DSiinf(appid, srcds, TwDG.Image, TwDAT.ImageInfo, TwMSG.Get, iinf);
            if (rc != TwRC.Success)
            {
                CloseSrc();
                return pics;
            }

            rc = DSixfer(appid, srcds, TwDG.Image, TwDAT.ImageNativeXfer, TwMSG.Get, ref hbitmap);
            if (rc != TwRC.XferDone)
            {
                CloseSrc();
                return pics;
            }

            rc = DSpxfer(appid, srcds, TwDG.Control, TwDAT.PendingXfers, TwMSG.EndXfer, pxfr);
            if (rc != TwRC.Success)
            {
                CloseSrc();
                return pics;
            }

            pics.Add(hbitmap);
        }
        while (pxfr.Count != 0);

        rc = DSpxfer(appid, srcds, TwDG.Control, TwDAT.PendingXfers, TwMSG.Reset, pxfr);
        return pics;
    }

    public TwainCommand PassMessage(ref Message m)
    {
        if (srcds.Id == IntPtr.Zero)
            return TwainCommand.Not;

        int pos = GetMessagePos();

        winmsg.hwnd = m.HWnd;
        winmsg.message = m.Msg;
        winmsg.wParam = m.WParam;
        winmsg.lParam = m.LParam;
        winmsg.time = GetMessageTime();
        winmsg.x = (short)pos;
        winmsg.y = (short)(pos >> 16);

        Marshal.StructureToPtr(winmsg, evtmsg.EventPtr, false);
        evtmsg.Message = 0;
        TwRC rc = DSevent(appid, srcds, TwDG.Control, TwDAT.Event, TwMSG.ProcessEvent, ref evtmsg);
        if (rc == TwRC.NotDSEvent)
            return TwainCommand.Not;
        if (evtmsg.Message == (short)TwMSG.XFerReady)
            return TwainCommand.TransferReady;
        if (evtmsg.Message == (short)TwMSG.CloseDSReq)
            return TwainCommand.CloseRequest;
        if (evtmsg.Message == (short)TwMSG.CloseDSOK)
            return TwainCommand.CloseOk;
        if (evtmsg.Message == (short)TwMSG.DeviceEvent)
            return TwainCommand.DeviceEvent;

        return TwainCommand.Null;
    }

    public void CloseSrc()
    {
        TwRC rc;
        if (srcds.Id != IntPtr.Zero)
        {
            TwUserInterface guif = new TwUserInterface();
            rc = DSuserif(appid, srcds, TwDG.Control, TwDAT.UserInterface, TwMSG.DisableDS, guif);
            rc = DSMident(appid, IntPtr.Zero, TwDG.Control, TwDAT.Identity, TwMSG.CloseDS, srcds);
        }
    }

    public void Finish()
    {
        TwRC rc;
        CloseSrc();
        if (appid.Id != IntPtr.Zero)
            rc = DSMparent(appid, IntPtr.Zero, TwDG.Control, TwDAT.Parent, TwMSG.CloseDSM, ref hwnd);
        appid.Id = IntPtr.Zero;
    }

    private IntPtr hwnd;
    private TwIdentity appid;
    private TwIdentity srcds;
    private TwEvent evtmsg;
    private WINMSG winmsg;



    // ------ DSM entry point DAT_ variants:
    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSMparent([In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, ref IntPtr refptr);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSMident([In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwIdentity idds);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSMstatus([In, Out] TwIdentity origin, IntPtr zeroptr, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwStatus dsmstat);


    // ------ DSM entry point DAT_ variants to DS:
    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSuserif([In, Out] TwIdentity origin, [In, Out] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, TwUserInterface guif);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSevent([In, Out] TwIdentity origin, [In, Out] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, ref TwEvent evt);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSstatus([In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwStatus dsmstat);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DScap([In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwCapability capa);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSiinf([In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwImageInfo imginf);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSixfer([In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, ref IntPtr hbitmap);

    [DllImport("twain_32.dll", EntryPoint = "#1")]
    private static extern TwRC DSpxfer([In, Out] TwIdentity origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwPendingXfers pxfr);


    [DllImport("kernel32.dll", ExactSpelling = true)]
    internal static extern IntPtr GlobalAlloc(int flags, int size);
    [DllImport("kernel32.dll", ExactSpelling = true)]
    internal static extern IntPtr GlobalLock(IntPtr handle);
    [DllImport("kernel32.dll", ExactSpelling = true)]
    internal static extern bool GlobalUnlock(IntPtr handle);
    [DllImport("kernel32.dll", ExactSpelling = true)]
    internal static extern IntPtr GlobalFree(IntPtr handle);

    [DllImport("user32.dll", ExactSpelling = true)]
    private static extern int GetMessagePos();
    [DllImport("user32.dll", ExactSpelling = true)]
    private static extern int GetMessageTime();


    [DllImport("gdi32.dll", ExactSpelling = true)]
    private static extern int GetDeviceCaps(IntPtr hDC, int nIndex);

    [DllImport("gdi32.dll", CharSet = CharSet.Auto)]
    private static extern IntPtr CreateDC(string szdriver, string szdevice, string szoutput, IntPtr devmode);

    [DllImport("gdi32.dll", ExactSpelling = true)]
    private static extern bool DeleteDC(IntPtr hdc);




    public static int ScreenBitDepth
    {
        get
        {
            IntPtr screenDC = CreateDC("DISPLAY", null, null, IntPtr.Zero);
            int bitDepth = GetDeviceCaps(screenDC, 12);
            bitDepth *= GetDeviceCaps(screenDC, 14);
            DeleteDC(screenDC);
            return bitDepth;
        }
    }


    [StructLayout(LayoutKind.Sequential, Pack = 4)]
    internal struct WINMSG
    {
        public IntPtr hwnd;
        public int message;
        public IntPtr wParam;
        public IntPtr lParam;
        public int time;
        public int x;
        public int y;
    }


} // class Twain

}

根据我的分析,这个错误是由于 64 位机器而发生的。请为此错误提出另一种解决方案。

4

2 回答 2

1

如果您使用的是 Twain 2.x (twaindsm.dll):

  • 32 位版本安装在 C:\Windows\SysWow64
  • 64位版本安装在C:\Windows\system32
  • 这些 dll 未在注册表中注册

如果您使用的是 Twain 1.x (twain_32.dll):

  • 32 位版本安装在 C:\Windows
  • 没有 64 位版本的 twain_32.dll

确保您的 DllImport 属性引用您尝试加载的正确 dll(twaindsm.dll 或 twain_32.dll)。确保构建设置中的平台目标与您尝试加载的 twain dll 匹配(x86、x64)。

于 2013-11-20T23:33:42.603 回答
0

Do you have TWAIN DSM on your machine? If not, please download & install it and try again.

Make sure your scanner has 64-bit TWAIN driver if you run your app as x64.

于 2013-08-22T06:27:17.280 回答