ååãšåæ§ã«ããã®èšäºã¯ããžã¥ãã¢ããã³ããã«ãããžã¡ã³ãã®éçºè ãšç¥ãåãã®ã«åœ¹ç«ã¡ãŸãã çŽ æãåŠç¿ããããã»ã¹ã§ã¯ã P / Invokeã䜿çšããŠCïŒã§äœã¬ãã«WinAPI DLLã«ã¢ã¯ã»ã¹ããæ¹æ³ãå°å·ã¢ãã¿ââãŒãããªã³ã¿ãŒãã©ã€ããŒãã·ã¹ãã ããå°å·ããã€ã¹ãã€ã³ã¹ããŒã«ãæ§æãåé€ããæ¹æ³ãããã€ã¹ããå ¥åããªãã€ã¬ã¯ãããããŒããéããŠãªã³ã¯ããæ¹æ³ãåŠç¿ããŸãã¢ãã¿ãŒã«å°å·ããŠã ããŒã·ã£ãªã³ã°ãé©çšããéèŠãªãã€ã³ããç解ããŸãã ãŸããAPIã䜿çšããŠã·ã¹ãã å ã®å°å·ããã€ã¹ã䟿å©ã«æäœããããã®APIã®äœ¿çšæ¹æ³ãããªã³ã¿ãŒããã®å°å·åŸã«åŠçãããããŒã¿ãã€ã³ã¿ãŒã»ããããæ¹æ³ãããã³ãããããµãŒããŒã«éä¿¡ããæ¹æ³ãææ¡ããŸãã
åé¡ã®å£°æ
æåã«ããã®èšäºã§è§£æ±ºããå¿ èŠãããã¿ã¹ã¯ã®ããããã®ãªã¹ãã®æŠèŠãææ¡ããŸãã 次ã®ããã«ããŸãã
- ã·ã¹ãã å ã®å°å·ããã€ã¹ã®å®å šãªã€ã³ã¹ããŒã«ãµã€ã¯ã«ãå¶åŸ¡ããæ©èœã
- ã·ã¹ãã ããå°å·ããã€ã¹ãåãå€ãå®å šãªãµã€ã¯ã«ã管çããæ©èœã
- å°å·ããã€ã¹ãæ§æããæ©èœã
- å¯èœã§ããã°ããããžã§ã¯ãã§ã®ã³ãŒãã®åå©çšãæé©åããAPIæ§é ãå¯èœãªéãæ©èœçãã€äŸ¿å©ã«ããŸãã
- APIã®ãã©ãŒã«ããã¬ã©ã³ã¹ãæ倧åããããšã¯å¯èœã§ãããåæã«äœã¬ãã«ã®Win32äŸå€ãžã®ã¢ã¯ã»ã¹ãç¶æããŸãã
- Windows XPããWindows 10ãŸã§ã®ã·ã¹ãã ãšã®äºææ§ã確ä¿ããŸãã
- APIã䜿çšããŠã³ãŒãå ã®å°å·ããŒã¿ãåŠçããæ©èœã
ãã®èšäºã®ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãã€ã¿ãªã¢ã®éçºè Lorenzo Montiã«ãã£ãŠæ¢ã«å®è£ ãããŠããmfilemon.dllå°å·ã¢ãã¿ââãŒã䜿çšããå ¬åŒã®Microsoft PostScriptããªã³ã¿ãŒãã©ã€ããŒãããªã³ã¿ãŒãã©ã€ããŒãšããŠäœ¿çšããŸã ã å®éãã¢ãã¿ãŒã®èŠä»¶ãšã¿ã¹ã¯ã«å¿ããŠãã¢ãã¿ãŒãšãã©ã€ããŒã¯ã©ãã§ãããŸããŸããã
çè«ã®ããã
ãã®èšäºã§ã¯ãããã¥ã¡ã³ããå°å·ããããã®çè«çåºç€ãPCL / PostScriptãµããŒãä»ãããªã³ã¿ãŒãšGDIããªã³ã¿ãŒããã³ãã®ä»ã®ããŒã¹ã®éãã«ã€ããŠã¯æ€èšããŸããã ãã®ãããã¯ã«é¢ããå¿ èŠãªæ å ±ã¯ãã¹ãŠããããã¯ãŒã¯ã®ãªãŒãã³ã¹ããŒã¹ã«è±å¯ã«ãããŸãã ããããç§ãã¡ã®ããã«èšå®ãããã¿ã¹ã¯ãã©ã®ããã«å®çŸããããããããç解ããã«ã¯ããŸã äœããç¥ãå¿ èŠããããŸãã
æãéèŠãªããšããå§ããŸããã-ã¹ããŒã©ãŒãµãŒãã¹ã¯ãWindowsã®å°å·ããã»ã¹ãå¶åŸ¡ããŸãã CïŒ/ Windows / System32 /ãã£ã¬ã¯ããªã«ã¯ç¬èªã®äœã¬ãã«ãã©ã€ãwinspool.drvããããŸããããã«ã¯ãå°å·ãµãŒãã¹ã®ã·ã¹ãã ãã£ã¬ã¯ããªãšã·ã¹ãã å ã®ããã©ã«ãããªã³ã¿ã®ååã®ååŸãããå°å·ãµãŒãã¹ã«ã¢ã¯ã»ã¹ããå€ãã®ã¢ã¯ã·ã§ã³ãå®è¡ããããã®å€ãã®ãšã³ããªãã€ã³ããå«ãŸããŠããŸãå°å·ãžã§ããã¥ãŒã䜿çšããæäœã winspool.hã«å ããŠãç¬èªã®ã¢ãã¿ãŒïŒãããããä»åŸã®èšäºã®ããããã§èª¬æããïŒãäœæããå Žåã¯ãDDKã®winsplp.hãå¿ èŠã§ããããã¯ãã¹ããŒã©ãŒä»æ§ã«åŸã£ãŠãã©ã€ããŒãæ§ç¯ããããã®è¿œå æ©èœãæäŸããŸãã ã
ããã«ãWindowsã®ãã«æ©èœã®å°å·ããã€ã¹ã¯ãç°¡åã«èšãã°ãã¢ãã¿ãŒããŒãã§éããŠããå°å·ã¢ãã¿ââãŒãå®éã®å°å·ããã€ã¹ïŒããªã³ã¿ãŒïŒãããã³ãã®ããã®ããªã€ã³ã¹ããŒã«ããããã©ã€ããŒã§æ§æãããŠããŸãïŒå³1ïŒã 1ã€ã®ã¢ãã¿ãŒã§è€æ°ã®ããŒããäžåºŠã«éãããšãã§ããè€æ°ã®ããªã³ã¿ãŒã1ã€ã®ããŒãã«äžåºŠã«æ¥ç¶ã§ããŸãã ããã¯ãã·ã¹ãã ããã³ã³ããŒãã³ããåé€ãããšãã«èæ ®ããå¿ èŠããããŸããããšãã°ãç¹å®ã®ããŒããåé€ããå Žåãæåã«ããã«æ¥ç¶ãããŠãããã¹ãŠã®å°å·ããã€ã¹ãç Žæ£ããå¿ èŠããããŸãã

