如何取消共享共享打印机?
How to un-share shared printer?
我正在通过 C# 开发 'Share Monitoring Application',它正在监视共享活动,我正在使用这些 API 来实现枚举共享 items/un-sharing 共享项目。
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
抱歉我的英语不好。
你试过通过 WMI 吗?
我自己还没有用它来 "unshare" 打印机,但我在应用程序中经常使用它以其他方式编辑打印机和打印机端口。
我认为这样的事情应该可以解决问题。
Win32_Printer class 看起来有一个 "shared" 属性,所以我建议尝试将其切换为 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上找到了<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd144911(v=vs.85).aspx" rel="nofollow noreferrer">GetPrinter</a>
and <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd145082(v=vs.85).aspx" rel="nofollow noreferrer">SetPrinter</a>
而且我还发现了<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd162848(v=vs.85).aspx" rel="nofollow noreferrer">PRINTER_INFO_5</a>
结构。根据 MSDN,Attributes
字段表示打印机的属性(包括打印机)是否共享。这可以检查 Attributes
字段有 PRINTER_ATTRIBUTE_SHARED
值。
反正这个问题只有<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd162751(v=vs.85).aspx" rel="nofollow noreferrer">OpenPrinter</a>
,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;
}
我正在通过 C# 开发 'Share Monitoring Application',它正在监视共享活动,我正在使用这些 API 来实现枚举共享 items/un-sharing 共享项目。
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
抱歉我的英语不好。
你试过通过 WMI 吗? 我自己还没有用它来 "unshare" 打印机,但我在应用程序中经常使用它以其他方式编辑打印机和打印机端口。 我认为这样的事情应该可以解决问题。
Win32_Printer class 看起来有一个 "shared" 属性,所以我建议尝试将其切换为 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上找到了<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd144911(v=vs.85).aspx" rel="nofollow noreferrer">GetPrinter</a>
and <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd145082(v=vs.85).aspx" rel="nofollow noreferrer">SetPrinter</a>
而且我还发现了<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd162848(v=vs.85).aspx" rel="nofollow noreferrer">PRINTER_INFO_5</a>
结构。根据 MSDN,Attributes
字段表示打印机的属性(包括打印机)是否共享。这可以检查 Attributes
字段有 PRINTER_ATTRIBUTE_SHARED
值。
反正这个问题只有<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd162751(v=vs.85).aspx" rel="nofollow noreferrer">OpenPrinter</a>
,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;
}