繁体   English   中英

如何从设备和打印机IShellFolder获取打印机名称?

[英]How I can get printer name from device and printers IShellFolder?

我正在使用代码获取系统打印机图标(我发现的唯一方法是使用IShellFolder),现在我想将它们与InstalledPrinters连接起来,但是问题是-我找不到方法来找到真实的打印机名称(例如“ \\ ServerName \\ PrinterName“),与“设备和打印机”外壳文件夹的内容的显示名称不同,仅适用于PrinterSettings。

我用于检索“设备和打印机”外壳文件夹中的打印机图标和打印机标题的代码:

    Shell32.IShellFolder iDesktopFolder = Shell32.GetDesktopFolder();
    try
    {
        IntPtr pidlPrintersFolder;
        if (Shell32.SHGetFolderLocation(_hwndOwner, (int)Shell32.CSIDL.CSIDL_PRINTERS, IntPtr.Zero, 0, out pidlPrintersFolder) == 0)
            try
            {
                StringBuilder strDisplay = new StringBuilder(260);
                Guid guidIShellFolder = Shell32.IID_IShellFolder;
                IntPtr ptrPrintersShellFolder;
                iDesktopFolder.BindToObject(pidlPrintersFolder, IntPtr.Zero, ref guidIShellFolder, out ptrPrintersShellFolder);
                Object objPrintersShellFolder = Marshal.GetTypedObjectForIUnknown(ptrPrintersShellFolder, Shell32.ShellFolderType);
                try
                {
                    Shell32.IShellFolder printersShellFolder = (Shell32.IShellFolder)objPrintersShellFolder;

                    IntPtr ptrObjectsList;

                    printersShellFolder.EnumObjects(_hwndOwner, Shell32.ESHCONTF.SHCONTF_NONFOLDERS, out ptrObjectsList);
                    Object objEnumIDList = Marshal.GetTypedObjectForIUnknown(ptrObjectsList, Shell32.EnumIDListType);
                    try
                    {
                        Shell32.IEnumIDList iEnumIDList = (Shell32.IEnumIDList)objEnumIDList;
                        IntPtr[] rgelt = new IntPtr[1];
                        IntPtr pidlPrinter;
                        int pceltFetched;
                        Shell32.STRRET ptrString;
                        while (iEnumIDList.Next(1, rgelt, out pceltFetched) == 0 && pceltFetched == 1)
                        {
                            printersShellFolder.GetDisplayNameOf(rgelt[0],                                        
                                Shell32.ESHGDN.SHGDN_NORMAL, out ptrString);                                        
                            if (Shell32.StrRetToBuf(ref ptrString, rgelt[0], strDisplay,
                                (uint)strDisplay.Capacity) == 0)
                            {
                                pidlPrinter = Shell32.ILCombine(pidlPrintersFolder, rgelt[0]);
                                string printerDisplayName = strDisplay.ToString();

                                Shell32.SHFILEINFO shinfo = new Shell32.SHFILEINFO();
                                Shell32.SHGetFileInfo(this._pidl, 0, out shinfo, (uint)Marshal.SizeOf(shinfo), Shell32.SHGFI.PIDL | Shell32.SHGFI.AddOverlays | Shell32.SHGFI.Icon);
                                Icon printerIcon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone();
                                Shell32.DestroyIcon(shinfo.hIcon);

                                // HOW TO GET PRINTER NAME (\\ServerName\printername) WITH IS DIFFERENT FROM A PRINTER NAME IN "DEVICES AND PRINTERS" SYSTEM FOLDER
                            }
                        }
                    }
                    finally
                    {
                        Marshal.ReleaseComObject(objEnumIDList);
                    }
                }
                finally
                {
                    Marshal.ReleaseComObject(objPrintersShellFolder);
                }
            }
            finally
            {
                Shell32.ILFree(pidlPrintersFolder);
            }
    }
    finally
    {
        Marshal.ReleaseComObject(iDesktopFolder);
    }

谢谢你的帮助。

自己找到答案。

要枚举IShellFolder中的打印机,我们必须使用IShellFolder.ParseDisplayName方法(而不是EnumObjects),并将打印机名称从PrinterSettings.IntalledPrinters(例如对于网络打印机的“ \\ ServerName \\ PrinterName”)发送到IShellFolder.ParseDisplayName参数pszDisplayName,IShellFolder“设备和打印机”很好地工作。

因此,在此之后,我们可以枚举实际的打印机名称(“ \\ ServerName \\ PrinterName”),打印机显示名称(“在设备和打印机”中列出的打印机的“ ServerName上的打印机名称”)和打印机图标。

经过一些编辑后,我将在此处发布完整代码以供父亲搜索。

在循环中,可以使用当前rgelt[0]上的IID_IDataObject printersShellFolder.GetUIObjectOf ,并使用剪贴板"PrinterFriendlyName"调用IDataObject::GetData以获取真实的打印机名称(以STGMEDIUM编码)。

您也可以在当前pidl上为IID_IQueryInfo使用printersShellFolder.GetUIObjectOf来获取打印机状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM