none
Scanning in Windows 10, unknown Parameter of Scansetting.dll RRS feed

  • Question

  • Hello,

    for scanning in our application we use the WIA COM Library for years.

    A few days ago I saw that the Windows Fax and Scan Tools have a new Scan Interface.

    I tested it and noticed that I works better with feed scanners.

    The Windows Fax and Scan tools uses the scansetting.dll.

    I tried to implement a sample project with the scansetting.dll,

    but there's a lack of information about the necessary parameters to

    chosse another scanner as the standart scanner.

    I only found the parameter (in VB.net) of the function GetImageDialog

    GetImageDialog(hWndParent As IntPtr, pwsFolder As String, pwsFilename As String, ByRef plNumFiles As IntPtr, ByRef p2 As IntPtr, ByRef pWiaItem21 As IntPtr, pWiaItem22 As IntPtr, nDisplay As Integer) As Integer

    But I found no way to refer to the selected WIA Device before, because it is a COM Object,

    and I've not information what p2, pWiaItem21 and pWiaItem22 mean.

    I conclusion, I need information about the Exported DLL functions like GetImageDialog, ProfilesDialog, ProgDlgTakeFgIfShowing and GetDefaultProfileScan with the necessary parameters and if feasible a sample how to set scanner or scan profil.

    Regards,

    bbuech

    Wednesday, February 14, 2018 11:59 AM

Answers

  • Yes, I tested in C++ and VB.NET

    In fact, I get the same dialog boxes with IWiaDevMgr2::GetImageDlg :

    Dim pWiaDevMgr2 As IWiaDevMgr2
    
    Dim CLSID_WiaDevMgr2 As New Guid("B6C292BC-7C88-41EE-8B54-8EC92617E599")
    Dim WiaDevMgr2Type As Type = Type.GetTypeFromCLSID(CLSID_WiaDevMgr2, True)
    Dim WiaDevMgr2 As Object = Activator.CreateInstance(WiaDevMgr2Type)
    pWiaDevMgr2 = DirectCast(WiaDevMgr2, IWiaDevMgr2)
    
    Dim sFolder As String = "E:\\test"
    Dim sFile As String = "Image"
    Dim nNumFiles As Integer = 0
    Dim pItem As IntPtr
    Dim sFilePaths() As String = New String() {}
    Dim hr As HRESULT = HRESULT.E_FAIL
    
    hr = pWiaDevMgr2.GetImageDlg(0, Nothing, Me.Handle, sFolder, sFile, nNumFiles, sFilePaths, pItem)
    with (I did not test all functions, some could be wrong...) =>

    Public Enum HRESULT As Integer
        S_OK = 0
        S_FALSE = 1
        E_NOINTERFACE = &H80004002
        E_NOTIMPL = &H80004001
        E_FAIL = &H80004005
    End Enum
    
    Public Enum STI_DEVICE_MJ_TYPE As Integer
        StiDeviceTypeDefault = 0
        StiDeviceTypeScanner = 1
        StiDeviceTypeDigitalCamera = 2
        StiDeviceTypeStreamingVideo = 3
    End Enum
    
    Public Const WIA_DEVINFO_ENUM_ALL = &HF
    Public Const WIA_DEVINFO_ENUM_LOCAL = &H10
    
    <ComImport>
    <Guid("79C07CF1-CBDD-41ee-8EC3-F00080CADA7A")>
    <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
    Public Interface IWiaDevMgr2
        Function EnumDeviceInfo(lFlags As Integer, ByRef ppIEnum As IntPtr) As HRESULT
        Function CreateDevice(lFlags As Integer, bstrDeviceID As String, ByRef ppWiaItem2Root As IntPtr) As HRESULT
        Function SelectDeviceDlg(hwndParent As IntPtr, lDeviceType As Integer, lFlags As Integer, ByRef pbstrDeviceID As String, ByRef ppItemRoot As IntPtr) As HRESULT
        Function SelectDeviceDlgID(hwndParent As IntPtr, lDeviceType As Integer, lFlags As Integer, ByRef pbstrDeviceID As String) As HRESULT
        Function RegisterEventCallbackInterface(lFlags As Integer, bstrDeviceID As String, pEventGUID As Guid, pIWiaEventCallback As IntPtr, ByRef pEventObject As IntPtr) As HRESULT
        Function RegisterEventCallbackProgram(lFlags As Integer, bstrDeviceID As String, pEventGUID As Guid, bstrFullAppName As String, bstrCommandLineArg As String, bstrName As String, bstrDescription As String, bstrIcon As String) As HRESULT
        Function RegisterEventCallbackCLSID(lFlags As Integer, bstrDeviceID As String, pEventGUID As Guid, pClsID As Guid, bstrName As String, bstrDescription As String, bstrIcon As String) As HRESULT
        Function GetImageDlg(lFlags As Integer, bstrDeviceID As String, hwndParent As IntPtr, bstrFolderName As String, bstrFilename As String, ByRef plNumFiles As Integer,
                            <Out> <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=5, ArraySubType:=UnmanagedType.BStr)> ByRef ppbstrFilePaths As String(), ByRef ppItem As IntPtr) As HRESULT
    End Interface
    
    <DllImport("ScanSetting.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Public Shared Function GetImageDialog(hWndParent As IntPtr, pwsFolder As String, pwsFilename As String, ByRef plNumFiles As IntPtr, ByRef p2 As IntPtr, ByRef pWiaItem21 As IntPtr, pWiaItem22 As IntPtr, nDisplay As Integer) As HRESULT
    End Function
    
    <DllImport("ScanSetting.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Public Shared Function ProfilesDialog(hWndParent As IntPtr) As HRESULT
    End Function

    • Marked as answer by bbuech Thursday, February 15, 2018 5:16 PM
    Thursday, February 15, 2018 3:51 PM

All replies

  • I did some tests with 2 scanners and the last IWiaItem2* of GetImageDialog is used to initialize the dialog box with the right scanner
    (I called IWiaDevMgr2::SelectDeviceDlgID then IWiaDevMgr2::CreateDevice first to get it)

    • Edited by Castorix31 Wednesday, February 14, 2018 4:32 PM
    Wednesday, February 14, 2018 4:31 PM
  • ProfilesDialog seems to be something like :

    typedef HRESULT(WINAPI * PPD)(HWND hWndParent);

    (the Dialog box is correctly displayed when tested with GetProcAddress)

    Wednesday, February 14, 2018 5:02 PM
  • I need the function declaration in VB.net.

    I could implement this functionality in C++ as Console Application, which is called by the VB.net Process.

    Is there any way to call IWiaDevMgr2::CreateDevice from VB.net?

    Thursday, February 15, 2018 1:08 PM
  • Yes, I tested in C++ and VB.NET

    In fact, I get the same dialog boxes with IWiaDevMgr2::GetImageDlg :

    Dim pWiaDevMgr2 As IWiaDevMgr2
    
    Dim CLSID_WiaDevMgr2 As New Guid("B6C292BC-7C88-41EE-8B54-8EC92617E599")
    Dim WiaDevMgr2Type As Type = Type.GetTypeFromCLSID(CLSID_WiaDevMgr2, True)
    Dim WiaDevMgr2 As Object = Activator.CreateInstance(WiaDevMgr2Type)
    pWiaDevMgr2 = DirectCast(WiaDevMgr2, IWiaDevMgr2)
    
    Dim sFolder As String = "E:\\test"
    Dim sFile As String = "Image"
    Dim nNumFiles As Integer = 0
    Dim pItem As IntPtr
    Dim sFilePaths() As String = New String() {}
    Dim hr As HRESULT = HRESULT.E_FAIL
    
    hr = pWiaDevMgr2.GetImageDlg(0, Nothing, Me.Handle, sFolder, sFile, nNumFiles, sFilePaths, pItem)
    with (I did not test all functions, some could be wrong...) =>

    Public Enum HRESULT As Integer
        S_OK = 0
        S_FALSE = 1
        E_NOINTERFACE = &H80004002
        E_NOTIMPL = &H80004001
        E_FAIL = &H80004005
    End Enum
    
    Public Enum STI_DEVICE_MJ_TYPE As Integer
        StiDeviceTypeDefault = 0
        StiDeviceTypeScanner = 1
        StiDeviceTypeDigitalCamera = 2
        StiDeviceTypeStreamingVideo = 3
    End Enum
    
    Public Const WIA_DEVINFO_ENUM_ALL = &HF
    Public Const WIA_DEVINFO_ENUM_LOCAL = &H10
    
    <ComImport>
    <Guid("79C07CF1-CBDD-41ee-8EC3-F00080CADA7A")>
    <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
    Public Interface IWiaDevMgr2
        Function EnumDeviceInfo(lFlags As Integer, ByRef ppIEnum As IntPtr) As HRESULT
        Function CreateDevice(lFlags As Integer, bstrDeviceID As String, ByRef ppWiaItem2Root As IntPtr) As HRESULT
        Function SelectDeviceDlg(hwndParent As IntPtr, lDeviceType As Integer, lFlags As Integer, ByRef pbstrDeviceID As String, ByRef ppItemRoot As IntPtr) As HRESULT
        Function SelectDeviceDlgID(hwndParent As IntPtr, lDeviceType As Integer, lFlags As Integer, ByRef pbstrDeviceID As String) As HRESULT
        Function RegisterEventCallbackInterface(lFlags As Integer, bstrDeviceID As String, pEventGUID As Guid, pIWiaEventCallback As IntPtr, ByRef pEventObject As IntPtr) As HRESULT
        Function RegisterEventCallbackProgram(lFlags As Integer, bstrDeviceID As String, pEventGUID As Guid, bstrFullAppName As String, bstrCommandLineArg As String, bstrName As String, bstrDescription As String, bstrIcon As String) As HRESULT
        Function RegisterEventCallbackCLSID(lFlags As Integer, bstrDeviceID As String, pEventGUID As Guid, pClsID As Guid, bstrName As String, bstrDescription As String, bstrIcon As String) As HRESULT
        Function GetImageDlg(lFlags As Integer, bstrDeviceID As String, hwndParent As IntPtr, bstrFolderName As String, bstrFilename As String, ByRef plNumFiles As Integer,
                            <Out> <MarshalAs(UnmanagedType.LPArray, SizeParamIndex:=5, ArraySubType:=UnmanagedType.BStr)> ByRef ppbstrFilePaths As String(), ByRef ppItem As IntPtr) As HRESULT
    End Interface
    
    <DllImport("ScanSetting.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Public Shared Function GetImageDialog(hWndParent As IntPtr, pwsFolder As String, pwsFilename As String, ByRef plNumFiles As IntPtr, ByRef p2 As IntPtr, ByRef pWiaItem21 As IntPtr, pWiaItem22 As IntPtr, nDisplay As Integer) As HRESULT
    End Function
    
    <DllImport("ScanSetting.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
    Public Shared Function ProfilesDialog(hWndParent As IntPtr) As HRESULT
    End Function

    • Marked as answer by bbuech Thursday, February 15, 2018 5:16 PM
    Thursday, February 15, 2018 3:51 PM
  • This does exactly want I need.

    I don't know that the IWiaDevMgr2 handles the scanners choice itself.

    So I've no need for the scansetting.dll.

    Thanks a lot for your help.

    Thursday, February 15, 2018 5:16 PM
  • Scansetting.dll contains the common WIA 2.0 scan dialog. The app developer does not use it directly from an app but still via the WIA COM API.

    A better alternative today and one that works for Store apps as well is the Windows Runtime Scan API:

    MSDN: https://docs.microsoft.com/en-us/uwp/api/Windows.Devices.Scanners

    The Microsoft Scan app available in the App Store is using this API.

    If there is need to remain with the COM API, for just desktop Win32 apps, see this tutorial:

    MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms629859(v=vs.85).aspx

    There is also the old WIA Scripting (OLE Automation) for scripted apps but please note this API is limited in functionality. C#, VB, etc. developers may want to use the Windows Runtime API instead.

    MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms630203(v=vs.85).aspx

    Thursday, February 15, 2018 7:44 PM