vb.net 使用 WIA 和 VB 从同一台计算机上的多个扫描仪自动扫描

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13598609/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 11:20:35  来源:igfitidea点击:

Automate scanning from multiple scanners on the same computer using WIA and VB

vb.netautomationwiascanning

提问by vincent

Hello Stack overflow !

你好堆栈溢出!

I'm the ultimate beginner in programming. I have some experience in php and vba, doing my own scripts as I need them, especially in excel.

我是编程的终极初学者。我在 php 和 vba 方面有一些经验,可以根据需要编写自己的脚本,尤其是在 excel 中。

Recently, for a project at works, I need to be able to scan AUTOMATICALLY(say every 2 minutes) from multiple scanners(say 2 for starters) both connected to the same computer. I decided to use this project as a start point for me to get a feeling of Visual Basic. So here we go, I installed visual studio express 2010 and started writing my script trying to find here and there bits of codes that could help me. I found that WIA could help with that (Twain could as well but it seems much more obscure to the newbie I am)

最近,对于工作中的一个项目,我需要能够从连接到同一台计算机的多个扫描仪(例如 2自动扫描(例如每 2 分钟一次)。我决定以这个项目为起点,让我感受一下 Visual Basic。所以我们开始了,我安装了 Visual Studio Express 2010 并开始编写我的脚本,试图在这里和那里找到一些可以帮助我的代码。我发现 WIA 可以帮助解决这个问题(吐温也可以,但对我这个新手来说似乎更模糊)

Anyway, I finally came up with an app that is able to automatically scan at the set interval when only one scanner is connected. The trouble arrives when I connect more than one scanner. then, the first scan occurs correctly (Scanner 1 scans, then scanner 2 scans), but when the second scan is supposed to start, nothing happens and the scanners become inaccessible (busy). I though maybe I forgot to "release" or "disconnect" the last scanner used. Or maybe, something remains in the scanner's buffer memory ?

无论如何,我终于想出了一个应用程序,当只连接一个扫描仪时,它能够以设定的时间间隔自动扫描。当我连接多个扫描仪时,问题就来了。然后,第一次扫描正确发生(扫描仪 1 扫描,然后扫描仪 2 扫描),但是当第二次扫描应该开始时,没有任何反应并且扫描仪变得无法访问(忙碌)。我虽然可能忘记了“释放”或“断开”上次使用的扫描仪。或者,扫描仪的缓冲存储器中还有一些东西?

I have been stuck on this issue for the last 3 days and don't know how to make it work.

过去 3 天我一直被困在这个问题上,不知道如何使它起作用。

here is the function that scans : (i don't past the rest as it is the UI and folder management)

这是扫描的功能:(我没有跳过其余部分,因为它是 UI 和文件夹管理)

 Public Sub scannerloop()

    'format constants
    Const wiaFormatBMP = "{B96B3CAB-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatPNG = "{B96B3CAF-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatGIF = "{B96B3CB0-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"
    Const wiaFormatTIFF = "{B96B3CB1-0728-11D3-9D7B-0000F81EF32E}"


    'file format
    Dim fileformat As String
    If Me.FileExt.SelectedItem = "TIF" Then fileformat = wiaFormatTIFF
    If Me.FileExt.SelectedItem = "JPEG" Then fileformat = wiaFormatJPEG
    If Me.FileExt.SelectedItem = "BMP" Then fileformat = wiaFormatBMP
    If Me.FileExt.SelectedItem = "PNG" Then fileformat = wiaFormatPNG
    If Me.FileExt.SelectedItem = "GIF" Then fileformat = wiaFormatGIF

    'colors
    Dim colorcode As Integer
    If Me.Colorbox.SelectedItem = "Black and white" Then colorcode = 4
    If Me.Colorbox.SelectedItem = "Greyscale" Then colorcode = 2
    If Me.Colorbox.SelectedItem = "Colour" Then colorcode = 1

    'Resolution
    Dim dpi As Integer
    dpi = Me.dpiBox.SelectedItem
    Dim horizextent = dpi * 8.2
    Dim vertextent = dpi * 11.6


    Dim j As String = 1
    Dim DeviceManager1 = CreateObject("WIA.DeviceManager")   'wia device manager

    For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices

        If DeviceManager1.DeviceInfos(i).Type = 1 Then  'Select only scanners, not webcams etc...

            'startpoint to calculate how long it is to scan
            Dim ScanStart = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)


            'Directory + file
            Dim targetdir = Me.ProjectFolderBox.Text & "\scans\Scanner" & j & "\S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
            Form2.CurrentActionLabel.Text = "Scanning from scanner #" & j


            Dim Scanner As WIA.Device = DeviceManager1.DeviceInfos(i).connect


            If IsNothing(Scanner) Then
                Log(Me.logfilename, Now & " | Scanner #" & j & " not found")
            Else
                Try
                    Dim Img As WIA.ImageFile

                    With Scanner.Items(1)
                        .Properties("6146").Value = colorcode '4 is Black-white,gray is 2, color 1 (Color Intent)
                        .Properties("6147").Value = dpi  'dots per inch/horizontal
                        .Properties("6148").Value = dpi 'dots per inch/vertical
                        .Properties("6149").Value = 0 'x point where to start scan
                        .Properties("6150").Value = 0 'y-point where to start scan

                        'Following is A4 paper size. (Not 100% accurate because real A4 Ht errors)
                        .Properties("6151").Value = horizextent 'horizontal exent DPI x inches wide
                        .Properties("6152").Value = vertextent 'vertical extent DPI x inches tall
                        '  .Properties("4104").Value = 8 'bits per pixel

                    End With

                    'transfer image
                    Img = Scanner.Items(1).Transfer(fileformat) 'scans the image.

                    'kill previous file if exists to avoid errors
                    If System.IO.File.Exists(targetdir) = True Then
                        Kill(targetdir)
                    End If

                    Img.SaveFile(targetdir)

                    'last scan
                    Form2.LastFileLabel.Text = "\Scanner" & j & "\S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
                    Form2.LastScanLabel.Text = Now

                Catch ex As Exception
                    MsgBox(ex.Message)
                Finally

                    Scanner = Nothing
                End Try
            End If

            'End time for the scan
            Dim ScanEnd = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)

            'log
            Log(Me.logfilename, Now & " | Scanner #" & j & " | Scanned " & targetdir & " | duration: " & (ScanEnd - ScanStart))

            j = j + 1



    Next
    DeviceManager1 = Nothing


    Me.CurrFileIndex = Me.CurrFileIndex + 1

    Me.ScanCount = Me.ScanCount + 1
    Me.NextScan = DateAdd("n", Me.IntervalBox.Value, Now)

    Form2.ScanCountLabel.Text = Me.ScanCount
    Form2.NextScanLabel.Text = Me.NextScan
    Form2.CurrentActionLabel.Text = "Waiting..."

    'Increment next file index and update in config file
    Me.FileIndexBox.Value = Me.CurrFileIndex
    SaveCfg()

End Sub

Please be indulgent with me, I am aware that the code is probably a nightmare for programming pros with lots of bad stuff, but it is literally my first VB program, and I am eager to learn.

请放纵我,我知道代码对于有很多坏东西的编程专业人士来说可能是一场噩梦,但它确实是我的第一个 VB 程序,我渴望学习。

So basically, the rest of the program is a form where I enter the target directory for the scan, the filenames, resolution etc, and when I click on 'start scanning', it - runs scannerloop one first time - starts a 'scantimer' which launches scannerloop each time it ticks.

所以基本上,程序的其余部分是一种形式,我在其中输入扫描的目标目录、文件名、分辨率等,当我单击“开始扫描”时,它 - 第一次运行扫描仪循环 - 启动“扫描计时器”每次打勾时都会启动scannerloop。

As I said, it works perfectly with 1 scanner (files created as expected, logfile updated, etc) but as soon as I have 2 scanners, only the first scan works and then, when scanner#1 is supposed to start scanning, it doesn't and the led of scanner#2 starts blinking (as if it was scanning, but it's not scanning)

正如我所说,它与 1 个扫描仪(按预期创建文件,更新日志文件等)完美配合,但是一旦我有 2 个扫描仪,只有第一次扫描有效,然后,当扫描仪#1 应该开始扫描时,它不会't 并且扫描仪#2 的 LED 开始闪烁(好像在扫描,但不是在扫描)

I hope someone will be able to help me.

我希望有人能够帮助我。

Thanks in advance.

提前致谢。

Vince

文斯



UPDATE - thing that I tried which may be of interest : I just tried to add a for loop to make it scan from both scanners several times (so, independantly from the timer and the rest of the program basically) :

更新 - 我尝试过的可能有趣的事情:我只是尝试添加一个 for 循环以使其从两个扫描仪扫描多次(因此,基本上独立于计时器和程序的其余部分):

Dim DeviceManager1 = CreateObject("WIA.DeviceManager")   'wia device manager
 For k = 1 To 3
            Dim j As String = 1
            For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices
[...]
          Next i
        Next k
        DeviceManager1 = Nothing

That showed that the first occurence of the loop works (scans once from each scanner) but that's it, the scanners never scan the second time and start blinking, so basically exactly the same problem. I also tried to include the Devicemanager declaration in the new loop :

这表明循环的第一次出现有效(从每个扫描仪扫描一次)但就是这样,扫描仪从不扫描第二次并开始闪烁,所以基本上完​​全相同的问题。我还尝试在新循环中包含 Devicemanager 声明:

 For k = 1 To 3 
Dim DeviceManager1 = CreateObject("WIA.DeviceManager")   'wia device manager
            Dim j As String = 1
            For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices
[...]
          Next i
        DeviceManager1 = Nothing
        Next k

but it did not change anything.

但它没有改变任何东西。

The next thing I did wat to log the events within the loop so that I can know where exactly things stop :

接下来我做的是记录循环中的事件,以便我可以知道事情到底在哪里停止:

Dim DeviceManager1 = CreateObject("WIA.DeviceManager") 'wia device manager Dim j As String = 1

Dim DeviceManager1 = CreateObject("WIA.DeviceManager") 'wia 设备管理器 Dim j As String = 1

For i = 1 To DeviceManager1.DeviceInfos.Count 'loop through all devices
    If DeviceManager1.DeviceInfos(i).Type = 1 Then  'Select only scanners, not webcams etc...

        'startpoint to calculate how long it is to scan
        Dim ScanStart = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)


        'Directory + file
        Dim targetdir = Me.ProjectFolderBox.Text & "\scans\Scanner" & j & "\S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
        Form2.CurrentActionLabel.Text = "Scanning from scanner #" & j


        Dim Scanner As WIA.Device = DeviceManager1.DeviceInfos(i).connect


        If IsNothing(Scanner) Then
            Log(Me.logfilename, Now & " | Scanner #" & j & " not found")
        Else
            Try
                Dim Img As WIA.ImageFile

                'log
                Log(Me.logfilename, Now & " | Scanner #" & j & " | Img initialized")

                With Scanner.Items(1)
                    .Properties("6146").Value = colorcode '4 is Black-white,gray is 2, color 1 (Color Intent)
                    .Properties("6147").Value = dpi  'dots per inch/horizontal
                    .Properties("6148").Value = dpi 'dots per inch/vertical
                    .Properties("6149").Value = 0 'x point where to start scan
                    .Properties("6150").Value = 0 'y-point where to start scan

                    'Following is A4 paper size. (Not 100% accurate because real A4 Ht errors)
                    .Properties("6151").Value = horizextent 'horizontal exent DPI x inches wide
                    .Properties("6152").Value = vertextent 'vertical extent DPI x inches tall
                    '  .Properties("4104").Value = 8 'bits per pixel

                End With

                'log
                Log(Me.logfilename, Now & " | Scanner #" & j & " | properties initialized")

                'transfer image
                Img = Scanner.Items(1).Transfer(fileformat) 'scans the image.

                'log
                Log(Me.logfilename, Now & " | Scanner #" & j & " |Transfer done")

                'kill previous file if exists to avoid errors
                If System.IO.File.Exists(targetdir) = True Then
                    Kill(targetdir)
                    'log
                    Log(Me.logfilename, Now & " | Scanner #" & j & " | deleted existing " & targetdir)

                End If

                Img.SaveFile(targetdir)
                'log
                Log(Me.logfilename, Now & " | Scanner #" & j & " | saved " & targetdir)

                'last scan
                Form2.LastFileLabel.Text = "\Scanner" & j & "\S" & j & "_" & Me.FilePrefix.Text & Me.CurrFileIndex & "." & Me.FileExt.SelectedItem
                Form2.LastScanLabel.Text = Now

            Catch ex As Exception
                MsgBox(ex.Message)
            Finally

                Scanner = Nothing
            End Try
        End If

        'End time for the scan
        Dim ScanEnd = DateAndTime.Second(Now) + (DateAndTime.Minute(Now) * 60) + (DateAndTime.Hour(Now) * 3600)

        'log
        Log(Me.logfilename, Now & " | Scanner #" & j & " | Scanned " & targetdir & " | duration: " & (ScanEnd - ScanStart))

        j = j + 1

    End If

