0

I am trying to log the connected scanner on a pc.

I am using NTwain.dll from https://bitbucket.org/soukoku/ntwain.

If I run my app on a server some dependency dlls from ntwain fail to load so I will load the dll at runtime and if it will fail I just want to return an empty list. There is no reference to NTwain in the project references anymore.

Problem: If I have the NTwain.dll in the folder with the exe and I run it on a server the app crashes. It doesn't return an empty list. If I delete the dll and run the app the empty list gets returned.

Code:

public class Scanner : IDB
    {

        private enum DataGroups : uint
        {
            None = 0,
            Control = 0x1,
            Image = 0x2,
            Audio = 0x4,
            Mask = 0xffff,
        }

        public string Name { get; private set; }
        public string ProductFamily { get; private set; }
        public string Version { get; private set; }

        public Scanner()
        {
            Name = String.Empty;
        }

        public static List<Scanner> getScanners()
        {

            List<Scanner> scanners = new List<Scanner>();

            try
            {
                Assembly assembly = Assembly.LoadFrom(Environment.CurrentDirectory + "\\NTwain.dll");
                Type tident = assembly.GetType("NTwain.Data.TWIdentity");
                Type tsession = assembly.GetType("NTwain.TwainSession");
                object appId = tident.GetMethod("CreateFromAssembly").Invoke(null, new object[] { DataGroups.Image, System.Reflection.Assembly.GetExecutingAssembly() });
                object session = Activator.CreateInstance(tsession, appId);
                tsession.GetMethod("Open", new Type[0]).Invoke(session, null);
                object sources = session.GetType().GetMethod("GetSources").Invoke(session, null);

                foreach (var item in (IEnumerable)sources)
                {
                    Scanner scanner = new Scanner();
                    scanner.Name = (string)item.GetType().GetProperty("Name").GetValue(item, null);
                    scanner.ProductFamily = (string)item.GetType().GetProperty("ProductFamily").GetValue(item, null);
                    object version = item.GetType().GetProperty("Version").GetValue(item, null);
                    scanner.Version = (string)version.GetType().GetProperty("Info").GetValue(version, null);
                    scanners.Add(scanner);
                }
                return scanners;
            }
            catch (Exception e)
            {
                return new List<Scanner>();
            }
        }
}
user547995
  • 2,036
  • 8
  • 33
  • 62

1 Answers1

0

I would guess to catch a DllNotFoundException works in your code:

If u delete the dll then

Assembly assembly = Assembly.LoadFrom(Environment.CurrentDirectory + "\\NTwain.dll");

throws an DllNotFoundException which is catched by your catch block which says to return an empty list (which works as u say).

If u don't delete the dll then the code passes above line successfully. In case by the following lines a different thread is started and an error occurs that is not catched within that thread, then your catch block will not catch that error (whatever it might be) and the application crashes.

FWE
  • 103
  • 3
  • ok thx for the info. Is there a solution the catch the error and return my list? – user547995 Aug 20 '14 at 10:59
  • First you should try to find whats going wrong (f.i. by generating a log file). In the case of an exception from a new thread that is not catched in that particular thread, you need to get rid of that error - as far as I know there is no way to catch an exception from another thread. – FWE Aug 20 '14 at 11:05
  • i am pretty sure that --> tsession.GetMethod("Open", new Type[0]).Invoke(session, null); fails – user547995 Aug 20 '14 at 11:22
  • Perhaps you could check return of "tsession.GetMethod("Open", new Type[0])" and the "session" for correctness before u put everything together like u do at the moment in tsession.GetMethod("Open", new Type[0]).Invoke(session, null);. U could check properties of the MethodInfo u get as return value and do the same with the session object after parse it. – FWE Aug 20 '14 at 11:37
  • If one of them is not as expected then return the empty list. – FWE Aug 20 '14 at 11:43