.NET StillImage,RegisterLaunchApplication

时间:2013-11-10 20:19:55

标签: c# .net sti

我正在尝试注册扫描程序扫描操作的应用程序。以下代码应该这样做:

public class Class1
{
    [ComImport]
    [Guid("641BD880-2DC8-11D0-90EA-00AA0060F86C")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    public interface IStillImage
    {
        [PreserveSig]
        int RegisterLaunchApplication([In, MarshalAs(UnmanagedType.LPWStr)] string pwszAppName, [In, MarshalAs(UnmanagedType.LPWStr)] string pwszCommandLine);
    }

    [DllImport("kernel32.dll")]
    static extern IntPtr GetModuleHandle(
    [MarshalAs(UnmanagedType.LPWStr)] string lpModuleName);

    [DllImport("sti.dll", EntryPoint = "StiCreateInstanceW")]
    static extern int StiCreateInstance(IntPtr hinst, int dwVer, out IStillImage ppSti, IntPtr punkOuter);

    const int STI_VERSION_3 = 0x01000003;

    public static void DoStaff()
    {
        IntPtr hinst = GetModuleHandle(null);
        IStillImage sti;
        int ret = StiCreateInstance(hinst, STI_VERSION_3, out sti, IntPtr.Zero);
        ret = sti.RegisterLaunchApplication("SuperTruperApp", @"c:\Windows\notepad.exe");
    }

}

但在运行此代码后,我总是收到错误-2147024809 => 0x80070057应该代表错误的论点。

我在http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.interop/2008-04/msg00123.html上发现同样的问题是否有人有工作解决方案?

下一个问题是关于成功取消注册: - )

非常感谢

2 个答案:

答案 0 :(得分:1)

我在这个主题上取得了很大的进步。我从EverNote源代码复制了STI接口实现,这个解决方案也正常运行。

namespace StiWorks
{
//COPY OF https://github.com/ryanmcdonnell/ScanToEvernote/blob/c8fd7dfed041950499afe7578700199461a37c65/ScanToEvernote/Sti.cs


public enum STI_DEVICE_TYPE : int
{
    StiDeviceTypeDefault = 0,
    StiDeviceTypeScanner = 1,
    StiDeviceTypeDigitalCamera = 2,
    StiDeviceTypeStreamingVideo = 3
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STI_DEV_CAPS
{
    public int dwGeneric;
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct STI_DEVICE_INFORMATIONW
{
    private const int STI_MAX_INTERNAL_NAME_LENGTH = 128;

    public int dwSize;

    public STI_DEVICE_TYPE DeviceType;

    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = STI_MAX_INTERNAL_NAME_LENGTH)]

    string szDeviceInternalName;

    public STI_DEV_CAPS DeviceCapabilities;

    public int dwHardwareConfiguration;

    [MarshalAs(UnmanagedType.LPWStr)]

    public string pszVendorDescription;

    [MarshalAs(UnmanagedType.LPWStr)]

    public string pszDeviceDescription;

    [MarshalAs(UnmanagedType.LPWStr)]

    public string pszPortName;

    [MarshalAs(UnmanagedType.LPWStr)]

    public string pszPropProvider;

    [MarshalAs(UnmanagedType.LPWStr)]

