【问题标题】:How to un-share shared printer?如何取消共享共享打印机?
【发布时间】:2015-05-18 00:44:02
【问题描述】:

我正在通过 C# 开发“共享监控应用程序”,它正在监控共享活动,我正在使用这些 API 来实现枚举共享项目/取消共享共享项目。

使用的 API:

NetShareEnum
NetShareDel


NetShareEnum 枚举所有共享项,NetShareDel 删除共享项 (=unshare)。
我使用SHChangeNotify 删除共享标记和目录工作正常。
(使用NetShareDel 删除共享项目不会立即受到影响。)

但打印机状态不受SHChangeNotify 的影响。这意味着在通过NetShareDel 删除共享打印机并使用SHCNE_NETUNSHARE 和SHCNF_PATHW 调用SHChangeNotify 之后。我也使用了SHCNE_NETUNSHARE 和SHCNF_PRINTERW,但什么也没发生。

共享打印机的状态标记: http://i.stack.imgur.com/1ZGrI.png
在这张图片中,您可以在检查圈的右侧看到用户,表示打印机是共享的。
但是在调用NetShareDel到非共享共享打印机后成功了,但是共享标记消失了。

有人知道如何实现吗?我在等你的帮助。 :D
对不起我的英语不好。

【问题讨论】:

    标签: c# windows printing share shared


    【解决方案1】:

    您是否尝试过通过 WMI? 我自己没有使用它来“取消共享”打印机,但我在应用程序中经常使用它来以其他方式编辑打印机和打印机端口。 我认为这样的事情应该可以解决问题。

    Win32_Printer 类看起来具有“共享”属性,因此我建议尝试将其切换为 false。 https://msdn.microsoft.com/en-us/library/aa394363%28v=vs.85%29.aspx

    我没有测试过取消共享的代码,但它与我用来更改其他属性的代码完全相同。

    //get the printer(s) through wmi query
    //prep query
    SelectQuery query = new SelectQuery(string.Format("select * from Win32_Printer WHERE Name = '{0}'", "printername"));
    //create scope (connect to server)
    ManagementScope scope = new ManagementScope("\\\\serverName\\root\\cimv2");
    //search for printers
    ManagementObjectSearcher search = new ManagementObjectSearcher(scope, query);
    //get collection of printers (should be 0 or 1, but it returns a collection regardless because of the query
    ManagementObjectCollection printers = search.Get();
    //iterate through the 0-1 printers and set Shared to false
    foreach (ManagementObject printer in printers)
    {
        printer.SetPropertyValue("Shared",false);
        printer.put();
    }
    

    【讨论】:

    • 感谢您的回答!!用这种方式解决了问题。非常感谢!!
    【解决方案2】:

    我尝试了 WMI,它在我的计算机上运行,​​但其他计算机抛出异常。而且我认为应用程序抛出异常的原因是计算机上缺少所需的库之一。 所以我正在寻找可以用来代替 WMI 的 API。

    最后我从 MSDN 中找到了 @987654321@ 和 @987654322@。

    我还发现了@987654323@ 结构。根据 MSDN,Attributes 字段表示打印机的属性,包括打印机是否共享。这可以检查Attributes 字段是否有PRINTER_ATTRIBUTE_SHARED 值。

    反正这个问题只能解决@987654324@、GetPrinter和SetPrinter。



    此图显示了调用“UnsharePrinter”方法之前和之后的情况。

    这是我取消共享共享打印机的方法。
    (可通过NetShareDel取消共享共享打印机,但无法通知系统打印机已取消共享。)

    Boolean UnsharePrinter(String printerName) {
        // fill PRINTER_DEFAULTS structure
        // and set DesiredAccess to PRINTER_ACCESS_ADMINISTER to 
        // get rights to call SetPrinter
        PRINTER_DEFAULTS pd;
        pd.pDatatype = IntPtr.Zero;
        pd.pDevMode = IntPtr.Zero;
        pd.DesiredAccess = PRINTER_ACCESS_ADMINISTER;
    
        IntPtr pDefaults = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PRINTER_DEFAULTS)));
        Marshal.StructureToPtr(pd, pDefaults, true);
    
        IntPtr hPrinter;
        // open the printer
        if ( !OpenPrinter(printerName, out hPrinter, pDefaults) ) {
            Marshal.FreeHGlobal(pDefaults);
            return false;
        }
    
        // first, call Zero pointer and 0 size to get minimum required space
        IntPtr pInfo = IntPtr.Zero;
        Int32 pcbNeeded;
        GetPrinter(hPrinter, 5, pInfo, 0, out pcbNeeded);
    
        // alloc reqiured space and call GetPrinter
        pInfo = Marshal.AllocHGlobal(pcbNeeded);
        if ( !GetPrinter(hPrinter, 5, pInfo, pcbNeeded, out pcbNeeded) ) {
            Marshal.FreeHGlobal(pInfo);
            ClosePrinter(hPrinter);
            return false;
        }
    
        // pointer to structure
        PRINTER_INFO_5 pi5 = (PRINTER_INFO_5) Marshal.PtrToStructure(pInfo, typeof(PRINTER_INFO_5));
        Marshal.FreeHGlobal(pInfo);
    
        // if printer is not shared, release the memory and exit
        if ( (pi5.Attributes & PRINTER_ATTRIBUTE_SHARED) == 0 ) {
            ClosePrinter(hPrinter);
            return false;
        }
    
        // remove the shared flag
        pi5.Attributes &= ~PRINTER_ATTRIBUTE_SHARED;
    
        // alloc pointer and make structure as pointer
        pInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(PRINTER_INFO_5)));
        Marshal.StructureToPtr(pi5, pInfo, true);
    
        // set printer
        Boolean r = SetPrinter(hPrinter, 5, pInfo, 0);
        Marshal.FreeHGlobal(pInfo);
        ClosePrinter(hPrinter);
    
        return r;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-27
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多