5

こんにちは、スタック オーバーフローです。

私はプログラミングの究極の初心者です。私はphpとvbaの経験があり、特にExcelで必要に応じて独自のスクリプトを実行しています。

最近、作業中のプロジェクトでは、同じコンピューターに接続された複数のスキャナー(最初は 2つとします) から自動的に(2 分ごとに) スキャンできるようにする必要があります。Visual Basic の感覚をつかむための出発点として、このプロジェクトを使用することにしました。というわけで、Visual Studio Express 2010 をインストールし、スクリプトを書き始めて、役立つコードをあちこちで見つけようとしました。私はWIAがそれを助けることができることを発見しました(トウェインも同様にできましたが、初心者の私にとってははるかにわかりにくいようです)

とはいえ、スキャナーが一台しか接続されていない場合でも、設定した間隔で自動スキャンできるアプリをついに思いつきました。複数のスキャナーを接続すると不具合が発生します。その後、最初のスキャンは正しく実行されますが (スキャナー 1 がスキャンし、次にスキャナー 2 がスキャンします)、2 番目のスキャンが開始されるはずのときに何も起こらず、スキャナーにアクセスできなくなります (ビジー)。最後に使用したスキャナーを「解放」または「切断」するのを忘れたのかもしれません。それとも、スキャナのバッファメモリに何か残っているのでしょうか?

過去 3 日間、この問題で立ち往生しており、それを機能させる方法がわかりません。

スキャンする機能は次のとおりです:(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

甘やかしてください。このコードはおそらくプログラミングのプロにとって悪夢のようなものであり、悪いことがたくさんあることは承知していますが、これは文字通り私の最初の VB プログラムであり、熱心に学びたいと思っています。

基本的に、プログラムの残りの部分は、スキャンの対象ディレクトリ、ファイル名、解像度などを入力するフォームです。「スキャンの開始」をクリックすると、最初にスキャナーループが実行され、「スキャンタイマー」が開始されます。ティックするたびにscannerloopを起動します。

私が言ったように、それは 1 つのスキャナー (期待どおりに作成されたファイル、更新されたログファイルなど) で完全に動作しますが、2 つのスキャナーがあるとすぐに、最初のスキャンのみが機能し、その後、スキャナー#1 がスキャンを開始するはずのときに機能しません。すると、scanner#2 の LED が点滅し始めます (スキャンしているように見えますが、スキャンしていません)。

誰かが私を助けてくれることを願っています。

前もって感謝します。

ヴィンス


更新 - 私が試したことは興味深いかもしれません: 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

これは、ループの最初の発生が機能することを示しました(各スキャナーから1回スキャンします)が、それだけです。スキャナーは2回目にスキャンせず、点滅を開始するため、基本的にまったく同じ問題です. また、新しいループに 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

しかし、何も変わりませんでした。

次に、ループ内のイベントをログに記録して、どこで停止したかを正確に把握できるようにしました。

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

生成されたログファイルは次のとおりです。

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

この行で問題が発生しているようです:

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

WIA はスキャナー 1 から 2 に切り替えることに満足しているようですが、次のラウンドでスキャナー 1 に戻ることを拒否しています。また、正確に言うと、2 番目のスキャンが発生するはずのときに、スキャナー #2 が点滅します (驚いたことに 1 ではありません)。スキャナー#2が「デフォルトスキャナー」またはそのようなものとして選択されている可能性はありますか?もしそうなら、それを元に戻す方法はありますか?

ご協力いただきありがとうございます

4

1 に答える 1