P /åŒã³åºã
ãã©ãããã©ãŒã åŒã³åºããµãŒãã¹ïŒPInvokeïŒã¯ããããŒãžã³ãŒãïŒCïŒ/ VBããã³.NETïŒããã¢ã³ãããŒãžã³ãŒãïŒC / C ++ããã³WinAPIïŒã§èšè¿°ãããDLLãšã³ããªãã€ã³ãïŒé¢æ°ïŒã«ã¢ã¯ã»ã¹ããããã®ãã©ãããã©ãŒã ã§ãã .NETããäœã¬ãã«ã³ãŒãã«ã¢ã¯ã»ã¹ããã«ã¯ãDLLã®å€éšã¡ãœãããšããããã§äœ¿çšãããæ§é ãèšè¿°ããå¿ èŠããããŸãã åæãäŸããšã«é çªã«æ€èšããŸãã
äŸ1 winspool.drvãã©ã€ããŒããGetPrinterDriverDirectoryã¡ãœãããåŒã³åºããŸãã
ãŸããã¡ãœãããè¿ããã®ãšãåŒã³åºããããšãã«åŒæ°ã«äœãå¿ èŠããç¥ãå¿ èŠããããŸãã ãããè¡ãã«ã¯ã ããã¥ã¡ã³ãã«ç§»åããã¡ãœããã·ã°ããã£ã®èª¬æãèªã¿ãŸãã å°æ¥çã«ã¯ãäœã¬ãã«APIã®ããã¥ã¡ã³ããåžžã«åç §ããå¿ èŠãããããšã«æ³šæããŠãã ããããã以éãç¹å®ã®ã¡ãœãã/æ§é ãå®è£ ãããšãã«ãã®ã¢ã¯ã·ã§ã³ã®å¿ èŠæ§ã瀺ãããšã¯ãããŸããã ãããã¯ããã©ã«ãã§å¿ èŠã§ãã
BOOL GetPrinterDriverDirectory( _In_ LPTSTR pName, _In_ LPTSTR pEnvironment, _In_ DWORD Level, _Out_ LPBYTE pDriverDirectory, _In_ DWORD cbBuf, _Out_ LPDWORD pcbNeeded );
åé¢æ°ãã©ã¡ãŒã¿ã®èª¬æã¯ãããã¥ã¡ã³ãã«ãèšèŒãããŠããŸãã ãã©ã¡ãŒã¿ãŒã¯å ¥åã®ã¿ïŒInïŒãåºåã®ã¿ïŒOutïŒãå ¥åãšåºåã®äž¡æ¹ãåæã«ïŒIn / OutïŒããªãã·ã§ã³ïŒä»ã®ãã©ã¡ãŒã¿ãŒã«å¿ããŠå ¥åãŸãã¯åºåã®ããããïŒã«ã§ããããšãç解ããããšãéèŠã§ãã ãŸãã WDTåã«ãããã³ã°ããå¿ èŠããã.NETã®ããŒã¿åãç¥ãå¿ èŠããããŸãïŒããã§ã¯ãã»ãšãã©ã®å ŽåããéèŠãª.NETåã«å²ãåœãŠãããã¡ã¢ãªã®ãµã€ãºã¯ãåºæ¬çãªC ++åã«å²ãåœãŠãããã¡ã¢ãªã®ãµã€ãºã«å¯Ÿå¿ããæ®ãã¯IntPtrã«ãªããŸã ãïŒã
次ã«ãåãåã£ãæ å ±ã«åºã¥ããŠãCïŒã®ãããŒãžã³ãŒãã§ã¡ãœããã説æããŸãã
[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] extern bool GetPrinterDriverDirectory(string serverName, string environment, uint level, [Out] StringBuilder driverDirectory, uint bufferSize, ref uint bytesNeeded);
DllImportAttributeå±æ§ã䜿çšãããšãäœã¬ãã«ã®ãšã³ããªãã€ã³ãã«ã¢ã¯ã»ã¹ããããã®ãã©ã¡ãŒã¿ãŒãæå®ã§ããŸãã WinAPIã§ã¯ãã»ãšãã©ã®é¢æ°ã¯UnicodeãšANSIã®2ã€ã®äž»èŠãªãšã³ã³ãŒãã£ã³ã°ãèæ ®ããŠèšè¿°ãããŠããŸããé¢æ°ã®æ«å°Ÿã¯ããããWãšAã§ãã ãšã³ã³ãŒãã§ç¹å®ã®ã¡ãœãããåç §ããå¿ èŠããããã説æããã¡ãœããã®ã¡ã€ã³åããªãã¡ã¯ã¿ãªã³ã°ããããªãå Žåã¯ã察å¿ããå±æ§åŒæ°ïŒããšãã°ãGetPrinterDriverDirectoryWïŒã«æž¡ãããšã§ãšã³ããªãã€ã³ãã®ååãæ瀺çã«æå®ã§ããŸãã ãŸããåŒæ°CharSet = CharSet.Unicodeãæå®ããããšãå¿ããªãã§ãã ããïŒãã®å Žåããšã³ã³ãŒãã¯èªåçã«æ±ºå®ãããŸãïŒã ä»ã®ãã¹ãŠã®æçšãªå±æ§ã«ã€ããŠã¯ã å ¬åŒããã¥ã¡ã³ãã§æ å ±ãèŠã€ããããšãã§ããŸãã
ã»ãšãã©ã®å Žåã InAttributeå±æ§ã¯çç¥ã§ããŸãã CïŒã¡ãœããã®åŒæ°ã¯ãããã©ã«ãã§å€ã«ãã£ãŠæž¡ãããŸãã æž¡ãããåŒæ°ã®åãåç §ã§ããããããŒã¿ãåºåããå¿ èŠãããå Žåã«ã OutAttributeå±æ§ãæå®ããŸãã æå¹ãªåã®åŒæ°ã®åºåã«ã¯ã refãæå®ããŸãã åŒæ°ãåç §æž¡ãããŸãã
äŸ2 winspool.drvãã©ã€ããŒããAddMonitorã¡ãœãããåŒã³åºããŸãã
ãã®äŸã§ã¯ã MONITOR_INFO_2ããŒã¿æ§é ã䜿çšããŸããæåã«CïŒã³ãŒãã§èª¬æããå¿ èŠããããŸãã
typedef struct _MONITOR_INFO_2 { LPTSTR pName; LPTSTR pEnvironment; LPTSTR pDLLName; } MONITOR_INFO_2, *PMONITOR_INFO_2; BOOL AddMonitor( _In_ LPTSTR pName, _In_ DWORD Level, _In_ LPBYTE pMonitors );
ããã§ãããã©ãŒã¯ãèšèªã話ãæ§é ã¯ãå€ãæ ŒçŽããç¹å®ã®ãµã€ãºã®å²ãåœãŠãããã¡ã¢ãªã»ã¯ã·ã§ã³ã®ã»ããã§ããããšãç解ããããšãéèŠã§ãã ãããã®åã»ã¯ã·ã§ã³ã¯ãç¹å®ã®ã¿ã€ãã®ããŒã¿ãã£ãŒã«ããè¡šããŸãã ãã£ãŒã«ãåãšãã®å±æ§ãå¯å€åïŒã¯ã©ã¹ïŒã«åºæã®ã¡ã¿ããŒã¿ãããŒã¿ã¹ãã¬ãŒãžã«å²ãåœãŠãããã¡ã¢ãªã®ãµã€ãºã«ã€ããŠã¯èª¬æããŠããŸããã ããã¯ãæ§é äœã®ååã ãã§ãªããæ§é äœã®ååãä»»æã§ãããå²ãåœãŠãããã¡ã¢ãªãµã€ãºãšåã¡ã³ããŒã®å¯Ÿå¿ã芳å¯ããããšãéèŠã§ããããšãæå³ããŸãã ãã®ãããªç®çã®ããã«ãã¡ã¢ãªå ã®ã¯ã©ã¹ãŸãã¯æ§é ã®ããŒã¿ãã£ãŒã«ãã®ç©ççãªé 眮ãå¶åŸ¡ã§ããStructLayoutAttributeå±æ§ããããŸãã ã¡ã¢ãªå ã®ãããã®ãã£ãŒã«ãã®é 眮ãå¶åŸ¡ããæ¹æ³ã¯å€æ°ãããŸãããã£ãŒã«ãã®ãªãã»ãããæ瀺çã«èšå®ããæ§é ã®çµ¶å¯Ÿãµã€ãºãæå®ããããŒã·ã£ãªã³ã°æ¹æ³ã®ãšã³ã³ãŒãã£ã³ã°ãæå®ããããã±ãŒãžåãããã£ãŒã«ãã»ã°ã¡ã³ããé£ç¶ããé ã«é 眮ããããšãªã©ãã§ããŸãã ããã§ãããã®ã¡ãœããã®å®è£ ã®äŸãèŠã€ããããšãã§ããŸã ã å ·äœçã«ã¯ãLayoutKind.Sequentialã䜿çšããŠæå®ããæåŸã®ã¡ãœããã¯ãã¿ã¹ã¯ã«æé©ã§ãã
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] struct MonitorInfo { [MarshalAs(UnmanagedType.LPTStr)] public string Name; [MarshalAs(UnmanagedType.LPTStr)] public string Environment; [MarshalAs(UnmanagedType.LPTStr)] public string DllName; } [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] static extern bool AddMonitor(string serverName, uint level, ref MonitorInfo monitor);
ä»çµã¿ïŒæ§é äœã宣èšããå±æ§ã§LayoutKind.Sequentialã䜿çšããŠã¡ã¢ãªå ã®ãã£ãŒã«ãã®é 眮ãæå®ãããã£ãŒã«ãããŒã¿åãæå®ããŸãããWinAPIã®å Žåãæ§é äœã®ããŒã¿åã¯éèŠã§ããã€ãŸããã¢ã³ãããŒãžã³ãŒãã§ã¯sizeofïŒïŒã§ã ã管ç察象-Marshal.SizeOfïŒïŒã§ ã ããã ãã§ã
ããŒã·ã£ãªã³ã°
ãããŒã·ã£ãªã³ã°ãïŒå¥åãããŒã·ã£ãªã³ã°ããå¥åãããŒã·ã£ãªã³ã°ãïŒã®æŠå¿µã¯ãã¡ã¢ãªã«ä¿åãããããŒã¿ãããè¡šçŸããå¥ã®è¡šçŸã«å€æããããã»ã¹ã説æããŸãã äžè¬çãª.NETã®å Žåãç¹ã«P / Invokeã®å Žåãã¢ã³ãããŒãžã³ãŒãããCLRãžã®åå€æã§ãã ããŒã·ã£ãªã³ã°ã«ããããããŒãžã³ãŒãã§ã¡ã¢ãªãæäœãããããªããŸãã ãããã®ç®çã®ããã«ã2ã€ã®äž»èŠãªã¯ã©ã¹ã MarshalãšMarshalAsAttributeãæäŸãããŠããŸãã MarshalAsAttributeå±æ§ã䜿çšãããšãã¢ã³ãããŒãžã³ãŒããããããŒãžã³ãŒããžã®å€æã®åäžèŽãæ瀺çã«èšå®ã§ããŸã ïŒåã®ã·ãªã¢ã«åäžã®ãããã³ã°ãšåæ§ïŒã ããã¯ãã¿ã€ããã£ãŒã«ãã paramïŒãä»ããæå®ãæã€ã¡ãœãããã©ã¡ãŒã¿ãŒãããã³returnïŒãä»ããæ»ãå€ã«ã®ã¿é©çšã§ããŸãã Marshalã¯ã©ã¹ã«ã¯ããã€ã³ã¿ãŒã®æäœãã¡ã¢ãªã®å²ãåœãŠããµã€ãºå€æŽãã·ãããªã©ã®ããã®å€ãã®äŸ¿å©ãªéçã¡ãœãããå«ãŸããŠããŸãã ãŸãã FlagsAttributeå±æ§ã¯åœ¹ã«ç«ã¡ãŸããããã«ãããäœã¬ãã«ã®ããããã©ã°ããenumã®CïŒãžã®å€æãæ§æã§ããŸãã
å°æ¥ã®APIã¢ãŒããã¯ãã£
çè«ãæŽçãããããå°æ¥ã®APIã®ã¢ãŒããã¯ãã£ãæ€èšãããšããæ¥ãŸããã ç¹å®ã®å²åŠãæé©ãªå²åŠã¯ãããŸããã誰ãã解決ããåé¡ã®ç¶æ ã«å¿ããŠãã³ãŒãèšèšã®å¿ èŠãªãã¿ãŒã³ãéžæããŸãã ä»åã®ã±ãŒã¹ã§ã¯ã次ã®ããšãè¡ãããšã«ããŸãããå°æ¥ã®ã©ã€ãã©ãªã®ãã¹ãŠã®ã³ãŒãã¯ã2ã€ã®äž»èŠãªã¢ãžã¥ãŒã«ã§æ§æãããŸã-ã¯ã©ã¹ã®ããã¡ã¯ããªãŒããšãããã®ã¯ã©ã¹ãå®è£ ããã€ã³ã¿ãŒãã§ãŒã¹ã§ãã ãããªãã¯å®è£ ã«ãããã·ã¹ãã ã«ã€ã³ã¹ããŒã«ãããŠãããã¹ãŠã®ã³ã³ããŒãã³ãã®ãªã¹ãã®ååŸãã³ã³ããŒãã³ãã®ã€ã³ã¹ããŒã«/ã¢ã³ã€ã³ã¹ããŒã«ãªã©ãå¯èœã«ãªããŸãã å éšå®è£ ã¯ãããŒã·ã£ãªã³ã°ãšP / Invokeã§æ©èœããŸãã ç¹å®ã®ã±ãŒã¹ã«ã€ããŠã¯ãã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãäœæãããããã®ã¡ãœãããåŒã³åºãããšãã§ããŸããåºæ¬çãªã±ãŒã¹ã«ã€ããŠã¯ããå·¥å Žãã«é£çµ¡ããŸãã èŠèŠçã«ã¯ãããã¯ãã¹ãŠæ¬¡ã®ããã«è¡šãããšãã§ããŸãïŒå³2ïŒã