Next i

and here is the logfile generated :

这是生成的日志文件:

Scan starts 29/11/2012 9:24:31 AM | Interval :Start scanning with 5 min | Res:100 DPI | 
29/11/2012 9:24:31 AM | Scanner #1 | Img initialized
29/11/2012 9:24:31 AM | Scanner #1 | properties initialized
29/11/2012 9:24:49 AM | Scanner #1 |Transfer done
29/11/2012 9:24:49 AM | Scanner #1 | saved C:\__2\scans\Scanner1\S1_img_1.TIF
29/11/2012 9:24:49 AM | Scanner #1 | Scanned C:\__2\scans\Scanner1\S1_img_1.TIF | duration: 18
29/11/2012 9:24:49 AM | Scanner #2 | Img initialized
29/11/2012 9:24:49 AM | Scanner #2 | properties initialized
29/11/2012 9:25:08 AM | Scanner #2 |Transfer done
29/11/2012 9:25:08 AM | Scanner #2 | saved C:\__2\scans\Scanner2\S2_img_1.TIF
29/11/2012 9:25:08 AM | Scanner #2 | Scanned C:\__2\scans\Scanner2\S2_img_1.TIF | duration: 19
29/11/2012 9:25:08 AM | Scanner #1 | Img initialized
29/11/2012 9:25:08 AM | Scanner #1 | properties initialized

