Как однозначно идентифицировать перенаправленный принтер EasyPrint в сеансе RDP в Delphi (или через Windows API)? - PullRequest
1 голос
/ 04 апреля 2019

Мне нравится однозначно идентифицировать перенаправленный принтер EasyPrint во время сеанса RDP в Delphi. Каждый раз, когда пользователь подключается к сеансу RDP, имя принтера меняется, например: «HPLJP1606 (перенаправлено 6 )». Последний номер ( 6 ) всегда меняется, чтобы обеспечить уникальность имени принтера на сервере. В моей программе мне нравится сохранять некоторые параметры, связанные с принтером, которые зависят от модели принтера. Я ожидал найти что-то вроде GUID, чтобы идентифицировать принтер где-то немного похожий на MAC-адрес. Это должно позволить моей программе убедиться, что это тот же принтер, что был выбран ранее.

Я и мои коллеги изучили это решение: Как я могу однозначно определить очередь печати в Windows, даже если очередь переименована? Это не будет работать, потому что GUID отличается для каждого сеанса.

Мы также попытались обойти систему, чтобы переименовать принтер, но обобщить нелегко.

Есть ли способ идентифицировать базовый принтер EasyPrint без использования имени принтера в Delphi или через Windows API?

Я использую Delphi 10.2

Заранее спасибо,

1 Ответ

2 голосов
/ 11 апреля 2019

Я не пользуюсь delphi, но это должно вам помочь. Вам нужно использовать следующие функции из класса установки.

Вот примерный код Cpp, который я написал. Независимо от того, является ли принтер локальным / сетевым / перенаправленным принтером rdp, аппаратный идентификатор всегда будет одинаковым, даже если имя другое.

#include <Windows.h>
#include <stdio.h>
#include <SetupAPI.h>
#pragma comment(lib, "setupapi.lib")

void PrintPrinterIds(REFGUID ClassGuid)
{
    HDEVINFO hDevInfo = SetupDiGetClassDevs(&ClassGuid, NULL, NULL, DIGCF_PRESENT);
    if (hDevInfo == INVALID_HANDLE_VALUE)
    {
        wprintf(L"Cannot get devices : %d\n", GetLastError());
        return;
    }

    int idx = 0;
    DWORD errorVal = ERROR_SUCCESS;
    while (true)
    {
        SP_DEVINFO_DATA devInfoData = {};
        WCHAR regProp[512];
        devInfoData.cbSize = sizeof(devInfoData);

        if (!SetupDiEnumDeviceInfo(hDevInfo, idx, &devInfoData))
        {
            errorVal = GetLastError();
            break;
        }

        if (!SetupDiGetDeviceRegistryProperty(
            hDevInfo,
            &devInfoData,
            SPDRP_FRIENDLYNAME,
            NULL,
            (PBYTE)regProp,
            sizeof(regProp),
            NULL))
        {
            errorVal = GetLastError();
            break;
        }

        wprintf(L"Friendly name = %s\n", regProp);

        if (!SetupDiGetDeviceRegistryProperty(
            hDevInfo,
            &devInfoData,
            SPDRP_HARDWAREID,
            NULL,
            (PBYTE)regProp,
            sizeof(regProp),
            NULL))
        {
            errorVal = GetLastError();
            break;
        }

        // hardwareId is reg_multi_sz
        // Print all of the hardware ids for this device
        PWCHAR pId = regProp;
        do
        {
            wprintf(L"HardwareId = %s\n", pId);
            pId += wcslen(pId) + 1;
        } while (pId[0] != 0);

        // Point to next device
        idx++;
    }

    if (errorVal != ERROR_NO_MORE_ITEMS)
    {
        printf("Error : %d\n", errorVal);
    }

    SetupDiDestroyDeviceInfoList(hDevInfo);
}

int main()
{
    // {4d36e979-e325-11ce-bfc1-08002be10318}
    static const GUID PrinterClass =
    { 0x4d36e979, 0xe325, 0x11ce, { 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18 } };
    PrintPrinterIds(PrinterClass);

    // L"{1ed2bbf9-11f0-4084-b21f-ad83a8e6dcdc}"
    static const GUID PrinterQueue =
    { 0x1ed2bbf9, 0x11f0, 0x4084, { 0xb2, 0x1f, 0xad, 0x83, 0xa8, 0xe6, 0xdc, 0xdc } };
    PrintPrinterIds(PrinterQueue);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...