ãã®èšäºã®ãã¬ãŒã ã¯ãŒã¯å ã§åé¡ã解決ããã«ã¯ãIMonitorãIPortãIDriverãIPrinterã®å®è£ ãPrintingApiãã¡ã¯ããªã¯ã©ã¹èªäœãããã³è£å©ãã©ã°ãå¿ èŠã§ãã æ®ãã¯ä»ã®ãšããçç¥ãããŠããŸãã
ã³ãŒãããŒã¹
ãŸãããã¹ãŠã®å°å·ã³ã³ããŒãã³ãã®åºæ¬çãªã€ã³ã¿ãŒãã§ãŒã¹ãäœæããŸãããã
/// <summary> /// , ( , , ). /// </summary> public interface IPrintableDevice { /// <summary> /// . /// </summary> string Name { get; } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> void Install(string serverName); /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> void Uninstall(string serverName); }
ããã§ã¯ãã¹ãŠãåçŽã§ããåã³ã³ããŒãã³ãã«ã¯ãã·ã¹ãã ã«ã€ã³ã¹ããŒã«/ã¢ã³ã€ã³ã¹ããŒã«ããããã®ååãš2ã€ã®æ¹æ³ãããããªã¢ãŒããã·ã³ã§äœæ¥ããããšãã§ããŸãã
次ã«ãå·¥å Žã®åºç€ãèšè¿°ããŸãã
ã¯ã©ã¹PrintingApi
/// <summary> /// API . /// </summary> public class PrintingApi { /// <summary> /// P/Invoke. /// </summary> /// <param name="serverName"> .</param> /// <param name="level"> .</param> /// <param name="structs"> .</param> /// <param name="bufferSize"> .</param> /// <param name="bytesNeeded"> .</param> /// <param name="bufferReturnedLength"> .</param> /// <returns></returns> internal delegate bool EnumInfo(string serverName, uint level, IntPtr structs, uint bufferSize, ref uint bytesNeeded, ref uint bufferReturnedLength); /// <summary> /// P/Invoke. /// </summary> /// <param name="serverName"> .</param> /// <param name="environment">.</param> /// <param name="level"> .</param> /// <param name="structs"> .</param> /// <param name="bufferSize"> .</param> /// <param name="bytesNeeded"> .</param> /// <param name="bufferReturnedLength"> .</param> /// <returns></returns> internal delegate bool EnumInfo2(string serverName, string environment, uint level, IntPtr structs, uint bufferSize, ref uint bytesNeeded, ref uint bufferReturnedLength); /// <summary> /// <see cref="PrintingApi"/>. /// </summary> public static PrintingApi Factory { get; protected set; } /// <summary> /// <see cref="PrintingApi"/>. /// </summary> static PrintingApi() { Factory = new PrintingApi(); } /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="level"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo handler, string serverName, uint level) where T : struct { uint bytesNeeded = 0; uint bufferReturnedLength = 0; if (handler(serverName, level, IntPtr.Zero, 0, ref bytesNeeded, ref bufferReturnedLength)) return null; int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != PrintingException.ErrorInsufficientBuffer) throw new PrintingException(lastWin32Error); IntPtr pointer = Marshal.AllocHGlobal((int)bytesNeeded); try { if (handler(serverName, level, pointer, bytesNeeded, ref bytesNeeded, ref bufferReturnedLength)) { IntPtr currentPointer = pointer; T[] dataCollection = new T[bufferReturnedLength]; Type type = typeof(T); for (int i = 0; i < bufferReturnedLength; i++) { dataCollection[i] = (T)Marshal.PtrToStructure(currentPointer, type); currentPointer = (IntPtr)(currentPointer.ToInt64() + Marshal.SizeOf(type)); } return dataCollection; } throw new PrintingException(Marshal.GetLastWin32Error()); } catch (Exception e) { throw new PrintingException(e.Message, e); } finally { Marshal.FreeHGlobal(pointer); } } /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo handler, string serverName) where T : struct => GetInfo<T>(handler, serverName, 2); /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="level"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo handler, uint level) where T : struct => GetInfo<T>(handler, null, level); /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo handler) where T : struct => GetInfo<T>(handler, null); /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="arg"> .</param> /// <param name="level"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo2 handler, string serverName, string arg, uint level) where T : struct { uint bytesNeeded = 0; uint bufferReturnedLength = 0; if (handler(serverName, arg, level, IntPtr.Zero, 0, ref bytesNeeded, ref bufferReturnedLength)) return null; int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != PrintingException.ErrorInsufficientBuffer) throw new PrintingException(lastWin32Error); IntPtr pointer = Marshal.AllocHGlobal((int)bytesNeeded); try { if (handler(serverName, arg, level, pointer, bytesNeeded, ref bytesNeeded, ref bufferReturnedLength)) { IntPtr currentPointer = pointer; T[] dataCollection = new T[bufferReturnedLength]; Type type = typeof(T); for (int i = 0; i < bufferReturnedLength; i++) { dataCollection[i] = (T)Marshal.PtrToStructure(currentPointer, type); currentPointer = (IntPtr)(currentPointer.ToInt64() + Marshal.SizeOf(type)); } return dataCollection; } throw new PrintingException(Marshal.GetLastWin32Error()); } catch (Exception e) { throw new PrintingException(e.Message, e); } finally { Marshal.FreeHGlobal(pointer); } } /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="arg"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo2 handler, string serverName, string arg) where T : struct => GetInfo<T>(handler, serverName, arg, 2); /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="arg"> .</param> /// <param name="level"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo2 handler, string arg, uint level) where T : struct => GetInfo<T>(handler, null, arg, level); /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="arg"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo2 handler, string arg) where T : struct => GetInfo<T>(handler, null, arg); /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="level"> .</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo2 handler, uint level) where T : struct => GetInfo<T>(handler, null, level); /// <summary> /// Spooler API. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <returns> Spooler API.</returns> internal static T[] GetInfo<T>(EnumInfo2 handler) where T : struct => GetInfo<T>(handler, null); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, string serverName, uint level, out T[] dataCollection, out PrintingException e) where T : struct { dataCollection = null; e = null; try { dataCollection = GetInfo<T>(handler, serverName, level); return true; } catch (PrintingException ex) { e = ex; } return false; } /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, string serverName, uint level, out T[] dataCollection) where T : struct => TryGetInfo(handler, serverName, level, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, string serverName, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, serverName, 2, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, string serverName, out T[] dataCollection) where T : struct => TryGetInfo(handler, serverName, 2, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, uint level, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, null, level, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, uint level, out T[] dataCollection) where T : struct => TryGetInfo(handler, null, level, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, null, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo handler, out T[] dataCollection) where T : struct => TryGetInfo(handler, null, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="arg"> .</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string serverName, string arg, uint level, out T[] dataCollection, out PrintingException e) where T : struct { dataCollection = null; e = null; try { dataCollection = GetInfo<T>(handler, serverName, arg, level); return true; } catch (PrintingException ex) { e = ex; } return false; } /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="arg"> .</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string serverName, string arg, uint level, out T[] dataCollection) where T : struct => TryGetInfo(handler, serverName, arg, level, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="arg"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string serverName, string arg, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, serverName, arg, 2, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="serverName"> .</param> /// <param name="arg"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string serverName, string arg, out T[] dataCollection) where T : struct => TryGetInfo(handler, serverName, arg, 2, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="arg"> .</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string arg, uint level, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, null, arg, level, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="arg"> .</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string arg, uint level, out T[] dataCollection) where T : struct => TryGetInfo(handler, null, arg, level, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="arg"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string arg, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, null, arg, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="arg"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, string arg, out T[] dataCollection) where T : struct => TryGetInfo(handler, null, arg, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, uint level, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, null, level, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="level"> .</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, uint level, out T[] dataCollection) where T : struct => TryGetInfo(handler, null, level, out dataCollection, out PrintingException e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="dataCollection"> Spooler API.</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, out T[] dataCollection, out PrintingException e) where T : struct => TryGetInfo(handler, null, out dataCollection, out e); /// <summary> /// Spooler API True. P/Invoke. /// </summary> /// <typeparam name="T"> .</typeparam> /// <param name="handler">- Spooler API.</param> /// <param name="dataCollection"> Spooler API.</param> /// <returns>True, , False.</returns> internal static bool TryGetInfo<T>(EnumInfo2 handler, out T[] dataCollection) where T : struct => TryGetInfo(handler, null, out dataCollection, out PrintingException e); }
ææžåãããã³ã¡ã³ããããäœãäœã§ãããã¯æããã ãšæããŸããsingleton ã䜿çšããŠãéçã³ã³ã¹ãã©ã¯ã¿ãŒã§ã¯ã©ã¹ã®æ°ããéçã€ã³ã¹ã¿ã³ã¹ãäœæããEnumInfoããã³EnumInfo2ã® 2ã€ã®ããªã²ãŒããèšè¿°ããŠãå°æ¥ã®ã¯ã©ã¹ã§ããŒã¿ãåãåãããã®ãã€ãã£ãã¡ãœãããåŒã³åºãããã€ãã£ãã¡ãœããã§ãã«ããŒã¡ãœãããèšè¿°ããŸãã
ã»ãšãã©ã®å Žåããã€ãã£ãã¡ãœãããæäœããããã»ã¹å šäœã¯ã次ã®äžé£ã®ã¢ã¯ã·ã§ã³ã«åæžãããŸãã
- , false 122 (« »). () . , , , ;
- . Marshal.AllocHGlobal() , ( ) IntPtr ;
- . Marshal.PtrToStructure() , Marshal.StructureToPtr , ;
- Marshal.GetLastWin32ErrorïŒïŒã䜿çšããŠWin32ãšã©ãŒã®å¯èœæ§ãã€ã³ã¿ãŒã»ããããããšãå¿ããªãã§ãã ããããŸããMarshal.FreeHGlobalïŒïŒã䜿çšããŠãããã¡çšã«ä»¥åã«å²ãåœãŠãããã¡ã¢ãªã解æŸããŠãã ããã
char **ãããã¡ãŒïŒæååé åïŒãæäœããã«ã¯ãStringBuilderã䜿çšããããšããå§ãããŸãããã€ã³ã¿ãŒã§åäœããæ¢è£œã®ãªãŒããŒããŒãããããããŒã·ã£ãªã³ã°ã«å¿ èŠãªãã¹ãŠã®æ©èœãå®è£ ããŠããŸãã
äŸå€ããã£ããããŠã¹ããŒããããã«ãAPIã«å¥ã®ã¯ã©ã¹ãæäŸããŸãã
ã¯ã©ã¹PrintingException
/// <summary> /// . /// </summary> [Serializable] public class PrintingException : Win32Exception { #region Error Codes /// <summary> /// " ". /// </summary> public const int ErrorFileNotFound = 2; /// <summary> /// " ". /// </summary> public const int ErrorInsufficientBuffer = 122; /// <summary> /// " ". /// </summary> public const int ErrorModuleNotFound = 126; /// <summary> /// " ". /// </summary> public const int ErrorInvalidPrinterName = 1801; /// <summary> /// " ". /// </summary> public const int ErrorMonitorUnknown = 3000; /// <summary> /// " ". /// </summary> public const int ErrorPrinterDriverIsReadyUsed = 3001; /// <summary> /// " ". /// </summary> public const int ErrorPrinterJobFileNotFound = 3002; /// <summary> /// " StartDocPrinter". /// </summary> public const int ErrorStartDocPrinterNotCalling = 3003; /// <summary> /// " AddJob". /// </summary> public const int ErrorAddJobNotCalling = 3004; /// <summary> /// " ". /// </summary> public const int ErrorPrinterProcessorAlreadyInstalled = 3005; /// <summary> /// " ". /// </summary> public const int ErrorMonitorAlreadyInstalled = 3006; /// <summary> /// " ". /// </summary> public const int ErrorInvalidMonitor = 3007; /// <summary> /// " ". /// </summary> public const int ErrorMonitorIsReadyUsed = 3008; #endregion /// <summary> /// <see cref="PrintingException"/>. /// </summary> public PrintingException() : base() { } /// <summary> /// <see cref="PrintingException"/>. /// </summary> /// <param name="nativeErrorCode"> Win32.</param> public PrintingException(int nativeErrorCode) : base(nativeErrorCode) { } /// <summary> /// <see cref="PrintingException"/>. /// </summary> /// <param name="message"> .</param> public PrintingException(string message) : base(message) { } /// <summary> /// <see cref="PrintingException"/>. /// </summary> /// <param name="nativeErrorCode"> Win32.</param> /// <param name="message"> .</param> public PrintingException(int nativeErrorCode, string message) : base(nativeErrorCode, message) { } /// <summary> /// <see cref="PrintingException"/>. /// </summary> /// <param name="message"> .</param> /// <param name="innerException"></param> public PrintingException(string message, Exception innerException) : base(message, innerException) { } /// <summary> /// <see cref="PrintingException"/>. /// </summary> /// <param name="info"> .</param> /// <param name="context"> .</param> public PrintingException(SerializationInfo info, StreamingContext context) : base(info, context) { } }
ããã§ã¯ã䟿å®äžãå°å·ãµãŒãã¹ã䜿çšããéã®ãã€ãã£ããšã©ãŒã®åºæ¬ã³ãŒããããã«èŠå®ããŸããã
ããã§ãã³ãŒãããã䟿å©ã«äœ¿çšããç¡å¹ãªåŒæ°ã®ãã€ãã£ãã¡ãœãããžã®è»¢éãæå°éã«æããããã«ãããã€ãã®åæåãå®è£ ããå¿ èŠããããŸãã
/// <summary> /// . /// </summary> public enum Environment { /// <summary> /// . /// </summary> Current, /// <summary> /// Windows NT x86. /// </summary> X86, /// <summary> /// Windows x64. /// </summary> X64, /// <summary> /// Windows IA64. /// </summary> IA64, } /// <summary> /// . /// </summary> [Flags] public enum PortType { /// <summary> /// . /// </summary> Write = 0x1, /// <summary> /// . /// </summary> Read = 0x2, /// <summary> /// . /// </summary> Redirected = 0x4, /// <summary> /// . /// </summary> NetAttached = 0x8, } /// <summary> /// . /// </summary> public enum DataType : uint { RAW = 1, LPR = 2, }
ç°å¢ãæååã«ããŸãã¯ãã®éã«å€æããã«ã¯ã2ã€ã®æ¡åŒµã¡ãœãããå®è£ ããŸãã
/// <summary> /// . /// </summary> public static class PrintingExtensions { /// <summary> /// , WinAPI. /// </summary> /// <param name="environment"> .</param> /// <returns> .</returns> internal static string GetEnvironmentName(this Environment environment) { switch (environment) { default: return null; case Environment.X86: return "Windows x86"; case Environment.X64: return "Windows x64"; case Environment.IA64: return "Windows IA64"; } } /// <summary> /// <see cref="Environment"/>, . /// </summary> /// <param name="environmentString"> .</param> /// <returns><see cref="Environment"/>, .</returns> internal static Environment GetEnvironment(this string environmentString) { environmentString = environmentString.ToLower(); if (environmentString.Contains("x86")) return Environment.X86; if (environmentString.Contains("x64")) return Environment.X64; if (environmentString.Contains("ia64")) return Environment.IA64; return Environment.Current; } }
2ã€ã®æ¡åŒµã¡ãœãããšenum Environmentã®ä»£ããã«ãéåžžã®æååå®æ°ã§ããŸãããããšãã§ããŸããæåã«ç°å¢ã®ååã§ç¡å¹ãªã®ã£ã°ãæž¡ãããšãçŠæ¢ãããã£ãã ãã§ããã®æ¹æ³ã§è¡ããŸããããåæã«ãäºåå®çŸ©ãããå¶éãããè¡ã»ããããéžæããæ©èœãä¿æããŸãã
åã¯ã©ã¹ã®ã³ã³ããŒãã³ããã€ã³ã¹ããŒã«ããã³åé€ããããã®ãªãŒããŒããŒãã¡ãœãããèšè¿°ããªãããã«ãåºæ¬çãªæœè±¡ã¯ã©ã¹ãå®è£ ããŸãã
æœè±¡ã¯ã©ã¹PrintableDevice
/// <summary> /// . /// </summary> public abstract class PrintableDevice : IPrintableDevice { /// <summary> /// . /// </summary> public virtual string Name { get; protected set; } /// <summary> /// <see cref="PrintableDevice"/>. /// </summary> /// <param name="name"></param> /// <exception cref="ArgumentNullException"/> public PrintableDevice(string name) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name"); Name = name; } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <exception cref="FileNotFoundException" /> /// <exception cref="PrintingException" /> public abstract void Install(string serverName); /// <summary> /// . /// </summary> /// <exception cref="FileNotFoundException" /> /// <exception cref="PrintingException" /> public void Install() => Install(null); /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> public bool TryInstall(string serverName, out PrintingException e) { e = null; try { Install(serverName); } catch (PrintingException ex) { e = ex; return false; } return true; } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <returns>True, , False.</returns> public bool TryInstall(string serverName) => TryInstall(serverName, out PrintingException e); /// <summary> /// . /// </summary> /// <param name="e">, .</param> /// <returns>True, , False.</returns> public bool TryInstall(out PrintingException e) => TryInstall(null, out e); /// <summary> /// . /// </summary> /// <returns>True, , False.</returns> public bool TryInstall() => TryInstall(out PrintingException e); /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <exception cref="PrintingException" /> public abstract void Uninstall(string serverName); /// <summary> /// . /// </summary> /// <exception cref="PrintingException" /> public void Uninstall() => Uninstall(null); /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <param name="e">, .</param> /// <returns>True, , False.</returns> public bool TryUninstall(string serverName, out PrintingException e) { e = null; try { Uninstall(serverName); } catch (PrintingException ex) { e = ex; return false; } return true; } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <returns>True, , False.</returns> public bool TryUninstall(string serverName) => TryUninstall(serverName, out PrintingException e); /// <summary> /// . /// </summary> /// <param name="e">, .</param> /// <returns>True, , False.</returns> public bool TryUninstall(out PrintingException e) => TryUninstall(null, out e); /// <summary> /// . /// </summary> /// <returns>True, , False.</returns> public bool TryUninstall() => TryUninstall(out PrintingException e); }
ããªã³ãã¢ãã¿ãŒ
å°å·ã¢ãã¿ââã®å®è£ ãéå§ããŸãããŸããçè«çãªéšåã§ãã§ã«èª¬æãããã€ãã£ãæ§é ãå¿ èŠã§ãã
struct MonitorInfo
/// <summary> /// . /// </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct MonitorInfo { /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string Name; /// <summary> /// , (, Windows NT x86, Windows IA64 Windows x64). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string Environment; /// <summary> /// *.dll . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string DllName; }
次ã«ãå°å·ã¢ãã¿ââãŒãå®è£ ããããã®ã€ã³ã¿ãŒãã§ãŒã¹ãå¿ èŠã§ãã
ã€ã³ã¿ãŒãã§ãŒã¹IMonitor
/// <summary> /// . /// </summary> public interface IMonitor : IPrintableDevice { /// <summary> /// , (, Windows NT x86, Windows IA64 Windows x64). /// </summary> Environment Environment { get; } /// <summary> /// *.dll . /// </summary> string Dll { get; } }
ä»ã®ãšããããã§ååã§ããå°æ¥ãããªã¢ãŒãã£ãºã ã«éåããããšãªãæ©èœãæ¡åŒµããå¿ èŠãããå Žåãã€ã³ã¿ãŒãã§ã€ã¹ã®ãããã§ããã®ã¿ã¹ã¯ãç°¡åã«å®è£ ã§ããŸãã
ãŸããèšäºã®çè«ãããã¯ã§ã·ã¹ãã ã«ã¢ãã¿ãŒãè¿œå ãããã€ãã£ãã¡ãœããã«ã€ããŠã説æããŸããããã€ã³ã¹ããŒã«ãããã¢ãã¿ãŒã®ãªã¹ããååŸããã¢ãã¿ãŒãåé€ããŠãã¢ãã¿ãŒã®ã¯ã©ã¹ãå®è£ ããæ¹æ³ã«ã€ããŠèª¬æããŸãã
ã¯ã©ã¹ã¢ãã¿ãŒ
/// <summary> /// . /// </summary> public class Monitor : PrintableDevice, IMonitor { /// <summary> /// , (, Windows NT x86, Windows IA64 Windows x64). /// </summary> public virtual Environment Environment { get; protected set; } /// <summary> /// *.dll . /// </summary> public virtual string Dll { get; protected set; } /// <summary> /// . /// </summary> public static Monitor[] All { get { if (!PrintingApi.TryGetInfo(EnumMonitors, out MonitorInfo[] monitorInfo)) return null; Monitor[] monitors = new Monitor[monitorInfo.Length]; for (int i = 0; i < monitorInfo.Length; i++) monitors[i] = new Monitor(monitorInfo[i].Name, monitorInfo[i].DllName, monitorInfo[i].Environment.GetEnvironment()); return monitors; } } /// <summary> /// <see cref="Monitor"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> *.dll .</param> /// <param name="environment">, (, Windows NT x86, Windows IA64 Windows x64).</param> /// <exception cref="ArgumentNullException" /> public Monitor(string name, string dll, Environment environment) : base(name) { if (string.IsNullOrEmpty(dll)) throw new ArgumentNullException("dll"); Environment = environment; Dll = dll; } /// <summary> /// <see cref="Monitor"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> *.dll .</param> /// <exception cref="ArgumentNullException" /> public Monitor(string name, string dll) : this(name, dll, Environment.Current) { } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <exception cref="FileNotFoundException"/> /// <exception cref="PrintingException"/> public override void Install(string serverName) { try { if (!File.Exists(Dll)) throw new FileNotFoundException(" ", Dll); string dllName = Path.GetFileName(Dll); string dllPath = Path.Combine(System.Environment.SystemDirectory, dllName); File.Copy(Dll, dllPath, true); MonitorInfo monitorInfo = new MonitorInfo { Name = Name, Environment = Environment.GetEnvironmentName(), DllName = File.Exists(dllPath) ? dllName : Dll, }; if (AddMonitor(serverName, 2, ref monitorInfo)) return; if (Marshal.GetLastWin32Error() == PrintingException.ErrorMonitorAlreadyInstalled && TryUninstall(serverName) && AddMonitor(serverName, 2, ref monitorInfo)) return; else throw new PrintingException(Marshal.GetLastWin32Error()); } catch (Exception e) { throw new PrintingException(e.Message, e); } } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <exception cref="PrintingException"/> public override void Uninstall(string serverName) { try { if (!All.Select(m => m.Name).Contains(Name)) return; /// TODO: . if (DeleteMonitor(serverName, Environment.GetEnvironmentName(), Name)) return; if (Marshal.GetLastWin32Error() == PrintingException.ErrorMonitorUnknown) return; if (DeleteMonitor(serverName, Environment.GetEnvironmentName(), Name)) return; throw new PrintingException(Marshal.GetLastWin32Error()); } catch (Exception e) { throw new PrintingException(e.Message, e); } } #region Native /// <summary> /// . /// </summary> /// <param name="serverName"> , . null - .</param> /// <param name="level"> . 2.</param> /// <param name="monitor"> <see cref="MonitorInfo"/>.</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool AddMonitor(string serverName, uint level, ref MonitorInfo monitor); /// <summary> /// <see cref="MonitorInfo"/>. /// </summary> /// <param name="serverName"> , . null - .</param> /// <param name="level"> . 1 2.</param> /// <param name="monitors"> <see cref="MonitorInfo"/>.</param> /// <param name="bufferSize"> <see cref="MonitorInfo"/> ( ).</param> /// <param name="bytesNeeded"> .</param> /// <param name="bufferReturnedLength"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool EnumMonitors(string serverName, uint level, IntPtr monitors, uint bufferSize, ref uint bytesNeeded, ref uint bufferReturnedLength); /// <summary> /// . /// </summary> /// <param name="serverName"> , . null - .</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="monitorName"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool DeleteMonitor(string serverName, string environment, string monitorName); #endregion }
ããã§ãåãã¯ã©ã¹ã®å°å·ã¢ãã¿ââãŒãæäœããããã«å¿ èŠãªæ©èœããã¹ãŠæããŸããããã¡ã¯ããªã«ã¢ãã¿ãŒã€ã³ã¹ã¿ã³ã¹ãäœæããã¡ãœãããè¿œå ããŸãã
PrintingApiã¯ã©ã¹ã®æ©èœãæ¡åŒµãã
/// <summary> /// . /// </summary> public static Monitor[] Monitors => Monitor.All; /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> dll .</param> /// <param name="environment">, .</param> /// <param name="serverName"> , .</param> /// <returns> .</returns> public Monitor CreateMonitor(string name, string dll, Environment environment, string serverName) { Monitor monitor = new Monitor(name, dll, environment); monitor.TryInstall(serverName); return monitor; } /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> dll .</param> /// <param name="environment">, .</param> /// <returns> .</returns> public Monitor CreateMonitor(string name, string dll, Environment environment) => CreateMonitor(name, dll, environment, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> dll .</param> /// <param name="serverName"> , .</param> /// <returns> .</returns> public Monitor CreateMonitor(string name, string dll, string serverName) => CreateMonitor(name, dll, Environment.Current, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> dll .</param> /// <returns> .</returns> public Monitor CreateMonitor(string name, string dll) => CreateMonitor(name, dll, null);
ã³ãŒãã®æäœæ§ãæ€èšŒããŸãããŠããããã¹ããè¿œå ãã䟿å®äžãã¢ãã¿ãŒDLLã®ååãšãã¹å®æ°ãèŠå®ããã¡ã€ã³ã³ãŒãã»ã°ã¡ã³ããã«ããŒãããã¹ãã¡ãœãããå®è£ ããŸãã
å°å·ã¢ãã¿ââãŒã®åäœãã¹ã
/// <summary> /// <see cref="Monitor"/>. /// </summary> [TestClass] public class MonitorTests { /// <summary> /// . /// </summary> protected const string MonitorName = "Test Monitor"; /// <summary> /// dll . /// </summary> protected const string MonitorDll = "D:/Printing Tests/mfilemon.dll"; /// <summary> /// dll . /// </summary> protected const string FailedMonitorDll = "noexist.dll"; /// <summary> /// . /// </summary> [TestMethod] public void InstallTest() { Monitor monitor = new Monitor(MonitorName, MonitorDll); monitor.Install(); Assert.IsTrue(Monitor.All.Select(m => m.Name).Contains(MonitorName)); } /// <summary> /// . /// </summary> [TestMethod] public void UninstallTest() { Monitor monitor = new Monitor(MonitorName, MonitorDll); monitor.Uninstall(); Assert.IsFalse(Monitor.All.Select(m => m.Name).Contains(MonitorName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryInstallTest() { Monitor monitor = new Monitor(MonitorName, MonitorDll); bool f = monitor.TryInstall(); Assert.IsTrue(f); Assert.IsTrue(Monitor.All.Select(m => m.Name).Contains(MonitorName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryUninstallTest() { Monitor monitor = new Monitor(MonitorName, MonitorDll); bool f = monitor.TryUninstall(); Assert.IsTrue(f); Assert.IsFalse(Monitor.All.Select(m => m.Name).Contains(MonitorName)); } /// <summary> /// . /// </summary> [TestMethod] [ExpectedException(typeof(PrintingException))] public void InstallFailedTest() { Monitor monitor = new Monitor(MonitorName, FailedMonitorDll); monitor.Install(); Assert.IsFalse(Monitor.All.Select(m => m.Name).Contains(MonitorName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryInstallFailedTest() { Monitor monitor = new Monitor(MonitorName, FailedMonitorDll); bool f = monitor.TryInstall(); Assert.IsFalse(f); Assert.IsFalse(Monitor.All.Select(m => m.Name).Contains(MonitorName)); }
ããªã³ãã¢ãã¿ãŒããã¹ããã£ã¬ã¯ããªmfilemon.dllã«ããããããããšãå¿ããªãã§ãã ããã
枯
ããŒãã«ã€ããŠãåãããšãè¡ããŸãããŸããIPortãå¿ èŠã§ãã
ã€ã³ã¿ãŒãã§ã€ã¹iport
/// <summary> /// . /// </summary> public interface IPort : IPrintableDevice { /// <summary> /// , . /// </summary> IMonitor Monitor { get; } /// <summary> /// . /// </summary> string Description { get; } /// <summary> /// . /// </summary> PortType Type { get; } }
次ã«ããã€ãã£ãããŒãã®ããŒã¿æ§é ã«ã€ããŠèª¬æããŸãã
struct portInfo
/// <summary> /// . /// </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PortInfo { /// <summary> /// (, "LPT1:"). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string PortName; /// <summary> /// (, "PJL monitor"). null. /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string MonitorName; /// <summary> /// (, <see cref="PortName"/> "LPT1:", <see cref="Description"/> "printer port"). null. /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string Description; /// <summary> /// . /// </summary> public PortType Type; /// <summary> /// . 0. /// </summary> internal uint Reserved; }
ã¹ããŒã©ãŒã¯ãããŒããééãã2ã€ã®æ¹æ³ãæäŸããŸãã1ã€ç®ã¯åºæ¬çãªAddPort / DeletePortã¡ãœããã䜿çšããæ¹æ³ã2ã€ç®ã¯XcvDataããŒã«ãšãã®äžã®ããŸããŸãªãã«ããŒã䜿çšããæ¹æ³ã§ãã2çªç®ã®ãªãã·ã§ã³ãæãŸããã®ã¯ãæåã®ã±ãŒã¹ã§ã¯ãã€ã³ã¹ããŒã«ããã»ã¹ã®ãã€ã¢ãã°ããã¯ã¹ãžã®ãã€ã³ã¿ãå¿ èŠã§ãããããã¯å¿ èŠãããŸãããXCVã«ã¯ãããã«æ¬¡ã®ãã®ãå¿ èŠã§ãã
åæåPrinterAccess-ããªã³ã¿ãŒããŒã¿ãžã®ã¢ã¯ã»ã¹æš©
/// <summary> /// . /// </summary> internal enum PrinterAccess { /// <summary> /// . /// </summary> ServerAdmin = 0x01, /// <summary> /// . /// </summary> ServerEnum = 0x02, /// <summary> /// . /// </summary> PrinterAdmin = 0x04, /// <summary> /// . /// </summary> PrinterUse = 0x08, /// <summary> /// . /// </summary> JobAdmin = 0x10, /// <summary> /// . /// </summary> JobRead = 0x20, /// <summary> /// . /// </summary> StandardRightsRequired = 0x000F0000, /// <summary> /// . /// </summary> PrinterAllAccess = (StandardRightsRequired | PrinterAdmin | PrinterUse), }
struct PrinterDefaults-XcvDataã®ããªã³ã¿ãŒèšå®
/// <summary> /// <see cref="Port.XcvData(IntPtr, string, IntPtr, uint, IntPtr, uint, out uint, out uint)"/>. /// </summary> [StructLayout(LayoutKind.Sequential)] internal struct PrinterDefaults { /// <summary> /// ( null). /// </summary> public IntPtr DataType; /// <summary> /// ( null). /// </summary> public IntPtr DevMode; /// <summary> /// . /// </summary> public PrinterAccess DesiredAccess; }
struct PortData-XcvDataã®ããŒãããŒã¿æ§é
/// <summary> /// <see cref="Port.XcvData(System.IntPtr, string, System.IntPtr, uint, System.IntPtr, uint, out uint, out uint)"/>. /// </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] internal struct PortData { /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string PortName; /// <summary> /// ( 1). /// </summary> public uint Version; /// <summary> /// . /// </summary> public DataType Protocol; /// <summary> /// . /// </summary> public uint BufferSize; /// <summary> /// . /// </summary> public uint ReservedSize; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 49)] public string HostAddress; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string SNMPCommunity; public uint DoubleSpool; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 33)] public string Queue; /// <summary> /// IP-. /// </summary> [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)] public string IPAddress; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.ByValArray, SizeConst = 540)] public byte[] Reserved; /// <summary> /// . /// </summary> public uint PortNumber; public uint SNMPEnabled; public uint SNMPDevIndex; }
åæåXcvDataType-XcvDataã®æäœã¿ã€ã
/// <summary> /// <see cref="Port.XcvData(IntPtr, string, IntPtr, uint, IntPtr, uint, out uint, out uint)"/>. /// </summary> internal enum XcvDataType { /// <summary> /// . /// </summary> AddPort, /// <summary> /// . /// </summary> DeletePort, }
ããŠãããã§ããŒãã¯ã©ã¹ãå®è£ ããããã«å¿ èŠãªãã®ããã¹ãŠæããŸããã
ã¯ã©ã¹ããŒã
/// <summary> /// . /// </summary> public class Port : PrintableDevice, IPort { /// <summary> /// , . /// </summary> public virtual IMonitor Monitor { get; protected set; } /// <summary> /// . /// </summary> public virtual string Description { get; protected set; } /// <summary> /// . /// </summary> public virtual PortType Type { get; protected set; } /// <summary> /// . /// </summary> public static Port[] All { get { if (!PrintingApi.TryGetInfo(EnumPorts, out PortInfo[] portInfo)) return null; Port[] ports = new Port[portInfo.Length]; for (int i = 0; i < portInfo.Length; i++) ports[i] = new Port(portInfo[i].PortName, portInfo[i].Description, portInfo[i].Type, portInfo[i].MonitorName); return ports; } } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="type"> .</param> /// <param name="monitorName"> , .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, string description, PortType type, string monitorName) : base(name) { Description = description; Type = type; Monitor[] monitors = PrintingApi.Monitors; if (monitors.Select(m => m.Name).Contains(monitorName)) Monitor = monitors.Where(m => m.Name == monitorName).FirstOrDefault(); } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="type"> .</param> /// <param name="monitor"> , .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, string description, PortType type, IMonitor monitor) : this(name, description, type, monitor?.Name) { } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="type"> .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, string description, PortType type) : this(name, description, type, null as string) { } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="monitorName"> , .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, string description, string monitorName) : this(name, description, PortType.Redirected, monitorName) { } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="monitor"> , .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, string description, IMonitor monitor) : this(name, description, PortType.Redirected, monitor) { } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, string description) : this(name, description, null as string) { } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="monitor"> , .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, IMonitor monitor) : this(name, null, monitor) { } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <param name="type"> .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name, PortType type) : this(name, null, type) { } /// <summary> /// <see cref="Port"/>. /// </summary> /// <param name="name"> .</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="PrintingException"/> public Port(string name) : this(name, null as string) { } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <exception cref="FileNotFoundException"/> /// <exception cref="PrintingException"/> public override void Install(string serverName) { try { if (All.Select(p => p.Name).Contains(Name)) Uninstall(serverName); PrinterDefaults defaults = new PrinterDefaults { DesiredAccess = PrinterAccess.ServerAdmin }; if (!OpenPrinter($",XcvMonitor {Monitor.Name}", out IntPtr printerHandle, ref defaults)) throw new PrintingException(Marshal.GetLastWin32Error()); PortData portData = new PortData { Version = 1, Protocol = DataType.RAW, PortNumber = 9100, // 9100 = RAW, 515 = LPR. ReservedSize = 0, PortName = Name, IPAddress = serverName, SNMPCommunity = "public", SNMPEnabled = 1, SNMPDevIndex = 1, }; uint size = (uint)Marshal.SizeOf(portData); portData.BufferSize = size; IntPtr pointer = Marshal.AllocHGlobal((int)size); Marshal.StructureToPtr(portData, pointer, true); try { IntPtr outputData = IntPtr.Zero; uint outputDataSize = 0; if (!XcvData(printerHandle, Enum.GetName(typeof(XcvDataType), XcvDataType.AddPort), pointer, size, outputData, outputDataSize, out uint outputNeeded, out uint status)) throw new PrintingException(Marshal.GetLastWin32Error()); } catch (Exception e) { throw new PrintingException(e.Message, e); } finally { Marshal.FreeHGlobal(pointer); ClosePrinter(printerHandle); } } catch (Exception e) { throw new PrintingException(e.Message, e); } } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <exception cref="FileNotFoundException"/> /// <exception cref="PrintingException"/> public override void Uninstall(string serverName) { try { if (!All.Select(p => p.Name).Contains(Name)) return; /// TODO: , . PrinterDefaults defaults = new PrinterDefaults { DesiredAccess = PrinterAccess.ServerAdmin }; if (!OpenPrinter($",XcvPort {Name}", out IntPtr printerHandle, ref defaults)) throw new PrintingException(Marshal.GetLastWin32Error()); PortData portData = new PortData { Version = 1, Protocol = DataType.RAW, PortNumber = 9100, ReservedSize = 0, PortName = Name, IPAddress = serverName, SNMPCommunity = "public", SNMPEnabled = 1, SNMPDevIndex = 1, }; uint size = (uint)Marshal.SizeOf(portData); portData.BufferSize = size; IntPtr pointer = Marshal.AllocHGlobal((int)size); Marshal.StructureToPtr(portData, pointer, true); try { IntPtr outputData = IntPtr.Zero; uint outputDataSize = 0; if (!XcvData(printerHandle, Enum.GetName(typeof(XcvDataType), XcvDataType.DeletePort), pointer, size, outputData, outputDataSize, out uint outputNeeded, out uint status)) throw new PrintingException(Marshal.GetLastWin32Error()); } catch (Exception e) { throw new PrintingException(e.Message, e); } finally { Marshal.FreeHGlobal(pointer); ClosePrinter(printerHandle); } } catch (Exception e) { throw new PrintingException(e.Message, e); } } #region Native /// <summary> /// . /// </summary> /// <param name="printerName"> .</param> /// <param name="printer"> .</param> /// <param name="printerDefaults"> <see cref="XcvData(IntPtr, string, IntPtr, uint, IntPtr, uint, out uint, out uint)"/>.</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool OpenPrinter(string printerName, out IntPtr printer, ref PrinterDefaults printerDefaults); /// <summary> /// . /// </summary> /// <param name="printer"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool ClosePrinter(IntPtr printer); /// <summary> /// . /// </summary> /// <param name="printer"> .</param> /// <param name="dataType"> .</param> /// <param name="inputData"> .</param> /// <param name="inputDataSize"> .</param> /// <param name="outputData"> .</param> /// <param name="outputDataSize"> .</param> /// <param name="outputNeeded"> .</param> /// <param name="status"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool XcvData(IntPtr printer, string dataType, IntPtr inputData, uint inputDataSize, IntPtr outputData, uint outputDataSize, out uint outputNeeded, out uint status); /// <summary> /// <see cref="PortInfo"/>. /// </summary> /// <param name="serverName"> , . null - .</param> /// <param name="level"> . 1 2.</param> /// <param name="ports"> <see cref="PortInfo"/>.</param> /// <param name="bufferSize"> <see cref="PortInfo"/> ( ).</param> /// <param name="bytesNeeded"> .</param> /// <param name="bufferReturnedLength"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool EnumPorts(string serverName, uint level, IntPtr ports, uint bufferSize, ref uint bytesNeeded, ref uint bufferReturnedLength); #endregion }
次ã«ãããŒããæäœããããã®æ©èœãå°å ¥ããŠãPrintingApiãæ¡åŒµããŸãã
PrintingApiãžã®ããŒãã¡ãœããã®è¿œå
/// <summary> /// . /// </summary> public static Port[] Ports => Port.All; /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="type"> .</param> /// <param name="monitor"> , .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Port OpenPort(string name, string description, PortType type, Monitor monitor, string serverName) { Port port = new Port(name, description, type, monitor); monitor.TryInstall(serverName); return port; } /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="type"> .</param> /// <param name="monitor"> , .</param> /// <returns> .</returns> public Port OpenPort(string name, string description, PortType type, Monitor monitor) => OpenPort(name, description, type, monitor, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="type"> .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Port OpenPort(string name, string description, PortType type, string serverName) => OpenPort(name, description, type, null, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="type"> .</param> /// <returns> .</returns> public Port OpenPort(string name, string description, PortType type) => OpenPort(name, description, type, null as string); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="monitor"> , .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Port OpenPort(string name, string description, Monitor monitor, string serverName) => OpenPort(name, description, PortType.Redirected, monitor, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="monitor"> , .</param> /// <returns> .</returns> public Port OpenPort(string name, string description, Monitor monitor) => OpenPort(name, description, monitor, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="monitor"> , .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Port OpenPort(string name, Monitor monitor, string serverName) => OpenPort(name, null, monitor, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="monitor"> , .</param> /// <returns> .</returns> public Port OpenPort(string name, Monitor monitor) => OpenPort(name, monitor, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="type"> .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Port OpenPort(string name, PortType type, string serverName) => OpenPort(name, null, type, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="type"> .</param> /// <returns> .</returns> public Port OpenPort(string name, PortType type) => OpenPort(name, type, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Port OpenPort(string name, string description, string serverName) => OpenPort(name, description, null, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="description"> .</param> /// <returns> .</returns> public Port OpenPort(string name, string description) => OpenPort(name, description, null as string); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <returns> .</returns> public Port OpenPort(string name) => OpenPort(name, null as string);
ãŸããTODOã®ä»£ããã«ã¢ãã¿ãŒã®åé€ã¡ãœããã«ãã§ãã¯ãè¿œå ããããšãå¿ããªãã§ãã ããïŒ
IEnumerable<Port> openPorts = Port.All.Where(p => p.Monitor?.Name == Name); foreach (Port openPort in openPorts) openPort.Uninstall(serverName);
ããã§ãã³ãŒããæ©èœããŠããããšã確èªãã次ã®ã¹ãããã«é²ãããšãã§ããŸãã
å°å·ããŒããæäœããããã®åäœãã¹ã
/// <summary> /// <see cref="Port"/>. /// </summary> [TestClass] public class PortTests { /// <summary> /// . /// </summary> protected const string PortName = "TESTPORT:"; /// <summary> /// . /// </summary> protected const string PortDescription = "Description for " + PortName; /// <summary> /// . /// </summary> protected const string MonitorName = "mfilemon"; /// <summary> /// . /// </summary> protected const string FailedMonitorName = "noexist"; /// <summary> /// . /// </summary> [TestMethod] public void InstallTest() { Port port = new Port(PortName, PortDescription, MonitorName); port.Install(); Assert.IsTrue(Port.All.Select(p => p.Name).Contains(PortName)); } /// <summary> /// . /// </summary> [TestMethod] public void UninstallTest() { Port port = new Port(PortName, PortDescription, MonitorName); port.Uninstall(); Assert.IsFalse(Port.All.Select(p => p.Name).Contains(PortName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryInstallTest() { Port port = new Port(PortName, PortDescription, MonitorName); bool f = port.TryInstall(); Assert.IsTrue(f); Assert.IsTrue(Port.All.Select(p => p.Name).Contains(PortName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryUninstallTest() { Port port = new Port(PortName, PortDescription, MonitorName); bool f = port.TryUninstall(); Assert.IsTrue(f); Assert.IsFalse(Port.All.Select(p => p.Name).Contains(PortName)); } /// <summary> /// . /// </summary> [TestMethod] [ExpectedException(typeof(PrintingException))] public void InstallFailedTest() { Port port = new Port(PortName, PortDescription, MonitorName); port.Install(); Assert.IsFalse(Port.All.Select(p => p.Name).Contains(PortName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryInstallFailedTest() { Port port = new Port(PortName, PortDescription, FailedMonitorName); bool f = port.TryUninstall(); Assert.IsTrue(f); Assert.IsFalse(Port.All.Select(p => p.Name).Contains(PortName)); } }
ããªã³ã¿ãŒãã©ã€ããŒ
ãã©ã€ããŒã®å Žåããã¹ãŠã¯ã¢ãã¿ãŒã®å ŽåãšãŸã£ããåãã§ããæåã«ããã€ãã£ãããŒã¿æ§é ã次ã«ã€ã³ã¿ãŒãã§ã€ã¹ãã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£ ãAPIæ©èœã®æ¡åŒµããã¹ãã説æããŸããæåã«ãã©ã€ããŒãã¡ã€ã«ããã¹ããã£ã¬ã¯ããªã«ããããããããšãå¿ããªãã§ãã ããã
struct DriverInfo
/// <summary> /// . /// </summary> [StructLayout(LayoutKind.Sequential)] public struct DriverInfo { /// <summary> /// , . - 3 4 (V3 V4 ). /// </summary> public uint Version; /// <summary> /// (, "QMS 810"). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string Name; /// <summary> /// , (, Windows x86, Windows IA64 Windows x64). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string Environment; /// <summary> /// (, "C:\DRIVERS\Pscript.dll"). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string DriverPath; /// <summary> /// (, "C:\DRIVERS\Qms810.ppd"). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string DataFile; /// <summary> /// dll (, "C:\DRIVERS\Pscriptui.dll"). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string ConfigFile; /// <summary> /// dll HLP- (, "C:\DRIVERS\Pscript.hlp"). /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string HelpFile; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string DependentFiles; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string MonitorName; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string DefaultDataType; }
ã€ã³ã¿ãŒãã§ãŒã¹idriver
/// <summary> /// . /// </summary> public interface IDriver : IPrintableDevice { /// <summary> /// . /// </summary> IMonitor Monitor { get; } /// <summary> /// , . - 3 4 (V3 V4 ). /// </summary> uint Version { get; } /// <summary> /// , (, Windows x86, Windows IA64 Windows x64). /// </summary> Environment Environment { get; } /// <summary> /// (, "C:\DRIVERS\Pscript.dll"). /// </summary> string Dll { get; } /// <summary> /// (, "C:\DRIVERS\Qms810.ppd"). /// </summary> string DataFile { get; } /// <summary> /// dll (, "C:\DRIVERS\Pscriptui.dll"). /// </summary> string ConfigFile { get; } /// <summary> /// dll HLP- (, "C:\DRIVERS\Pscript.hlp"). /// </summary> string HelpFile { get; } /// <summary> /// . /// </summary> string DependentFiles { get; } /// <summary> /// . /// </summary> DataType DefaultDataType { get; } }
ã¯ã©ã¹ãã©ã€ããŒ
/// <summary> /// . /// </summary> public class Driver : PrintableDevice, IDriver { /// <summary> /// . /// </summary> public virtual IMonitor Monitor { get; protected set; } /// <summary> /// , . - 3 4 (V3 V4 ). /// </summary> public virtual uint Version { get; protected set; } /// <summary> /// , . /// </summary> public virtual Environment Environment { get; protected set; } /// <summary> /// . /// </summary> public virtual string Dll { get; protected set; } /// <summary> /// . /// </summary> public virtual string DataFile { get; protected set; } /// <summary> /// dll . /// </summary> public virtual string ConfigFile { get; protected set; } /// <summary> /// dll HLP- . /// </summary> public virtual string HelpFile { get; protected set; } /// <summary> /// . /// </summary> public virtual string DependentFiles { get; protected set; } /// <summary> /// . /// </summary> public virtual DataType DefaultDataType { get; protected set; } /// <summary> /// . /// </summary> public static string Directory { get; protected set; } /// <summary> /// . /// </summary> public static Driver[] All { get { if (!PrintingApi.TryGetInfo(EnumPrinterDrivers, 3, out DriverInfo[] driverInfo)) return null; Driver[] drivers = new Driver[driverInfo.Length]; for (int i = 0; i < driverInfo.Length; i++) drivers[i] = new Driver(driverInfo[i].Name, driverInfo[i].DriverPath, driverInfo[i].DataFile, driverInfo[i].ConfigFile, driverInfo[i].HelpFile, driverInfo[i].Version, driverInfo[i].Environment.GetEnvironment(), (DataType)Enum.Parse(typeof(DataType), driverInfo[i].DefaultDataType ?? "RAW", true), driverInfo[i].DependentFiles, driverInfo[i].MonitorName); return drivers; } } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="dependentFiles"> .</param> /// <param name="monitorName"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, string dependentFiles, string monitorName) : base(name) { Dll = dll; DataFile = dataFile; ConfigFile = configFile; HelpFile = helpFile; Version = version; Environment = environment; DefaultDataType = defaultDataType; DependentFiles = dependentFiles; Monitor[] monitors = PrintingApi.Monitors; if (monitors.Select(m => m.Name).Contains(monitorName)) Monitor = monitors.Where(m => m.Name == monitorName).FirstOrDefault(); } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="dependentFiles"> .</param> /// <param name="monitor"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, string dependentFiles, IMonitor monitor) : this(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, dependentFiles, monitor?.Name) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="monitorName"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, string monitorName) : this(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, null, monitorName) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="monitor"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, IMonitor monitor) : this(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, monitor?.Name) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="monitorName"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, string monitorName) : this(name, dll, dataFile, configFile, helpFile, version, environment, DataType.RAW, monitorName) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="monitor"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, IMonitor monitor) : this(name, dll, dataFile, configFile, helpFile, version, environment, monitor?.Name) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="monitorName"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, string monitorName) : this(name, dll, dataFile, configFile, helpFile, version, Environment.Current, monitorName) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="monitor"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, IMonitor monitor) : this(name, dll, dataFile, configFile, helpFile, version, monitor?.Name) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="monitorName"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, string monitorName) : this(name, dll, dataFile, configFile, helpFile, 3, monitorName) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="monitor"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string helpFile, IMonitor monitor) : this(name, dll, dataFile, configFile, helpFile, monitor?.Name) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="monitorName"> .</param> public Driver(string name, string dll, string dataFile, string configFile, string monitorName) : this(name, dll, dataFile, configFile, null, monitorName) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="monitor"> .</param> public Driver(string name, string dll, string dataFile, string configFile, IMonitor monitor) : this(name, dll, dataFile, configFile, monitor?.Name) { } /// <summary> /// <see cref="Driver"/>. /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> public Driver(string name, string dll, string dataFile, string configFile) : this(name, dll, dataFile, configFile, null as string) { } /// <summary> /// <see cref="Driver"/>. /// </summary> static Driver() { uint length = 1024; StringBuilder driverDirectory = new StringBuilder((int)length); uint bytesNeeded = 0; if (!GetPrinterDriverDirectory(null, null, 1, driverDirectory, length, ref bytesNeeded)) throw new PrintingException(Marshal.GetLastWin32Error()); Directory = driverDirectory.ToString(); } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> public override void Install(string serverName) { try { if (!File.Exists(Dll)) throw new PrintingException($" '{Dll}'"); if (!File.Exists(DataFile)) throw new PrintingException($" '{DataFile}'"); if (!File.Exists(ConfigFile)) throw new PrintingException($" '{ConfigFile}'"); if (All.Select(d => d.Name).Contains(Name)) Uninstall(serverName); string systemDriverPath = Path.Combine(Directory, Path.GetFileName(Dll)); string systemDataPath = Path.Combine(Directory, Path.GetFileName(DataFile)); string systemConfigPath = Path.Combine(Directory, Path.GetFileName(ConfigFile)); string systemHelpPath = Path.Combine(Directory, Path.GetFileName(HelpFile)); File.Copy(Dll, systemDriverPath, true); File.Copy(DataFile, systemDataPath, true); File.Copy(ConfigFile, systemConfigPath, true); if (File.Exists(HelpFile)) File.Copy(HelpFile, systemHelpPath, true); DriverInfo driverInfo = new DriverInfo { Version = Version, Name = Name, Environment = Environment.GetEnvironmentName(), DriverPath = File.Exists(systemDriverPath) ? systemDriverPath : Dll, DataFile = File.Exists(systemDataPath) ? systemDataPath : DataFile, ConfigFile = File.Exists(systemConfigPath) ? systemConfigPath : ConfigFile, HelpFile = File.Exists(systemHelpPath) ? systemHelpPath : HelpFile, DependentFiles = DependentFiles, MonitorName = Monitor?.Name, DefaultDataType = Enum.GetName(typeof(DataType), DefaultDataType), }; if (AddPrinterDriver(serverName, Version, ref driverInfo)) return; int lastWin32ErrorCode = Marshal.GetLastWin32Error(); if (lastWin32ErrorCode == 0) return; throw new PrintingException(lastWin32ErrorCode); } catch (Exception e) { throw new PrintingException(e.Message, e); } } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> public override void Uninstall(string serverName) { try { if (!All.Select(d => d.Name).Contains(Name)) return; /// TODO: , . if (DeletePrinterDriver(serverName, Environment.GetEnvironmentName(), Name)) return; throw new PrintingException(Marshal.GetLastWin32Error()); } catch (Exception e) { throw new PrintingException(e.Message, e); } } #region Native /// <summary> /// . /// </summary> /// <param name="serverName"> , . null - .</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="level"> . 1.</param> /// <param name="driverDirectory"> .</param> /// <param name="bufferSize"> .</param> /// <param name="bytesNeeded"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool GetPrinterDriverDirectory(string serverName, string environment, uint level, [Out] StringBuilder driverDirectory, uint bufferSize, ref uint bytesNeeded); /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <param name="level"> . 1, 2, 3, 4, 5, 6 8.</param> /// <param name="driverInfo"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool AddPrinterDriver(string serverName, uint level, ref DriverInfo driverInfo); /// <summary> /// <see cref="DriverInfo"/>. /// </summary> /// <param name="serverName"> , . null - .</param> /// <param name="environment"> (, Windows x86, Windows IA64, Windows x64, Windows NT R4000). null, /// ( ). "all", , /// .</param> /// <param name="level"> . 1, 2, 3, 4, 5, 6 8.</param> /// <param name="drivers"> <see cref="DriverInfo"/>.</param> /// <param name="bufferSize"> <see cref="DriverInfo"/> ( ).</param> /// <param name="bytesNeeded"> .</param> /// <param name="bufferReturnedLength"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool EnumPrinterDrivers(string serverName, string environment, uint level, IntPtr drivers, uint bufferSize, ref uint bytesNeeded, ref uint bufferReturnedLength); /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <param name="environment"> (, Windows x86, Windows IA64, Windows x64, Windows NT R4000). null, /// ( ). "all", , /// .</param> /// <param name="driverName"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool DeletePrinterDriver(string serverName, string environment, string driverName); #endregion }
ãã©ã€ããŒã¡ãœããã§PrintingApiãæ¡åŒµãã
/// <summary> /// . /// </summary> public static Driver[] Drivers => Driver.All; /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="dependentFiles"> .</param> /// <param name="monitor"> .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, string dependentFiles, Monitor monitor, string serverName) { Driver driver = new Driver(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, dependentFiles, monitor); driver.TryInstall(serverName); return driver; } /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="dependentFiles"> .</param> /// <param name="monitor"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, string dependentFiles, Monitor monitor) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, dependentFiles, monitor, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="dependentFiles"> .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, string dependentFiles, string serverName) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, dependentFiles, null, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <param name="dependentFiles"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType, string dependentFiles) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, dependentFiles, null as string); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="defaultDataType"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, DataType defaultDataType) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, environment, defaultDataType, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment, string serverName) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, environment, DataType.RAW, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="environment">, (, Windows x86, Windows IA64 Windows x64).</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, Environment environment) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, environment, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version, string serverName) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, Environment.Current, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="version"> , . - 3 4 (V3 V4 ).</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, uint version) => InstallDriver(name, dll, dataFile, configFile, helpFile, version, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile, string serverName) => InstallDriver(name, dll, dataFile, configFile, helpFile, 3, serverName); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <param name="helpFile"> dll HLP- (, "C:\DRIVERS\Pscript.hlp").</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile, string helpFile) => InstallDriver(name, dll, dataFile, configFile, helpFile, null); /// <summary> /// . /// </summary> /// <param name="name"> .</param> /// <param name="dll"> (, "C:\DRIVERS\Pscript.dll").</param> /// <param name="dataFile"> (, "C:\DRIVERS\Qms810.ppd").</param> /// <param name="configFile"> dll (, "C:\DRIVERS\Pscriptui.dll").</param> /// <returns> .</returns> public Driver InstallDriver(string name, string dll, string dataFile, string configFile) => InstallDriver(name, dll, dataFile, configFile, null);
ã¢ãã¿ãŒã®åé€æ¹æ³ã§ãå°å·ã¢ãã¿ââãŒã«é¢é£ä»ããããŠãããã©ã€ããŒã®åé€ãè¿œå ããŸã
IEnumerable<Driver> drivers = Driver.All.Where(d => d.Monitor?.Name == Name); foreach (Driver driver in drivers) driver.Uninstall(serverName);
åäœãã¹ãã䜿çšãããã¹ã
/// <summary> /// <see cref="Driver"/>. /// </summary> [TestClass] public class DriverTests { /// <summary> /// . /// </summary> protected const string DriverName = "Test Driver"; /// <summary> /// . /// </summary> protected const string MonitorName = "mfilemon"; /// <summary> /// . /// </summary> protected const string FailedMonitorName = "noexist"; protected const string DllPath = "D:/Printing Tests/pscript.dll"; protected const string DataPath = "D:/Printing Tests/testprinter.ppd"; protected const string ConfigPath = "D:/Printing Tests/pscriptui.dll"; protected const string HelpPath = "D:/Printing Tests/pscript.hlp"; /// <summary> /// . /// </summary> [TestMethod] public void InstallTest() { Driver driver = new Driver(DriverName, DllPath, DataPath, ConfigPath, HelpPath, MonitorName); driver.Install(); Assert.IsTrue(Driver.All.Select(d => d.Name).Contains(DriverName)); } /// <summary> /// . /// </summary> [TestMethod] public void UninstallTest() { Driver driver = new Driver(DriverName, DllPath, DataPath, ConfigPath, HelpPath, MonitorName); driver.Uninstall(); Assert.IsFalse(Driver.All.Select(d => d.Name).Contains(DriverName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryInstallTest() { Driver driver = new Driver(DriverName, DllPath, DataPath, ConfigPath, HelpPath, MonitorName); bool f = driver.TryInstall(); Assert.IsTrue(f); Assert.IsTrue(Driver.All.Select(d => d.Name).Contains(DriverName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryUninstallTest() { Driver driver = new Driver(DriverName, DllPath, DataPath, ConfigPath, HelpPath, MonitorName); bool f = driver.TryUninstall(); Assert.IsTrue(f); Assert.IsFalse(Driver.All.Select(d => d.Name).Contains(DriverName)); } /// <summary> /// . /// </summary> [TestMethod] [ExpectedException(typeof(PrintingException))] public void InstallFailedTest() { Driver driver = new Driver(DriverName, DllPath + "failed", DataPath, ConfigPath, HelpPath, FailedMonitorName); driver.Install(); Assert.IsFalse(Driver.All.Select(d => d.Name).Contains(DriverName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryInstallFailedTest() { Driver driver = new Driver(DriverName, DllPath + "failed", DataPath, ConfigPath, HelpPath, FailedMonitorName); bool f = driver.TryInstall(); Assert.IsTrue(f); Assert.IsFalse(Driver.All.Select(d => d.Name).Contains(DriverName)); } }
å°å·è£ 眮
ãããŠãä»åºŠã¯ããããããUIãšå°å·ã¢ãã¿ââãŒã®éã®é¢ä¿ãæäŸããæãéèŠãªã³ã³ããŒãã³ãã§ããããªã³ã¿ãŒãå®è£ ãããšãã§ãã以åã®æäœãšã®éããã»ãšãã©ãããŸããã
struct PrinterInfo
/// <summary> /// . /// </summary> [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public struct PrinterInfo { /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string ServerName; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string PrinterName; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string ShareName; /// <summary> /// , . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string PortName; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string DriverName; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string Comment; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string Location; public IntPtr DevMode; [MarshalAs(UnmanagedType.LPTStr)] public string SepFile; /// <summary> /// , . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string PrintProcessor; /// <summary> /// . /// </summary> [MarshalAs(UnmanagedType.LPTStr)] public string DataType; [MarshalAs(UnmanagedType.LPTStr)] public string Parameters; public IntPtr SecurityDescriptor; public uint Attributes; public uint Priority; public uint DefaultPriority; public uint StartTime; public uint UntilTime; public uint Status; public uint cJobs; public uint AveragePPM; }
ã€ã³ã¹ããŒã«ãããŠããããªã³ã¿ãŒã®ãªã¹ããååŸããã«ã¯ããã©ã°ãå¿ èŠã§ãã
åæåPrinterEnumFlag
/// <summary> /// . /// </summary> [Flags] internal enum PrinterEnumFlag { Default = 0x00000001, Local = 0x00000002, Connections = 0x00000004, Favorite = 0x00000004, Name = 0x00000008, Remote = 0x00000010, Shared = 0x00000020, Network = 0x00000040, Expand = 0x00004000, Container = 0x00008000, IconMask = 0x00ff0000, Icon1 = 0x00010000, Icon2 = 0x00020000, Icon3 = 0x00040000, Icon4 = 0x00080000, Icon5 = 0x00100000, Icon6 = 0x00200000, Icon7 = 0x00400000, Icon8 = 0x00800000, Hide = 0x01000000, All = 0x02000000, Category3D = 0x04000000, }
ã€ã³ã¿ãŒãã§ã€ã¹IPrinter
/// <summary> /// . /// </summary> public interface IPrinter : IPrintableDevice { /// <summary> /// , . /// </summary> IPort Port { get; } /// <summary> /// , . /// </summary> IDriver Driver { get; } /// <summary> /// . /// </summary> string ShareName { get; } /// <summary> /// , . /// </summary> string ServerName { get; } /// <summary> /// . /// </summary> string Description { get; } /// <summary> /// . /// </summary> string Location { get; } string SepFile { get; } /// <summary> /// . /// </summary> string Parameters { get; } /// <summary> /// . /// </summary> DataType DataType { get; } }
ã¯ã©ã¹ããªã³ã¿ãŒ
/// <summary> /// . /// </summary> public class Printer : PrintableDevice, IPrinter { /// <summary> /// , . /// </summary> public virtual IPort Port { get; protected set; } /// <summary> /// , . /// </summary> public virtual IDriver Driver { get; protected set; } /// <summary> /// . /// </summary> public virtual string ShareName { get; protected set; } /// <summary> /// . /// </summary> public virtual string Description { get; protected set; } /// <summary> /// . /// </summary> public virtual DataType DataType { get; protected set; } /// <summary> /// . /// </summary> public virtual string Processor { get; protected set; } /// <summary> /// , . /// </summary> public virtual string ServerName { get; protected set; } /// <summary> /// . /// </summary> public virtual string Location { get; protected set; } /// <summary> /// . /// </summary> public virtual string Parameters { get; protected set; } public virtual string SepFile { get; protected set; } /// <summary> /// . /// </summary> public static Printer Default { get { uint length = 0; if (GetDefaultPrinter(null, ref length)) return null; int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != PrintingException.ErrorInsufficientBuffer) throw new PrintingException(lastWin32Error); StringBuilder printerName = new StringBuilder((int)length); if (!GetDefaultPrinter(printerName, ref length)) throw new PrintingException(Marshal.GetLastWin32Error()); string name = printerName.ToString(); return All.Where(p => p.Name == name).FirstOrDefault(); } set { if (!SetDefaultPrinter(value?.Name)) throw new PrintingException(Marshal.GetLastWin32Error()); } } /// <summary> /// . /// </summary> public static Printer[] All { get { uint bytesNeeded = 0; uint bufferReturnedLength = 0; uint level = 2; PrinterEnumFlag flags = PrinterEnumFlag.Local | PrinterEnumFlag.Network; if (EnumPrinters(flags, null, level, IntPtr.Zero, 0, ref bytesNeeded, ref bufferReturnedLength)) return null; int lastWin32Error = Marshal.GetLastWin32Error(); if (lastWin32Error != PrintingException.ErrorInsufficientBuffer) throw new PrintingException(lastWin32Error); IntPtr printersPtr = Marshal.AllocHGlobal((int)bytesNeeded); try { if (EnumPrinters(flags, null, level, printersPtr, bytesNeeded, ref bytesNeeded, ref bufferReturnedLength)) { IntPtr currentPrinterPtr = printersPtr; PrinterInfo[] printerInfo = new PrinterInfo[bufferReturnedLength]; Printer[] printers = new Printer[bufferReturnedLength]; Type type = typeof(PrinterInfo); for (int i = 0; i < bufferReturnedLength; i++) { printerInfo[i] = (PrinterInfo)Marshal.PtrToStructure(currentPrinterPtr, type); currentPrinterPtr = (IntPtr)(currentPrinterPtr.ToInt64() + Marshal.SizeOf(type)); printers[i] = new Printer(printerInfo[i].PrinterName, printerInfo[i].PortName, printerInfo[i].DriverName, printerInfo[i].PrintProcessor, printerInfo[i].ShareName, printerInfo[i].ServerName, printerInfo[i].Comment, (DataType)Enum.Parse(typeof(DataType), printerInfo[i].DataType), printerInfo[i].Location, printerInfo[i].Parameters, printerInfo[i].SepFile); } return printers; } throw new PrintingException(Marshal.GetLastWin32Error()); } catch { return null; } finally { Marshal.FreeHGlobal(printersPtr); } } } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> /// <param name="parameters"> .</param> /// <param name="sepFile"></param> public Printer(string name, string portName, string driverName, string processorName, string shareName, string serverName, string description, DataType dataType, string location, string parameters, string sepFile) : base(name) { Port[] ports = PrintingApi.Ports; Driver[] drivers = PrintingApi.Drivers; if (ports.Select(p => p.Name).Contains(portName)) Port = ports.Where(p => p.Name == portName).FirstOrDefault(); if (drivers.Select(d => d.Name).Contains(driverName)) Driver = drivers.Where(d => d.Name == driverName).FirstOrDefault(); Processor = processorName; ShareName = shareName; ServerName = serverName; Description = description; DataType = dataType; Location = location; Parameters = parameters; SepFile = sepFile; } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> /// <param name="parameters"> .</param> /// <param name="sepFile"></param> public Printer(string name, IPort port, IDriver driver, string processorName, string shareName, string serverName, string description, DataType dataType, string location, string parameters, string sepFile) : this(name, port?.Name, driver?.Name, processorName, shareName, serverName, description, dataType, location, parameters, sepFile) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> /// <param name="parameters"> .</param> public Printer(string name, string portName, string driverName, string processorName, string shareName, string serverName, string description, DataType dataType, string location, string parameters) : this(name, portName, driverName, processorName, shareName, serverName, description, dataType, location, parameters, null) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> /// <param name="parameters"> .</param> public Printer(string name, IPort port, IDriver driver, string processorName, string shareName, string serverName, string description, DataType dataType, string location, string parameters) : this(name, port?.Name, driver?.Name, processorName, shareName, serverName, description, dataType, location, parameters) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> public Printer(string name, string portName, string driverName, string processorName, string shareName, string serverName, string description, DataType dataType, string location) : this(name, portName, driverName, processorName, shareName, serverName, description, dataType, location, null) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> public Printer(string name, IPort port, IDriver driver, string processorName, string shareName, string serverName, string description, DataType dataType, string location) : this(name, port?.Name, driver?.Name, processorName, shareName, serverName, description, dataType, location) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> public Printer(string name, string portName, string driverName, string processorName, string shareName, string serverName, string description, DataType dataType) : this(name, portName, driverName, processorName, shareName, serverName, description, dataType, null) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> public Printer(string name, IPort port, IDriver driver, string processorName, string shareName, string serverName, string description, DataType dataType) : this(name, port?.Name, driver?.Name, processorName, shareName, serverName, description, dataType) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> public Printer(string name, string portName, string driverName, string processorName, string shareName, string serverName, string description) : this(name, portName, driverName, processorName, shareName, serverName, description, DataType.RAW) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> public Printer(string name, IPort port, IDriver driver, string processorName, string shareName, string serverName, string description) : this(name, port?.Name, driver?.Name, processorName, shareName, serverName, description) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> public Printer(string name, string portName, string driverName, string processorName, string shareName, string serverName) : this(name, portName, driverName, processorName, shareName, serverName, null) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> public Printer(string name, IPort port, IDriver driver, string processorName, string shareName, string serverName) : this(name, port?.Name, driver?.Name, processorName, shareName, serverName) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> public Printer(string name, string portName, string driverName, string processorName, string shareName) : this(name, portName, driverName, processorName, shareName, null) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> public Printer(string name, IPort port, IDriver driver, string processorName, string shareName) : this(name, port?.Name, driver?.Name, processorName, shareName) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> /// <param name="processorName"> .</param> public Printer(string name, string portName, string driverName, string processorName) : this(name, portName, driverName, processorName, null) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> public Printer(string name, IPort port, IDriver driver, string processorName) : this(name, port?.Name, driver?.Name, processorName) { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="portName"> .</param> /// <param name="driverName"> .</param> public Printer(string name, string portName, string driverName) : this(name, portName, driverName, "WinPrint") { } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> public Printer(string name, IPort port, IDriver driver) : this(name, port?.Name, driver?.Name) { } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> public override void Install(string serverName) { try { if (All.Select(p => p.Name).Contains(Name)) Uninstall(serverName); PrinterInfo printerInfo = new PrinterInfo { ServerName = serverName, PrinterName = Name, ShareName = ShareName, PortName = Port?.Name, DriverName = Driver?.Name, Comment = Description, Location = Location, DevMode = new IntPtr(0), SepFile = SepFile, PrintProcessor = Processor, DataType = Enum.GetName(typeof(DataType), DataType), Parameters = Parameters, SecurityDescriptor = new IntPtr(0), }; if (AddPrinter(serverName, 2, ref printerInfo)) return; int lastWin32ErrorCode = Marshal.GetLastWin32Error(); if (lastWin32ErrorCode == 0) return; throw new PrintingException(lastWin32ErrorCode); } catch (Exception e) { throw new PrintingException(e.Message, e); } } /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> public override void Uninstall(string serverName) { try { if (!All.Select(p => p.Name).Contains(Name)) return; PrinterDefaults defaults = new PrinterDefaults { DesiredAccess = PrinterAccess.PrinterAllAccess }; if (!NET.Port.OpenPrinter(Name, out IntPtr printerHandle, ref defaults)) throw new PrintingException(Marshal.GetLastWin32Error()); if (!DeletePrinter(printerHandle)) { int lastWin32ErrorCode = Marshal.GetLastWin32Error(); if (lastWin32ErrorCode == PrintingException.ErrorInvalidPrinterName) return; throw new PrintingException(lastWin32ErrorCode); } NET.Port.ClosePrinter(printerHandle); } catch (Exception e) { throw new PrintingException(e.Message, e); } } #region Native /// <summary> /// . /// </summary> /// <param name="serverName"> .</param> /// <param name="level"> .</param> /// <param name="printerInfo"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.StdCall)] internal static extern bool AddPrinter(string serverName, uint level, [In] ref PrinterInfo printerInfo); /// <summary> /// , . /// </summary> /// <param name="printerName"> .</param> /// <param name="bytesNeeded"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool GetDefaultPrinter([Out] StringBuilder printerName, ref uint bytesNeeded); /// <summary> /// . /// </summary> /// <param name="printerName"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool SetDefaultPrinter(string printerName); /// <summary> /// . /// </summary> /// <param name="flags"> .</param> /// <param name="serverName"> .</param> /// <param name="level"> .</param> /// <param name="printers"> .</param> /// <param name="bufferSize"> .</param> /// <param name="bytesNeeded"> .</param> /// <param name="bufferReturnedLength"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)] internal static extern bool EnumPrinters(PrinterEnumFlag flags, string serverName, uint level, IntPtr printers, uint bufferSize, ref uint bytesNeeded, ref uint bufferReturnedLength); /// <summary> /// . /// </summary> /// <param name="printer"> .</param> /// <returns>True, , False.</returns> [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.StdCall)] internal static extern bool DeletePrinter(IntPtr printer); #endregion }
å°å·Apiã®æ¡å€§
/// <summary> /// . /// </summary> public static Printer[] Printers => Printer.All; /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> /// <param name="parameters"> .</param> /// <param name="sepFile"></param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName, string shareName, string serverName, string description, DataType dataType, string location, string parameters, string sepFile) { Printer printer = new Printer(name, port, driver, processorName, shareName, serverName, description, dataType, location, parameters, sepFile); printer.TryInstall(serverName); return printer; } /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> /// <param name="parameters"> .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName, string shareName, string serverName, string description, DataType dataType, string location, string parameters) => RunPrinter(name, port, driver, processorName, shareName, serverName, description, dataType, location, parameters, null); /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <param name="location"> .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName, string shareName, string serverName, string description, DataType dataType, string location) => RunPrinter(name, port, driver, processorName, shareName, serverName, description, dataType, location, null); /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <param name="dataType"> .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName, string shareName, string serverName, string description, DataType dataType) => RunPrinter(name, port, driver, processorName, shareName, serverName, description, dataType, null); /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <param name="description"> .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName, string shareName, string serverName, string description) => RunPrinter(name, port, driver, processorName, shareName, serverName, description, DataType.RAW); /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <param name="serverName"> .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName, string shareName, string serverName) => RunPrinter(name, port, driver, processorName, shareName, serverName, null); /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <param name="shareName"> .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName, string shareName) => RunPrinter(name, port, driver, processorName, shareName, null); /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <param name="processorName"> .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver, string processorName) => RunPrinter(name, port, driver, processorName, null); /// <summary> /// <see cref="Printer"/>. /// </summary> /// <param name="name"> .</param> /// <param name="port">, .</param> /// <param name="driver">, .</param> /// <returns> .</returns> public Printer RunPrinter(string name, Port port, Driver driver) => RunPrinter(name, port, driver, "WinPrint");
æ¥ç¶ãããŠãããã¹ãŠã®ããªã³ã¿ãŒã®åé€ããåé€ããããŒããšãã©ã€ããŒã«è¿œå ããŸã
IEnumerable<Printer> printers = Printer.All.Where(p => p.Driver?.Name == Name); foreach (Printer printer in printers) printer.Uninstall(serverName);
ãã¹ãäž
/// <summary> /// <see cref="Printer"/>. /// </summary> [TestClass] public class PrinterTests { /// <summary> /// . /// </summary> protected const string PrinterName = "Test Printer"; /// <summary> /// . /// </summary> protected const string PortName = "TESTPORT:"; /// <summary> /// . /// </summary> protected const string DriverName = "Test Driver"; /// <summary> /// . /// </summary> [TestMethod] public void InstallTest() { Printer printer = new Printer(PrinterName, PortName, DriverName); printer.Install(); Assert.IsTrue(Printer.All.Select(p => p.Name).Contains(PrinterName)); } /// <summary> /// . /// </summary> [TestMethod] public void UninstallTest() { Printer printer = new Printer(PrinterName, PortName, DriverName); printer.Uninstall(); Assert.IsFalse(Printer.All.Select(p => p.Name).Contains(PrinterName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryInstallTest() { Printer printer = new Printer(PrinterName, PortName, DriverName); bool f = printer.TryInstall(); Assert.IsTrue(f); Assert.IsTrue(Printer.All.Select(p => p.Name).Contains(PrinterName)); } /// <summary> /// . /// </summary> [TestMethod] public void TryUninstallTest() { Printer printer = new Printer(PrinterName, PortName, DriverName); bool f = printer.TryUninstall(); Assert.IsTrue(f); Assert.IsFalse(Printer.All.Select(p => p.Name).Contains(PrinterName)); } }
ã·ã¹ãã ã®å€æŽãæå¹ã«ããã«ã¯ãããªã³ã¿ãŒãã€ã³ã¹ããŒã«ããåŸãå°å·ãµãŒãã¹ãæåã§åèµ·åããå¿ èŠããããŸããSpoolerãèµ·å/åèµ·åããéçã¡ãœãããPrintingApiã¯ã©ã¹ã«èšè¿°ããŸããããã¯ãã³ã³ãã¥ãŒã¿ãŒã®å°å·ãµãŒãã¹ãæåã«åæ¢ãããå Žåã«ãåœãŠã¯ãŸããŸãã
/// <summary> /// . /// </summary> /// <returns>True, , False.</returns> public static bool TryRestart() { int tryCount = 5; while (tryCount > 0) { try { ServiceController sc = new ServiceController("Spooler"); if (sc.Status != ServiceControllerStatus.Stopped || sc.Status != ServiceControllerStatus.StopPending) { sc.Stop(); sc.WaitForStatus(ServiceControllerStatus.Stopped); } sc.Start(); sc.WaitForStatus(ServiceControllerStatus.Running); return sc.Status == ServiceControllerStatus.Running; } catch { tryCount--; } } return false; }
System.ServiceProcess.dllãžã®ãªã³ã¯ããããžã§ã¯ãã«æ¥ç¶ããå¿ èŠããããŸãããã¹ãŠãåçŽã§ãïŒãµãŒãã¹ã³ã³ãããŒã©ãŒãèµ·åããã¹ããŒã¿ã¹ã確èªããéå§ãããŠããå Žåã¯åæ¢ããåæ¢ãããŸã§åŸ æ©ããŠããããšã©ãŒãçºçããå ŽåïŒããšãã°ããµãŒãã¹ãçŸåšããžãŒã§ããå ŽåïŒãéå§ããŠã¹ããŒã¿ã¹ããéå§ãã«å€ãããŸã§åŸ æ©ããæé 4ãç¹°ãè¿ããŸãåã
ãã®äžã§ãå°å·ããã€ã¹ãæäœããããã®åºæ¬æ©èœã¯æºåãã§ããŠãããšèããããšãã§ããŸãããã®ãããçŸæç¹ã§APIã§ã§ããããšïŒ
- ã€ã³ã¹ããŒã«ãããã¢ãã¿ãŒããã©ã€ããŒãéããŠããããŒããå®è¡äžã®ããªã³ã¿ãŒã®ã³ã¬ã¯ã·ã§ã³ãååŸããŸãã
- æ°ããã¢ãã¿ãŒãã€ã³ã¹ããŒã«ããŸãããã®ãããªã¢ãã¿ãŒãæ¢ã«ã€ã³ã¹ããŒã«ãããŠããå Žåã¯ãåã€ã³ã¹ããŒã«ããŸãã
- ã¢ãã¿ãŒãåãå€ããŸããã¢ãã¿ãŒã§ããŒããéããŠããå ŽåããŸãã¯ãã©ã€ããŒãæ¥ç¶ãããŠããå Žåã¯ããŸãããããåé€ããŸãã
- æ°ããããŒããéããŸãããã®ãããªããŒãããã§ã«éããŠããå Žåã¯ãå床éããŸãã
- ããŒããéããŸããããŒãã«ããªã³ã¿ãŒãæ¥ç¶ãããŠããå Žåã¯ãæåã«ããªã³ã¿ãŒãåæããŸãã
- ããªã³ã¿ãŒãã©ã€ããŒãã€ã³ã¹ããŒã«ããŸãããã©ã€ããæ¢ã«ã€ã³ã¹ããŒã«ãããŠããå Žå-åã€ã³ã¹ããŒã«ããŸãã
- ããªã³ã¿ãŒãã©ã€ããŒãã¢ã³ã€ã³ã¹ããŒã«ããŸãããã©ã€ããŒãããªã³ã¿ãŒã«ãã£ãŠäœ¿çšãããå Žå-æåã«ããããç¡å¹ã«ããŸãã
- ããªã³ã¿ãŒãèµ·åããŸããæå®ãããååã®ããªã³ã¿ãŒãæ¢ã«å®è¡ãããŠããå Žå-åèµ·åããŸãã
- ããªã³ã¿ãŒã®é»æºãåããŸãã
- CLRããã³Win32ãšã©ãŒããã£ããããŸãã
- å°å·ãµãŒãã¹ãåèµ·åããŸãã
PrintingApiã¯ã©ã¹ã®æåŸã®äžè¬çãªãã¹ããè¡ããèšäºã®æåŸã®éšåã«é²ã¿ãŸãã
å°å·ããã€ã¹ã®ãã¹ãŠã®ã³ã³ããŒãã³ãã®é 次ã€ã³ã¹ããŒã«ã確èªããåäœãã¹ã
[TestClass] public class PrintingApiTests { protected const string MonitorName = "mfilemon"; protected const string PortName = "TESTPORT:"; protected const string DriverName = "Test Driver"; protected const string PrinterName = "Test Printer"; protected const string MonitorFile = "D:/Printing Tests/mfilemon.dll"; protected const string DriverFile = "D:/Printing Tests/pscript5.dll"; protected const string DriverDataFile = "D:/Printing Tests/testprinter.ppd"; protected const string DriverConfigFile = "D:/Printing Tests/ps5ui.dll"; protected const string DriverHelpFile = "D:/Printing Tests/pscript.hlp"; [TestMethod] public void PrinterInstallationTest() { PrintingApi.TryRestart(); Monitor monitor = PrintingApi.Factory.CreateMonitor(MonitorName, MonitorFile); Port port = PrintingApi.Factory.OpenPort(PortName, monitor); Driver driver = PrintingApi.Factory.InstallDriver(DriverName, DriverFile, DriverDataFile, DriverConfigFile, DriverHelpFile, 3, Environment.Current, DataType.RAW, null, monitor); Printer printer = PrintingApi.Factory.RunPrinter(PrinterName, port, driver); PrintingApi.TryRestart(); Assert.IsNotNull(printer); } }


