我正在通过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
在此图片中,您可以看到用户右侧的checkbox,表示打印机已共享。
但是在调用NetShareDel
去共享共享打印机并且成功之后,共享标记却消失了。
任何人都知道如何实现这个? 我在等你的帮助。 :d
对不起,我的英语不好。
你试过通过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(); }
我试过WMI,它可以在我的电脑上运行,但是其他电脑却会抛出异常。 我认为应用程序抛出异常的原因是计算机上缺少必需的库。 所以我正在寻找可以用来代替WMI的API。
最后,我从MSDN中找到了GetPrinter
和SetPrinter
。
而且我还发现了PRINTER_INFO_5
结构。 根据MSDN, Attributes
字段表示包括打印机在内的打印机的属性是否共享。 这可以检查Attributes
字段有PRINTER_ATTRIBUTE_SHARED
值。
无论如何,这个问题只能解决OpenPrinter
, 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; }