1

プリンターの用紙ソース、用紙サイズなどのリストを取得したいです。http://www.pinvoke.net/default.aspx/Enums/DeviceCapabilities.html?diff=y のコードを少し変更しました。コードは時々機能します。時々そうではありません。問題は、DeviceCapabilities(DeviceName, strPort, DeviceCapabilitiesFlags.DC_BINNAMES, (IntPtr)null, (IntPtr)null) が -1 を返すことです。最後のエラーは「データが無効です」です。コンピューターを再起動しても問題が解決しない場合があります。問題が発生したら、次は大丈夫かもしれないし、そうでないかもしれません。

では、ここで何が問題なのですか?

ArrayList arrBinName;
string sError = "";
GetBins("\\Lindy-PC.MyCpmpany.local\HP LaserJet 4000 Series PCL 5", "LPT1", out arrBinName, out sError);

    public static bool GetBins(string DeviceName, string strPort, out ArrayList BinName, out string strError)
    {
        strError = "";
        BinName = new ArrayList();

        IntPtr pAddr = default(IntPtr);
        int offset = 0;

        int nRes = DeviceCapabilities(DeviceName, strPort, DeviceCapabilitiesFlags.DC_BINNAMES, (IntPtr)null, (IntPtr)null);  //Returns -1
        if (nRes >= 0)
        {
            try
            {
                pAddr = Marshal.AllocHGlobal((int)nRes * 24);
                nRes = DeviceCapabilities(DeviceName, strPort, DeviceCapabilitiesFlags.DC_BINNAMES, pAddr, (IntPtr)null);
                if (nRes < 0)
                {
                    strError = new Win32Exception(Marshal.GetLastWin32Error()).Message + "[" + DeviceName + ": " + strPort + ".DC_BINNAMES]";
                    return false;
                }

                offset = pAddr.ToInt32();
                for (int i = 0; i < nRes; i++)
                {
                    BinName.Add(Marshal.PtrToStringAnsi(new IntPtr(offset + i * 24)));
                }
            }
            finally
            {
                Marshal.FreeHGlobal(pAddr);
            }
        }
        else
            strError = new Win32Exception(Marshal.GetLastWin32Error()).Message + "[" + DeviceName + ": " + strPort + ".DC_BINNAMES]";

        return true;
    }
4

1 に答える 1

1

aggaton が彼または彼女のコメントで述べたようにDeviceCapabilities、特定の状況では 2 つの呼び出しが必要であり、ビン名の取得はその 1 つです。最初にDeviceCapabilitiesのドキュメントを読む必要があります。

次に戻って、使用したサンプル コードを確認します。重要なステップを省略しました:

// BinNames
nRes = DeviceCapabilities(strDeviceName, strPort, DeviceCapabilitiesFlags.DC_BINNAMES, (IntPtr)null, (IntPtr)null);
pAddr = Marshal.AllocHGlobal((int)nRes * 24);
nRes = DeviceCapabilities(strDeviceName, strPort, DeviceCapabilitiesFlags.DC_BINNAMES, pAddr, (IntPtr)null);
if(nRes < 0)
{
    strError = new Win32Exception(Marshal.GetLastWin32Error()).Message + "["+ strDeviceName +": "+ strPort +"]";
    return false;
}

そのコードには への3 つの呼び出しがあることに注意してください。DeviceCapabilities3 つすべてが必要です。(各呼び出しを別のコード行にすることでコードがより明確になると思いますが、それはスタイルの問題です。)DeviceCapabilities上記のサンプルコードとドキュメントのドキュメントは、あなたを軌道に乗せるはずです。

于 2015-11-11T05:46:35.370 に答える