it appears that things go wrong at this line :

看来这行出了问题:

Img = Scanner.Items(1).Transfer(fileformat) 'scans the image.

It looks like WIA is happy to switch from scanner 1 to 2 but refuses to come back to scanner 1 for the next round. also, I should precise, when the second scan is supposed to occur, scanner #2 blinks (and not 1 which surprises me). Is it possible that scanner#2 is selected as "default scanner" or something like that and if so, is there a way to revert that ?

看起来 WIA 很高兴从扫描仪 1 切换到 2,但拒绝在下一轮返回到扫描仪 1。另外,我应该准确地说,当应该发生第二次扫描时,扫描仪 #2 会闪烁(而不是让我感到惊讶的 1)。扫描仪#2 是否有可能被选为“默认扫描仪”或类似的东西,如果是这样,有没有办法恢复它?

thanks for your help

感谢您的帮助

回答by muhannad

this code for scanning image :"dont forget adding wiaaut.DLL from windows\sys32 to solution ref." first check if scanner device is attached

用于扫描图像的此代码:“不要忘记将 wiaaut.DLL 从 windows\sys32 添加到解决方案参考。” 首先检查是否连接了扫描仪设备

Dim tempfile As String
Dim mydevice As WIA.Device
Dim item As WIA.Item
Dim imfile As WIA.ImageFile
Dim Commondialog1 As WIA.CommonDialog
sub check()
  On Error Resume Next
    Commondialog1 = New WIA.CommonDialog
    mydevice = Commondialog1.ShowSelectDevice
    MsgBox(mydevice.Type)

  On Error GoTo Err_btnTakePicture_click

end sub
'then connect to scanner

sub scan()
    'put the path and name for the location of your temp file here.
    tempfile = ("d:\filename.jpg")

    'the next 4 lines deletes the old temp file if it exists
    Dim filesystemobject = CreateObject("Scripting.FileSystemObject")
    If filesystemobject.fileExists(tempfile) Then
        Kill(tempfile)
    End If

    'the next two lines set up the configuration
    Dim Commondialog1 As New WIA.CommonDialog
    mydevice = Commondialog1.ShowSelectDevice

    Dim wiaFormatJPEG As String = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}"

    item = mydevice.Items(1)


    imfile = DirectCast(Commondialog1.ShowTransfer(item, wiaFormatJPEG, False), WIA.ImageFile)

    'this line saves the picture to a specified file
    imfile.SaveFile(tempfile)


    MsgBox("Picture taken")
    PictureBox1.ImageLocation = tempfile

  Exit_btnTakePicture_click:
    mydevice = Nothing
    item = Nothing
    Exit Sub

  Err_btnTakePicture_click:
    MsgBox(Err.Description, vbOKOnly + vbCritical, "Error Taking Picture")
    Resume Exit_btnTakePicture_click
   end sub