, Spooler , , API , STA- UI.
, . , . , mfilemon.dll :
string monitorName = "mfilemon"; string portName = "TESTPORT:"; string keyName = $"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\{monitorName}\\{portName}"; Registry.LocalMachine.CreateSubKey(keyName); using (RegistryKey regKey = Registry.LocalMachine.OpenSubKey(keyName, true)) { regKey.SetValue("OutputPath", "D:/Printing Tests/", RegistryValueKind.String); regKey.SetValue("FilePattern", "%r_%c_%u_%Y%m%d_%H%n%s_%j.ps", RegistryValueKind.String); regKey.SetValue("Overwrite", 0, RegistryValueKind.DWord); regKey.SetValue("UserCommand", string.Empty, RegistryValueKind.String); regKey.SetValue("ExecPath", string.Empty, RegistryValueKind.String); regKey.SetValue("WaitTermination", 0, RegistryValueKind.DWord); regKey.SetValue("PipeData", 0, RegistryValueKind.DWord); }
ããã§ããDïŒ/ Printing Tests /ããã£ã¬ã¯ããªã«ããŒãžèšè¿°ã®æ¢ã«çæãããPostScriptãã¡ã€ã«ã衚瀺ãããŸããå°ãªããšãããã¹ã圢åŒãŸãã¯PDFã«å€æããå€ãæ¹æ³ã§è§£æïŒGod forbidïŒãŸãã¯GhostScriptããŒã«ã䜿çšããŠããµãŒããŒã«è»¢éããå°ãªããšãã¡ã¢ãªã«ããŒãããŸããå°å·åŸã«ãã¡ã€ã«ãäœæãããç¬éãååããããã ãã«æ®ã£ãŠããŸãããã®ãããSystem.IOã¯ã©ã¹ã¯FileSystemWatcherã¯ã©ã¹ãæäŸããŸããããã¯ãã¡ã€ã«ã·ã¹ãã ã®ç¶æ ãç£èŠããã€ãã³ããã³ãã©ãŒãåŒã³åºãããšãã§ããŸãã
// , , , . FileSystemWatcher fileSystemWatcher = new FileSystemWatcher("D:/Printing Tests/", "*.ps") { NotifyFilter = NotifyFilters.DirectoryName }; fileSystemWatcher.NotifyFilter = fileSystemWatcher.NotifyFilter | NotifyFilters.FileName; fileSystemWatcher.NotifyFilter = fileSystemWatcher.NotifyFilter | NotifyFilters.Attributes; fileSystemWatcher.Created += new FileSystemEventHandler(PrinterHandler); // . try { fileSystemWatcher.EnableRaisingEvents = true; // . } catch (ArgumentException e) { }
ã€ãã³ããã³ãã©ã¯æ¬¡ã®ããã«ãªããŸãã
void PrinterHandler(object sender, FileSystemEventArgs e) { // . switch (e.ChangeType) { // . , . case WatcherChangeTypes.Created: try { // TODO: , - ( ). byte[] fileData = File.ReadAllBytes(e.FullPath); // , . // . File.Delete(e.FullPath); // , . } catch (Exception ex) { } break; } }
å®éãããã§ç§ãã¡ã®ã¿ã¹ã¯ã¯å®å šã«è§£æ±ºããããšèããããšãã§ããŸãã
ãããã«
ãã€ãã®ããã«ãç§ã¯ãã®èšäºã§äœãããããµããããŸãããä»æ¥ãç§ã¯ãç¹å®ã®ãåé¡ã«å¯Ÿãã解決çããæã§ã説æããããšããŸããïŒãã ããéå»æ°å¹Žã®çµéš-ããã§ãé¢é£æ§ããããŸãïŒã¯ãç§ã«ãšã£ãŠã§ããã ããããããã詳现ãªCïŒèšèªã«ãã£ãŠè§£æ±ºãããŸããããã®èšäºãã圹ã«ç«ãŠã°å¹žãã§ããæéãç¡é§ã«ããªãã§ãã ããã
äžèšã®è³æã¯ãã¹ããŒã©ãŒå°å·ãµãŒãã¹ã®åäœã®åºæ¬çãªç解ã ãã§ãªããã»ãšãã©ãã¹ãŠã®è€éãã®ã¢ã³ãããŒãžã³ãŒãã§é«ã¬ãã«ã®ãã«ããŒãäœæããã®ã«ååãªã¯ãã§ãã
ãããããç§ã¯ãã®ãããžã§ã¯ããåŒãç¶ããµããŒãããããªã³ãããã»ããµã§ã®äœæ¥ãããªã³ããã¥ãŒã®åŠçãªã©ã®å¯èœæ§ãèªèããŸãããããžã§ã¯ãã®ãŠããããã¹ããæ·»ä»ããããœãŒã¹ã³ãŒãã¯ããã¡ãã«ãããŸããããããžã§ã¯ãã§äœ¿çšããNuGetããã±ãŒãžã¯ããã¡ãããå ¥æã§ããŸãããããããŠãããŒãµã«PPDïŒããã³ä»®æ³ã¢ãã¿ãŒãã©ã€ããŒïŒãããŠã³ããŒãããŸãã
ãæž èŽããããšãããããŸããïŒ