    public string pszLocalName;

}

[Guid("641BD880-2DC8-11D0-90EA-00AA0060F86C"), // IStillImageW
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStillImage // cannot list any base interfaces here
{
    // note that IUnknown Interface members are NOT listed here
    void Initialize(IntPtr hinst, [In] int dwVersion);

    void GetDeviceList([In] int dwType, [In] int dwFlags, [Out] out int pdwItemsReturned, [In, Out] IntPtr ppBuffer);

    void GetDeviceInfo([In, MarshalAs(UnmanagedType.LPWStr)] string pwszDeviceName, [In, Out] IntPtr ppBuffer);

    void CreateDevice([In, MarshalAs(UnmanagedType.LPWStr)] string pwszDeviceName, [In] int dwMode, [In, Out] IntPtr pDevice, [In, Out] IntPtr punkOuter);

    void GetDeviceValue([In, MarshalAs(UnmanagedType.LPWStr)] string pwszDeviceName, [In, MarshalAs(UnmanagedType.LPWStr)] string pValueName, [In, Out] ref int pType, [In, Out] StringBuilder pData, [In, Out] ref int cbData);

    void SetDeviceValue([In, MarshalAs(UnmanagedType.LPWStr)] string pwszDeviceName, [In, MarshalAs(UnmanagedType.LPWStr)] string pValueName, [In] int Type, [In, Out] IntPtr pData, [In] int cbData);

    void GetSTILaunchInformation([In, Out, MarshalAs(UnmanagedType.LPWStr)] ref string pwszDeviceName, [In, Out] ref int pdwEventCode, [In, Out, MarshalAs(UnmanagedType.LPWStr)] ref string pwszEventName);

    void RegisterLaunchApplication([In, MarshalAs(UnmanagedType.LPWStr)] string pwszAppName, [In, MarshalAs(UnmanagedType.LPWStr)] string pwszCommandLine);

    void UnregisterLaunchApplication([In, MarshalAs(UnmanagedType.LPWStr)] string pwszAppName);

    void EnableHwNotifications([In, MarshalAs(UnmanagedType.LPWStr)] string pwszDeviceName, [In] bool bNewState);

    void GetHwNotificationState([In, MarshalAs(UnmanagedType.LPWStr)] string pwszDeviceName, [In, Out] ref bool pbCurrentState);

    void RefreshDeviceBus([In, MarshalAs(UnmanagedType.LPWStr)] string pwszDeviceName);

    void LaunchApplicationForDevice([In, MarshalAs(UnmanagedType.LPWStr)]
            string pwszDeviceName, [In, MarshalAs(UnmanagedType.LPWStr)] string
            pwszAppName, [In, Out] IntPtr pStiNofify);

    void SetupDeviceParameters([In, Out] ref STI_DEVICE_INFORMATIONW pDeviceInfo);

    void WriteToErrorLog([In] int dwMessageType, [In, MarshalAs(UnmanagedType.LPWStr)] string pszMessage);
}

[ComImport, Guid("B323F8E0-2E68-11D0-90EA-00AA0060F86C")]
public class Sti
{

}

以及在应用程序注册代码中的用法

        Sti sti = new Sti();
        IStillImage stillImage = (IStillImage) sti;
        stillImage.RegisterLaunchApplication("MY_ID_I_WANT_TO_BE_IN_REGISTRY", "C:\ApplicationToRegister.exe");

在应用程序取消注册的代码中的用法

        Sti sti = new Sti();
        IStillImage stillImage = (IStillImage) sti;
        stillImage.UnregisterLaunchApplication("MY_ID_I_WANT_TO_BE_IN_REGISTRY");

答案 1 :(得分:0)

您错过了界面中的某些方法,因此您调用了Initialize方法而不是RegisterLaunchApplication方法。请尝试使用下一个界面(除RegisterLaunchApplicationUnregisterLaunchApplication之外的所有方法都是存根):

[ComImport]
[Guid("641BD880-2DC8-11D0-90EA-00AA0060F86C")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStillImage
{
    int Initialize();

    int GetDeviceList();

    int GetDeviceInfo();

    int CreateDevice();

    int GetDeviceValue();

    int SetDeviceValue();

    int GetSTILaunchInformation();

    [PreserveSig]
    int RegisterLaunchApplication([In, MarshalAs(UnmanagedType.LPWStr)] string pwszAppName, [In, MarshalAs(UnmanagedType.LPWStr)] string pwszCommandLine);

    [PreserveSig]
    int UnregisterLaunchApplication([In, MarshalAs(UnmanagedType.LPWStr)] string pwszAppName);
}