@esslassi/electron-printer 0.0.2 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +222 -53
- package/binding.gyp +51 -33
- package/package.json +47 -33
- package/src/linux_printer.cpp +171 -0
- package/src/linux_printer.h +21 -0
- package/src/mac_printer.cpp +166 -0
- package/src/mac_printer.h +22 -0
- package/src/main.cpp +22 -0
- package/src/print.cpp +272 -0
- package/src/printer_factory.cpp +20 -0
- package/src/printer_factory.h +13 -0
- package/src/printer_interface.h +29 -0
- package/src/windows_printer.cpp +210 -0
- package/src/windows_printer.h +35 -0
- package/.gitattributes +0 -2
- package/Gruntfile.js +0 -80
- package/LICENSE +0 -21
- package/binding.js +0 -244
- package/index.js +0 -1
- package/printer.js +0 -1
- package/src/hello_world.cc +0 -8
- package/src/macros.hh +0 -53
- package/src/node_printer.cc +0 -31
- package/src/node_printer.hpp +0 -77
- package/src/node_printer_win.cc +0 -586
- package/test/getDefaultPrinterName.test.js +0 -18
- package/test/getPrinters.test.js +0 -26
- package/test/incompleteFunctions.js +0 -56
- package/test/printDirect.test.js +0 -34
- package/test/sayMyName.test.js +0 -21
- package/tools/buildElectronLinux.sh +0 -10
- package/tools/buildElectronWindows.ps1 +0 -20
- package/tools/buildWindows.ps1 +0 -23
- package/tools/generateReleaseBuildsLinux.sh +0 -59
- package/tools/generateReleaseBuildsWindows.ps1 +0 -63
- package/tools/getSourceFiles.py +0 -12
- package/tools/remove_directory.py +0 -27
- package/tsconfig.json +0 -22
- package/types/index.d.ts +0 -56
package/src/node_printer.hpp
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
#ifndef NODE_PRINTER_HPP
|
|
2
|
-
#define NODE_PRINTER_HPP
|
|
3
|
-
#include "macros.hh"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
MY_NODE_MODULE_CALLBACK(SayMyName);
|
|
7
|
-
MY_NODE_MODULE_CALLBACK(getPrinters);
|
|
8
|
-
MY_NODE_MODULE_CALLBACK(getDefaultPrinterName);
|
|
9
|
-
MY_NODE_MODULE_CALLBACK(printDirect);
|
|
10
|
-
MY_NODE_MODULE_CALLBACK(getPrinter);
|
|
11
|
-
MY_NODE_MODULE_CALLBACK(printFile);
|
|
12
|
-
MY_NODE_MODULE_CALLBACK(getSupportedPrintFormats);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* @brief A base class template for managing a pointer to a value of type Type.
|
|
18
|
-
*
|
|
19
|
-
* This class provides basic functionality for managing a pointer to a value,
|
|
20
|
-
* including construction, destruction, and access methods.
|
|
21
|
-
*
|
|
22
|
-
* @tparam Type The type of the value being managed.
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
template<typename Type>
|
|
26
|
-
class MemValueBase
|
|
27
|
-
{
|
|
28
|
-
public:
|
|
29
|
-
/**
|
|
30
|
-
* @brief Default constructor. Initializes the pointer to NULL.
|
|
31
|
-
*/
|
|
32
|
-
MemValueBase(): _value(NULL) {}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* @brief Virtual destructor. The allocated memory will be deallocated.
|
|
36
|
-
*/
|
|
37
|
-
virtual ~MemValueBase() {}
|
|
38
|
-
/**
|
|
39
|
-
* @brief Gets the pointer to the value.
|
|
40
|
-
*
|
|
41
|
-
* @return A pointer to the value of type Type.
|
|
42
|
-
*/
|
|
43
|
-
Type * get() {return _value; }
|
|
44
|
-
/**
|
|
45
|
-
* @brief Overloaded arrow operator to access the value.
|
|
46
|
-
*
|
|
47
|
-
* @return A pointer to the value of type Type.
|
|
48
|
-
*/
|
|
49
|
-
Type * operator ->() { return &_value; }
|
|
50
|
-
/**
|
|
51
|
-
* @brief Conversion operator to check if the pointer is not NULL.
|
|
52
|
-
*
|
|
53
|
-
* @return True if the pointer is not NULL, false otherwise.
|
|
54
|
-
*/
|
|
55
|
-
operator bool() const { return (_value != NULL); }
|
|
56
|
-
protected:
|
|
57
|
-
Type *_value; /**< Pointer to the value of type Type. */
|
|
58
|
-
/**
|
|
59
|
-
* @brief Virtual method to free the allocated memory.
|
|
60
|
-
*
|
|
61
|
-
* This method can be overridden by derived classes to provide custom
|
|
62
|
-
* memory deallocation logic.
|
|
63
|
-
*/
|
|
64
|
-
virtual void free() {};
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Try to extract a string or buffer from a N-API value.
|
|
69
|
-
* @param value - source N-API value
|
|
70
|
-
* @param oData - destination data
|
|
71
|
-
* @return TRUE if value is a string or buffer, FALSE otherwise
|
|
72
|
-
*/
|
|
73
|
-
|
|
74
|
-
bool getStringOrBufferFromNapiValue(const Napi::Value& value, std::string& oData);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
#endif
|
package/src/node_printer_win.cc
DELETED
|
@@ -1,586 +0,0 @@
|
|
|
1
|
-
#include "node_printer.hpp"
|
|
2
|
-
#if _MSC_VER
|
|
3
|
-
#include <windows.h>
|
|
4
|
-
#include <Winspool.h>
|
|
5
|
-
#include <Wingdi.h>
|
|
6
|
-
#pragma comment(lib, "Winspool.lib")
|
|
7
|
-
#else
|
|
8
|
-
#error "Unsupported compiler for windows. Feel free to add it."
|
|
9
|
-
#endif
|
|
10
|
-
|
|
11
|
-
#include <string>
|
|
12
|
-
#include <map>
|
|
13
|
-
#include <utility>
|
|
14
|
-
#include <sstream>
|
|
15
|
-
#include <cstdio>
|
|
16
|
-
|
|
17
|
-
// Utility function to output messages
|
|
18
|
-
void ConsolePrint(const std::string& message) {
|
|
19
|
-
printf("%s\n", message.c_str());
|
|
20
|
-
fflush(stdout); // Ensure the output is flushed immediately
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
// Function to convert std::u16string to std::wstring
|
|
24
|
-
std::wstring u16stringToWString(const std::u16string& u16str) {
|
|
25
|
-
return std::wstring(u16str.begin(), u16str.end());
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
namespace{
|
|
29
|
-
typedef std::map<std::string, DWORD> StatusMapType;
|
|
30
|
-
|
|
31
|
-
/** Memory value class management to avoid memory leak
|
|
32
|
-
*/
|
|
33
|
-
template<typename Type>
|
|
34
|
-
class MemValue: public MemValueBase<Type> {
|
|
35
|
-
public:
|
|
36
|
-
/** Constructor of allocating iSizeKbytes bytes memory;
|
|
37
|
-
* @param iSizeKbytes size in bytes of required allocating memory
|
|
38
|
-
*/
|
|
39
|
-
MemValue(const DWORD iSizeKbytes) {
|
|
40
|
-
_value = (Type*)malloc(iSizeKbytes);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
~MemValue () {
|
|
44
|
-
free();
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
Type* get() {
|
|
48
|
-
return _value;
|
|
49
|
-
}
|
|
50
|
-
protected:
|
|
51
|
-
virtual void free() {
|
|
52
|
-
if(_value != NULL)
|
|
53
|
-
{
|
|
54
|
-
::free(_value);
|
|
55
|
-
_value = NULL;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
private:
|
|
60
|
-
Type* _value; // Declaration of the member variable
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
struct PrinterHandle
|
|
64
|
-
{
|
|
65
|
-
PrinterHandle(LPWSTR iPrinterName)
|
|
66
|
-
{
|
|
67
|
-
_ok = OpenPrinterW(iPrinterName, &_printer, NULL);
|
|
68
|
-
}
|
|
69
|
-
~PrinterHandle()
|
|
70
|
-
{
|
|
71
|
-
if(_ok)
|
|
72
|
-
{
|
|
73
|
-
ClosePrinter(_printer);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
operator HANDLE() {return _printer;}
|
|
77
|
-
operator bool() { return (!!_ok);}
|
|
78
|
-
HANDLE& operator *() { return _printer;}
|
|
79
|
-
HANDLE* operator ->() { return &_printer;}
|
|
80
|
-
const HANDLE& operator ->() const { return _printer;}
|
|
81
|
-
HANDLE _printer;
|
|
82
|
-
BOOL _ok;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
const StatusMapType& getStatusMap()
|
|
86
|
-
{
|
|
87
|
-
static StatusMapType result;
|
|
88
|
-
if(!result.empty())
|
|
89
|
-
{
|
|
90
|
-
return result;
|
|
91
|
-
}
|
|
92
|
-
// add only first time
|
|
93
|
-
#define STATUS_PRINTER_ADD(value, type) result.insert(std::make_pair(value, type))
|
|
94
|
-
STATUS_PRINTER_ADD("BUSY", PRINTER_STATUS_BUSY);
|
|
95
|
-
STATUS_PRINTER_ADD("DOOR-OPEN", PRINTER_STATUS_DOOR_OPEN);
|
|
96
|
-
STATUS_PRINTER_ADD("ERROR", PRINTER_STATUS_ERROR);
|
|
97
|
-
STATUS_PRINTER_ADD("INITIALIZING", PRINTER_STATUS_INITIALIZING);
|
|
98
|
-
STATUS_PRINTER_ADD("IO-ACTIVE", PRINTER_STATUS_IO_ACTIVE);
|
|
99
|
-
STATUS_PRINTER_ADD("MANUAL-FEED", PRINTER_STATUS_MANUAL_FEED);
|
|
100
|
-
STATUS_PRINTER_ADD("NO-TONER", PRINTER_STATUS_NO_TONER);
|
|
101
|
-
STATUS_PRINTER_ADD("NOT-AVAILABLE", PRINTER_STATUS_NOT_AVAILABLE);
|
|
102
|
-
STATUS_PRINTER_ADD("OFFLINE", PRINTER_STATUS_OFFLINE);
|
|
103
|
-
STATUS_PRINTER_ADD("OUT-OF-MEMORY", PRINTER_STATUS_OUT_OF_MEMORY);
|
|
104
|
-
STATUS_PRINTER_ADD("OUTPUT-BIN-FULL", PRINTER_STATUS_OUTPUT_BIN_FULL);
|
|
105
|
-
STATUS_PRINTER_ADD("PAGE-PUNT", PRINTER_STATUS_PAGE_PUNT);
|
|
106
|
-
STATUS_PRINTER_ADD("PAPER-JAM", PRINTER_STATUS_PAPER_JAM);
|
|
107
|
-
STATUS_PRINTER_ADD("PAPER-OUT", PRINTER_STATUS_PAPER_OUT);
|
|
108
|
-
STATUS_PRINTER_ADD("PAPER-PROBLEM", PRINTER_STATUS_PAPER_PROBLEM);
|
|
109
|
-
STATUS_PRINTER_ADD("PAUSED", PRINTER_STATUS_PAUSED);
|
|
110
|
-
STATUS_PRINTER_ADD("PENDING-DELETION", PRINTER_STATUS_PENDING_DELETION);
|
|
111
|
-
STATUS_PRINTER_ADD("POWER-SAVE", PRINTER_STATUS_POWER_SAVE);
|
|
112
|
-
STATUS_PRINTER_ADD("PRINTING", PRINTER_STATUS_PRINTING);
|
|
113
|
-
STATUS_PRINTER_ADD("PROCESSING", PRINTER_STATUS_PROCESSING);
|
|
114
|
-
STATUS_PRINTER_ADD("SERVER-UNKNOWN", PRINTER_STATUS_SERVER_UNKNOWN);
|
|
115
|
-
STATUS_PRINTER_ADD("TONER-LOW", PRINTER_STATUS_TONER_LOW);
|
|
116
|
-
STATUS_PRINTER_ADD("USER-INTERVENTION", PRINTER_STATUS_USER_INTERVENTION);
|
|
117
|
-
STATUS_PRINTER_ADD("WAITING", PRINTER_STATUS_WAITING);
|
|
118
|
-
STATUS_PRINTER_ADD("WARMING-UP", PRINTER_STATUS_WARMING_UP);
|
|
119
|
-
#undef STATUS_PRINTER_ADD
|
|
120
|
-
return result;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
const StatusMapType& getJobStatusMap()
|
|
124
|
-
{
|
|
125
|
-
static StatusMapType result;
|
|
126
|
-
if(!result.empty())
|
|
127
|
-
{
|
|
128
|
-
return result;
|
|
129
|
-
}
|
|
130
|
-
// add only first time
|
|
131
|
-
#define STATUS_PRINTER_ADD(value, type) result.insert(std::make_pair(value, type))
|
|
132
|
-
// Common statuses
|
|
133
|
-
STATUS_PRINTER_ADD("PRINTING", JOB_STATUS_PRINTING);
|
|
134
|
-
STATUS_PRINTER_ADD("PRINTED", JOB_STATUS_PRINTED);
|
|
135
|
-
STATUS_PRINTER_ADD("PAUSED", JOB_STATUS_PAUSED);
|
|
136
|
-
|
|
137
|
-
// Specific statuses
|
|
138
|
-
STATUS_PRINTER_ADD("BLOCKED-DEVQ", JOB_STATUS_BLOCKED_DEVQ);
|
|
139
|
-
STATUS_PRINTER_ADD("DELETED", JOB_STATUS_DELETED);
|
|
140
|
-
STATUS_PRINTER_ADD("DELETING", JOB_STATUS_DELETING);
|
|
141
|
-
STATUS_PRINTER_ADD("ERROR", JOB_STATUS_ERROR);
|
|
142
|
-
STATUS_PRINTER_ADD("OFFLINE", JOB_STATUS_OFFLINE);
|
|
143
|
-
STATUS_PRINTER_ADD("PAPEROUT", JOB_STATUS_PAPEROUT);
|
|
144
|
-
STATUS_PRINTER_ADD("RESTART", JOB_STATUS_RESTART);
|
|
145
|
-
STATUS_PRINTER_ADD("SPOOLING", JOB_STATUS_SPOOLING);
|
|
146
|
-
STATUS_PRINTER_ADD("USER-INTERVENTION", JOB_STATUS_USER_INTERVENTION);
|
|
147
|
-
// XP and later
|
|
148
|
-
#ifdef JOB_STATUS_COMPLETE
|
|
149
|
-
STATUS_PRINTER_ADD("COMPLETE", JOB_STATUS_COMPLETE);
|
|
150
|
-
#endif
|
|
151
|
-
#ifdef JOB_STATUS_RETAINED
|
|
152
|
-
STATUS_PRINTER_ADD("RETAINED", JOB_STATUS_RETAINED);
|
|
153
|
-
#endif
|
|
154
|
-
|
|
155
|
-
#undef STATUS_PRINTER_ADD
|
|
156
|
-
return result;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const StatusMapType& getAttributeMap()
|
|
160
|
-
{
|
|
161
|
-
static StatusMapType result;
|
|
162
|
-
if(!result.empty())
|
|
163
|
-
{
|
|
164
|
-
return result;
|
|
165
|
-
}
|
|
166
|
-
// add only first time
|
|
167
|
-
#define ATTRIBUTE_PRINTER_ADD(value, type) result.insert(std::make_pair(value, type))
|
|
168
|
-
ATTRIBUTE_PRINTER_ADD("DIRECT", PRINTER_ATTRIBUTE_DIRECT);
|
|
169
|
-
ATTRIBUTE_PRINTER_ADD("DO-COMPLETE-FIRST", PRINTER_ATTRIBUTE_DO_COMPLETE_FIRST);
|
|
170
|
-
ATTRIBUTE_PRINTER_ADD("ENABLE-DEVQ", PRINTER_ATTRIBUTE_ENABLE_DEVQ);
|
|
171
|
-
ATTRIBUTE_PRINTER_ADD("HIDDEN", PRINTER_ATTRIBUTE_HIDDEN);
|
|
172
|
-
ATTRIBUTE_PRINTER_ADD("KEEPPRINTEDJOBS", PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS);
|
|
173
|
-
ATTRIBUTE_PRINTER_ADD("LOCAL", PRINTER_ATTRIBUTE_LOCAL);
|
|
174
|
-
ATTRIBUTE_PRINTER_ADD("NETWORK", PRINTER_ATTRIBUTE_NETWORK);
|
|
175
|
-
ATTRIBUTE_PRINTER_ADD("PUBLISHED", PRINTER_ATTRIBUTE_PUBLISHED);
|
|
176
|
-
ATTRIBUTE_PRINTER_ADD("QUEUED", PRINTER_ATTRIBUTE_QUEUED);
|
|
177
|
-
ATTRIBUTE_PRINTER_ADD("RAW-ONLY", PRINTER_ATTRIBUTE_RAW_ONLY);
|
|
178
|
-
ATTRIBUTE_PRINTER_ADD("SHARED", PRINTER_ATTRIBUTE_SHARED);
|
|
179
|
-
ATTRIBUTE_PRINTER_ADD("OFFLINE", PRINTER_ATTRIBUTE_WORK_OFFLINE);
|
|
180
|
-
// XP
|
|
181
|
-
#ifdef PRINTER_ATTRIBUTE_FAX
|
|
182
|
-
ATTRIBUTE_PRINTER_ADD("FAX", PRINTER_ATTRIBUTE_FAX);
|
|
183
|
-
#endif
|
|
184
|
-
// vista
|
|
185
|
-
#ifdef PRINTER_ATTRIBUTE_FRIENDLY_NAME
|
|
186
|
-
ATTRIBUTE_PRINTER_ADD("FRIENDLY-NAME", PRINTER_ATTRIBUTE_FRIENDLY_NAME);
|
|
187
|
-
ATTRIBUTE_PRINTER_ADD("MACHINE", PRINTER_ATTRIBUTE_MACHINE);
|
|
188
|
-
ATTRIBUTE_PRINTER_ADD("PUSHED-USER", PRINTER_ATTRIBUTE_PUSHED_USER);
|
|
189
|
-
ATTRIBUTE_PRINTER_ADD("PUSHED-MACHINE", PRINTER_ATTRIBUTE_PUSHED_MACHINE);
|
|
190
|
-
#endif
|
|
191
|
-
// server 2003
|
|
192
|
-
#ifdef PRINTER_ATTRIBUTE_TS
|
|
193
|
-
ATTRIBUTE_PRINTER_ADD("TS", PRINTER_ATTRIBUTE_TS);
|
|
194
|
-
#endif
|
|
195
|
-
#undef ATTRIBUTE_PRINTER_ADD
|
|
196
|
-
return result;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const StatusMapType& getJobCommandMap()
|
|
200
|
-
{
|
|
201
|
-
static StatusMapType result;
|
|
202
|
-
if(!result.empty())
|
|
203
|
-
{
|
|
204
|
-
return result;
|
|
205
|
-
}
|
|
206
|
-
// add only first time
|
|
207
|
-
#define COMMAND_JOB_ADD(value, type) result.insert(std::make_pair(value, type))
|
|
208
|
-
COMMAND_JOB_ADD("CANCEL", JOB_CONTROL_CANCEL);
|
|
209
|
-
COMMAND_JOB_ADD("PAUSE", JOB_CONTROL_PAUSE);
|
|
210
|
-
COMMAND_JOB_ADD("RESTART", JOB_CONTROL_RESTART);
|
|
211
|
-
COMMAND_JOB_ADD("RESUME", JOB_CONTROL_RESUME);
|
|
212
|
-
COMMAND_JOB_ADD("DELETE", JOB_CONTROL_DELETE);
|
|
213
|
-
COMMAND_JOB_ADD("SENT-TO-PRINTER", JOB_CONTROL_SENT_TO_PRINTER);
|
|
214
|
-
COMMAND_JOB_ADD("LAST-PAGE-EJECTED", JOB_CONTROL_LAST_PAGE_EJECTED);
|
|
215
|
-
#ifdef JOB_CONTROL_RETAIN
|
|
216
|
-
COMMAND_JOB_ADD("RETAIN", JOB_CONTROL_RETAIN);
|
|
217
|
-
#endif
|
|
218
|
-
#ifdef JOB_CONTROL_RELEASE
|
|
219
|
-
COMMAND_JOB_ADD("RELEASE", JOB_CONTROL_RELEASE);
|
|
220
|
-
#endif
|
|
221
|
-
#undef COMMAND_JOB_ADD
|
|
222
|
-
return result;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
void parseJobObject(JOB_INFO_2W *job, Napi::Object result_printer_job)
|
|
226
|
-
{
|
|
227
|
-
Napi::Env env = result_printer_job.Env(); // info.Env();
|
|
228
|
-
// Common fields
|
|
229
|
-
ADD_NAPI_NUMBER_PROPERTY(result_printer_job, "id", job->JobId);
|
|
230
|
-
// Example usage of the string property macro
|
|
231
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "printerName", pPrinterName);
|
|
232
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "user", pUserName);
|
|
233
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "format", pDatatype);
|
|
234
|
-
result_printer_job.Set(Napi::String::New(env, "priority"), Napi::Number::New(env, job->Priority));
|
|
235
|
-
result_printer_job.Set(Napi::String::New(env, "size"), Napi::Number::New(env, job->Size));
|
|
236
|
-
Napi::Array result_printer_job_status = Napi::Array::New(env);
|
|
237
|
-
int i_status = 0;
|
|
238
|
-
for (const auto &itStatus : getJobStatusMap())
|
|
239
|
-
{
|
|
240
|
-
if (job->Status & itStatus.second)
|
|
241
|
-
{
|
|
242
|
-
result_printer_job_status.Set(i_status++, Napi::String::New(env, itStatus.first.c_str()));
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
if ((job->pStatus != NULL) && (*job->pStatus != L'\0'))
|
|
246
|
-
{
|
|
247
|
-
result_printer_job_status.Set(i_status++, Napi::String::New(env, (char16_t *)job->pStatus));
|
|
248
|
-
}
|
|
249
|
-
result_printer_job.Set(Napi::String::New(env, "status"), result_printer_job_status);
|
|
250
|
-
// Specific fields
|
|
251
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "machineName", pMachineName);
|
|
252
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "document", pDocument);
|
|
253
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "notifyName", pNotifyName);
|
|
254
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "printProcessor", pPrintProcessor);
|
|
255
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "parameters", pParameters);
|
|
256
|
-
ADD_NAPI_STRING_PROPERTY(result_printer_job, "driverName", pDriverName);
|
|
257
|
-
result_printer_job.Set(Napi::String::New(env, "position"), Napi::Number::New(env, job->Position));
|
|
258
|
-
result_printer_job.Set(Napi::String::New(env, "startTime"), Napi::Number::New(env, job->StartTime));
|
|
259
|
-
result_printer_job.Set(Napi::String::New(env, "untilTime"), Napi::Number::New(env, job->UntilTime));
|
|
260
|
-
result_printer_job.Set(Napi::String::New(env, "totalPages"), Napi::Number::New(env, job->TotalPages));
|
|
261
|
-
result_printer_job.Set(Napi::String::New(env, "time"), Napi::Number::New(env, job->Time));
|
|
262
|
-
result_printer_job.Set(Napi::String::New(env, "pagesPrinted"), Napi::Number::New(env, job->PagesPrinted));
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
std::string getLastErrorCodeAndMessage() {
|
|
266
|
-
std::ostringstream s;
|
|
267
|
-
DWORD erroCode = GetLastError();
|
|
268
|
-
s << "code: " << erroCode;
|
|
269
|
-
DWORD retSize;
|
|
270
|
-
LPTSTR pTemp = NULL;
|
|
271
|
-
retSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
|
|
272
|
-
FORMAT_MESSAGE_FROM_SYSTEM|
|
|
273
|
-
FORMAT_MESSAGE_ARGUMENT_ARRAY,
|
|
274
|
-
NULL,
|
|
275
|
-
erroCode,
|
|
276
|
-
LANG_NEUTRAL,
|
|
277
|
-
(LPTSTR)&pTemp,
|
|
278
|
-
0,
|
|
279
|
-
NULL );
|
|
280
|
-
if (retSize && pTemp != NULL) {
|
|
281
|
-
//pTemp[strlen(pTemp)-2]='\0'; //remove cr and newline character
|
|
282
|
-
//TODO: check if it is needed to convert c string to std::string
|
|
283
|
-
std::string stringMessage(pTemp);
|
|
284
|
-
s << ", message: " << stringMessage;
|
|
285
|
-
LocalFree((HLOCAL)pTemp);
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
return s.str();
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
std::string retrieveAndParseJobs(const LPWSTR iPrinterName, const DWORD& iTotalJobs, Napi::Object result_printer_jobs, PrinterHandle& iPrinterHandle)
|
|
292
|
-
{
|
|
293
|
-
Napi::Env env = result_printer_jobs.Env();
|
|
294
|
-
DWORD bytes_needed = 0, totalJobs = 0;
|
|
295
|
-
BOOL bError = EnumJobsW(*iPrinterHandle, 0, iTotalJobs, 2, NULL, bytes_needed, &bytes_needed, &totalJobs);
|
|
296
|
-
MemValue<JOB_INFO_2W> jobs(bytes_needed);
|
|
297
|
-
if(!jobs)
|
|
298
|
-
{
|
|
299
|
-
std::string error_str("Error on allocating memory for jobs: ");
|
|
300
|
-
error_str += getLastErrorCodeAndMessage();
|
|
301
|
-
Napi::Object result_printer_job = Napi::Object::New(env);
|
|
302
|
-
result_printer_job.Set(NAPI_STRING_NEW_UTF8(env, "error"), NAPI_STRING_NEW_UTF8(env, error_str.c_str()));
|
|
303
|
-
result_printer_jobs.Set(uint32_t(0), result_printer_job);
|
|
304
|
-
return std::string("");
|
|
305
|
-
}
|
|
306
|
-
DWORD dummy_bytes = 0;
|
|
307
|
-
bError = EnumJobsW(*iPrinterHandle, 0, iTotalJobs, 2, (LPBYTE)jobs.get(), bytes_needed, &dummy_bytes, &totalJobs);
|
|
308
|
-
if(!bError)
|
|
309
|
-
{
|
|
310
|
-
std::string error_str("Error on EnumJobsW: ");
|
|
311
|
-
error_str += getLastErrorCodeAndMessage();
|
|
312
|
-
Napi::Object result_printer_job = Napi::Object::New(env);
|
|
313
|
-
result_printer_job.Set(NAPI_STRING_NEW_UTF8(env, "error"), NAPI_STRING_NEW_UTF8(env, error_str.c_str()));
|
|
314
|
-
result_printer_jobs.Set(uint32_t(0), result_printer_job);
|
|
315
|
-
return std::string("");
|
|
316
|
-
}
|
|
317
|
-
JOB_INFO_2W *job = jobs.get();
|
|
318
|
-
for(DWORD i = 0; i < totalJobs; ++i, ++job)
|
|
319
|
-
{
|
|
320
|
-
Napi::Object result_printer_job = Napi::Object::New(env);
|
|
321
|
-
parseJobObject(job, result_printer_job);
|
|
322
|
-
result_printer_jobs.Set(i, result_printer_job);
|
|
323
|
-
}
|
|
324
|
-
return std::string("");
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
std::string parsePrinterInfo(const PRINTER_INFO_2W *printer, Napi::Object result_printer, PrinterHandle& iPrinterHandle) {
|
|
328
|
-
Napi::Env env = result_printer.Env();
|
|
329
|
-
#define ADD_V8_STRING_PROPERTY(name, key) if((printer->##key != NULL) && (*printer->##key != L'\0')) \
|
|
330
|
-
{ \
|
|
331
|
-
result_printer.Set(Napi::String::New(result_printer.Env(), #name), Napi::String::New(result_printer.Env(), (char16_t*)printer->##key)); \
|
|
332
|
-
}
|
|
333
|
-
//LPTSTR pPrinterName;
|
|
334
|
-
ADD_V8_STRING_PROPERTY(name, pPrinterName)
|
|
335
|
-
//LPTSTR pServerName;
|
|
336
|
-
ADD_V8_STRING_PROPERTY(serverName, pServerName)
|
|
337
|
-
//LPTSTR pShareName;
|
|
338
|
-
ADD_V8_STRING_PROPERTY(shareName, pShareName)
|
|
339
|
-
//LPTSTR pPortName;
|
|
340
|
-
ADD_V8_STRING_PROPERTY(portName, pPortName)
|
|
341
|
-
//LPTSTR pDriverName;
|
|
342
|
-
ADD_V8_STRING_PROPERTY(driverName, pDriverName)
|
|
343
|
-
//LPTSTR pComment;
|
|
344
|
-
ADD_V8_STRING_PROPERTY(comment, pComment)
|
|
345
|
-
//LPTSTR pLocation;
|
|
346
|
-
ADD_V8_STRING_PROPERTY(location, pLocation)
|
|
347
|
-
//LPTSTR pSepFile;
|
|
348
|
-
ADD_V8_STRING_PROPERTY(sepFile, pSepFile)
|
|
349
|
-
//LPTSTR pPrintProcessor;
|
|
350
|
-
ADD_V8_STRING_PROPERTY(printProcessor, pPrintProcessor)
|
|
351
|
-
//LPTSTR pDatatype;
|
|
352
|
-
ADD_V8_STRING_PROPERTY(datatype, pDatatype)
|
|
353
|
-
//LPTSTR pParameters;
|
|
354
|
-
ADD_V8_STRING_PROPERTY(parameters, pParameters)
|
|
355
|
-
#undef ADD_V8_STRING_PROPERTY
|
|
356
|
-
//DWORD Status;
|
|
357
|
-
// statuses from:
|
|
358
|
-
// http://msdn.microsoft.com/en-gb/library/windows/desktop/dd162845(v=vs.85).aspx
|
|
359
|
-
Napi::Array result_printer_status = Napi::Array::New(env);
|
|
360
|
-
int i_status = 0;
|
|
361
|
-
for (const auto& itStatus : getStatusMap()) {
|
|
362
|
-
if (printer->Status & itStatus.second) {
|
|
363
|
-
result_printer_status.Set(i_status++, Napi::String::New(env, itStatus.first.c_str()));
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
result_printer.Set(Napi::String::New(env, "status"), result_printer_status);
|
|
367
|
-
result_printer.Set(Napi::String::New(env, "statusNumber"), Napi::Number::New(env, printer->Status));
|
|
368
|
-
// Attributes
|
|
369
|
-
Napi::Array result_printer_attributes = Napi::Array::New(env);
|
|
370
|
-
int i_attribute = 0;
|
|
371
|
-
for (const auto& itAttribute : getAttributeMap()) {
|
|
372
|
-
if (printer->Attributes & itAttribute.second) {
|
|
373
|
-
result_printer_attributes.Set(i_attribute++, Napi::String::New(env, itAttribute.first.c_str()));
|
|
374
|
-
}
|
|
375
|
-
result_printer.Set(Napi::String::New(env, "attributes"), result_printer_attributes);
|
|
376
|
-
// Other properties
|
|
377
|
-
result_printer.Set(Napi::String::New(env, "priority"), Napi::Number::New(env, printer->Priority));
|
|
378
|
-
result_printer.Set(Napi::String::New(env, "defaultPriority"), Napi::Number::New(env, printer->DefaultPriority));
|
|
379
|
-
result_printer.Set(Napi::String::New(env, "averagePPM"), Napi::Number::New(env, printer->AveragePPM));
|
|
380
|
-
|
|
381
|
-
if (printer->StartTime > 0) {
|
|
382
|
-
result_printer.Set(Napi::String::New(env, "startTime"), Napi::Number::New(env, printer->StartTime));
|
|
383
|
-
}
|
|
384
|
-
if (printer->UntilTime > 0) {
|
|
385
|
-
result_printer.Set(Napi::String::New(env, "untilTime"), Napi::Number::New(env, printer->UntilTime));
|
|
386
|
-
}
|
|
387
|
-
if (printer->cJobs > 0) {
|
|
388
|
-
Napi::Array result_printer_jobs = Napi::Array::New(env, printer->cJobs);
|
|
389
|
-
std::string error_str = retrieveAndParseJobs(printer->pPrinterName, printer->cJobs, result_printer_jobs, iPrinterHandle);
|
|
390
|
-
if (!error_str.empty()) {
|
|
391
|
-
return error_str;
|
|
392
|
-
}
|
|
393
|
-
result_printer.Set(Napi::String::New(env, "jobs"), result_printer_jobs);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
return "";
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
MY_NODE_MODULE_CALLBACK(getPrinters)
|
|
406
|
-
{
|
|
407
|
-
MY_NODE_MODULE_HANDLESCOPE;
|
|
408
|
-
DWORD printers_size = 0;
|
|
409
|
-
DWORD printers_size_bytes = 0, dummyBytes = 0;
|
|
410
|
-
DWORD Level = 2;
|
|
411
|
-
DWORD flags = PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS;
|
|
412
|
-
// First try to retrieve the number of printers
|
|
413
|
-
BOOL bError = EnumPrintersW(flags, NULL, Level, NULL, 0, &printers_size_bytes, &printers_size);
|
|
414
|
-
// Check for errors in the first call
|
|
415
|
-
if (!bError && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
|
|
416
|
-
RETURN_EXCEPTION_STR(MY_NODE_MODULE_ENV, "Error retrieving printer size.");
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
// Check if we got a valid size
|
|
420
|
-
if (printers_size_bytes == 0) {
|
|
421
|
-
RETURN_EXCEPTION_STR(info.Env(), "No printers found or invalid size returned.");
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Allocate the required memory
|
|
425
|
-
MemValue<PRINTER_INFO_2W> printers(printers_size_bytes);
|
|
426
|
-
if (!printers.get()) // Make sure to check the pointer
|
|
427
|
-
{
|
|
428
|
-
RETURN_EXCEPTION_STR(MY_NODE_MODULE_ENV, "Error allocating memory for printers");
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
// Second call to retrieve printer information
|
|
432
|
-
bError = EnumPrintersW(flags, NULL, Level, (LPBYTE)(printers.get()), printers_size_bytes, &dummyBytes, &printers_size);
|
|
433
|
-
if (!bError)
|
|
434
|
-
{
|
|
435
|
-
std::string error_str("Error on EnumPrinters");
|
|
436
|
-
error_str += getLastErrorCodeAndMessage();
|
|
437
|
-
RETURN_EXCEPTION_STR(MY_NODE_MODULE_ENV, error_str.c_str());
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
// Prepare result array
|
|
441
|
-
Napi::Array result = Napi::Array::New(MY_NODE_MODULE_ENV, printers_size);
|
|
442
|
-
PRINTER_INFO_2W *printer = printers.get();
|
|
443
|
-
DWORD i = 0;
|
|
444
|
-
for (; i < printers_size; ++i, ++printer)
|
|
445
|
-
{
|
|
446
|
-
Napi::Object a_printer = Napi::Object::New(MY_NODE_MODULE_ENV);
|
|
447
|
-
PrinterHandle printerHandle((LPWSTR)(printer->pPrinterName));
|
|
448
|
-
std::string error_str = parsePrinterInfo(printer, a_printer, printerHandle);
|
|
449
|
-
if (!error_str.empty())
|
|
450
|
-
{
|
|
451
|
-
RETURN_EXCEPTION_STR(MY_NODE_MODULE_ENV, error_str.c_str());
|
|
452
|
-
}
|
|
453
|
-
result.Set(i, a_printer);
|
|
454
|
-
}
|
|
455
|
-
MY_NODE_MODULE_RETURN_VALUE(result);
|
|
456
|
-
}
|
|
457
|
-
|
|
458
|
-
MY_NODE_MODULE_CALLBACK(getDefaultPrinterName)
|
|
459
|
-
{
|
|
460
|
-
MY_NODE_MODULE_HANDLESCOPE;
|
|
461
|
-
DWORD cSize = 0;
|
|
462
|
-
GetDefaultPrinterW(NULL, &cSize);
|
|
463
|
-
|
|
464
|
-
if(cSize == 0) {
|
|
465
|
-
MY_NODE_MODULE_RETURN_VALUE(NAPI_STRING_NEW_UTF8(MY_NODE_MODULE_ENV, ""));
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
MemValue<uint16_t> bPrinterName(cSize*sizeof(uint16_t));
|
|
469
|
-
BOOL res = GetDefaultPrinterW((LPWSTR)(bPrinterName.get()), &cSize);
|
|
470
|
-
|
|
471
|
-
if(!res) {
|
|
472
|
-
MY_NODE_MODULE_RETURN_VALUE(NAPI_STRING_NEW_UTF8(MY_NODE_MODULE_ENV, ""));
|
|
473
|
-
}
|
|
474
|
-
MY_NODE_MODULE_RETURN_VALUE(NAPI_STRING_NEW_2BYTES(MY_NODE_MODULE_ENV, bPrinterName.get()));
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
MY_NODE_MODULE_CALLBACK(printDirect)
|
|
478
|
-
{
|
|
479
|
-
MY_NODE_MODULE_HANDLESCOPE;
|
|
480
|
-
// Ensure the correct number of arguments
|
|
481
|
-
if (info.Length() < 5) {
|
|
482
|
-
Napi::TypeError::New(env, "Expected 5 arguments").ThrowAsJavaScriptException();
|
|
483
|
-
return env.Null();
|
|
484
|
-
}
|
|
485
|
-
|
|
486
|
-
// Check and extract the first argument (string or buffer)
|
|
487
|
-
std::string data;
|
|
488
|
-
if (!getStringOrBufferFromNapiValue(info[0], data)) {
|
|
489
|
-
Napi::TypeError::New(env, "Argument 0 must be a string or Buffer").ThrowAsJavaScriptException();
|
|
490
|
-
return env.Null();
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
// Check and extract the second argument (string)
|
|
494
|
-
if (!info[1].IsString()) {
|
|
495
|
-
Napi::TypeError::New(env, "Argument 1 must be a string").ThrowAsJavaScriptException();
|
|
496
|
-
return env.Null();
|
|
497
|
-
}
|
|
498
|
-
std::u16string u16PrinterName = info[1].As<Napi::String>().Utf16Value();
|
|
499
|
-
std::wstring printername = u16stringToWString(u16PrinterName);
|
|
500
|
-
|
|
501
|
-
// Check and extract the third argument (string)
|
|
502
|
-
if (!info[2].IsString()) {
|
|
503
|
-
Napi::TypeError::New(env, "Argument 2 must be a string").ThrowAsJavaScriptException();
|
|
504
|
-
return env.Null();
|
|
505
|
-
}
|
|
506
|
-
std::u16string u16DocName = info[2].As<Napi::String>().Utf16Value();
|
|
507
|
-
std::wstring docname = u16stringToWString(u16DocName);
|
|
508
|
-
|
|
509
|
-
// Check and extract the fourth argument (string)
|
|
510
|
-
if (!info[3].IsString()) {
|
|
511
|
-
Napi::TypeError::New(env, "Argument 3 must be a string").ThrowAsJavaScriptException();
|
|
512
|
-
return env.Null();
|
|
513
|
-
}
|
|
514
|
-
std::u16string u16Type = info[3].As<Napi::String>().Utf16Value();
|
|
515
|
-
std::wstring type = u16stringToWString(u16Type);
|
|
516
|
-
|
|
517
|
-
// Convert std::wstring to LPWSTR (mutable wide string pointer)
|
|
518
|
-
std::vector<wchar_t> printernameMutable(printername.begin(), printername.end());
|
|
519
|
-
printernameMutable.push_back(L'\0'); // Ensure null-termination
|
|
520
|
-
|
|
521
|
-
PrinterHandle printerHandle(printernameMutable.data());
|
|
522
|
-
if (!printerHandle) {
|
|
523
|
-
std::string error_str("Error on PrinterHandle: ");
|
|
524
|
-
error_str += getLastErrorCodeAndMessage();
|
|
525
|
-
Napi::TypeError::New(env, error_str).ThrowAsJavaScriptException();
|
|
526
|
-
return env.Null();
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
// Fill in the structure with info about this "document."
|
|
530
|
-
DOC_INFO_1W DocInfo;
|
|
531
|
-
DocInfo.pDocName = const_cast<LPWSTR>(docname.c_str());
|
|
532
|
-
DocInfo.pOutputFile = NULL;
|
|
533
|
-
DocInfo.pDatatype = const_cast<LPWSTR>(type.c_str());
|
|
534
|
-
|
|
535
|
-
// Inform the spooler the document is beginning.
|
|
536
|
-
DWORD dwJob = StartDocPrinterW(*printerHandle, 1, (LPBYTE)&DocInfo);
|
|
537
|
-
if (dwJob > 0) {
|
|
538
|
-
// Start a page.
|
|
539
|
-
BOOL bStatus = StartPagePrinter(*printerHandle);
|
|
540
|
-
if (bStatus) {
|
|
541
|
-
// Send the data to the printer.
|
|
542
|
-
DWORD dwBytesWritten = 0L;
|
|
543
|
-
bStatus = WritePrinter(*printerHandle, (LPVOID)(data.c_str()), (DWORD)data.size(), &dwBytesWritten);
|
|
544
|
-
EndPagePrinter(*printerHandle);
|
|
545
|
-
|
|
546
|
-
// Check to see if correct number of bytes were written.
|
|
547
|
-
if (dwBytesWritten != data.size()) {
|
|
548
|
-
Napi::TypeError::New(env, "Not all bytes were sent").ThrowAsJavaScriptException();
|
|
549
|
-
return env.Null();
|
|
550
|
-
}
|
|
551
|
-
} else {
|
|
552
|
-
std::string error_str("StartPagePrinter error: ");
|
|
553
|
-
error_str += getLastErrorCodeAndMessage();
|
|
554
|
-
Napi::TypeError::New(env, error_str).ThrowAsJavaScriptException();
|
|
555
|
-
return env.Null();
|
|
556
|
-
}
|
|
557
|
-
// Inform the spooler that the document is ending.
|
|
558
|
-
EndDocPrinter(*printerHandle);
|
|
559
|
-
} else {
|
|
560
|
-
std::string error_str("StartDocPrinterW error: ");
|
|
561
|
-
error_str += getLastErrorCodeAndMessage();
|
|
562
|
-
Napi::TypeError::New(env, error_str).ThrowAsJavaScriptException();
|
|
563
|
-
return env.Null();
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
MY_NODE_MODULE_RETURN_VALUE(Napi::Number::New(env, dwJob));
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
MY_NODE_MODULE_CALLBACK(getPrinter)
|
|
571
|
-
{
|
|
572
|
-
MY_NODE_MODULE_HANDLESCOPE;
|
|
573
|
-
MY_NODE_MODULE_RETURN_VALUE(NAPI_STRING_NEW_UTF8(MY_NODE_MODULE_ENV, "getPrinter is not implemented yet, request for a PR if required"));
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
MY_NODE_MODULE_CALLBACK(printFile)
|
|
577
|
-
{
|
|
578
|
-
MY_NODE_MODULE_HANDLESCOPE;
|
|
579
|
-
RETURN_EXCEPTION(MY_NODE_MODULE_ENV, "Not yet implemented on Windows");
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
MY_NODE_MODULE_CALLBACK(getSupportedPrintFormats)
|
|
583
|
-
{
|
|
584
|
-
MY_NODE_MODULE_HANDLESCOPE;
|
|
585
|
-
RETURN_EXCEPTION(MY_NODE_MODULE_ENV, "Not yet implemented, Request for a PR");
|
|
586
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const assert = require('assert/strict');
|
|
2
|
-
const { test, beforeEach } = require('node:test');
|
|
3
|
-
|
|
4
|
-
let addon;
|
|
5
|
-
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
addon = require('../lib');
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
test('Ensure getDefaultPrinterName function exists', (t) => {
|
|
11
|
-
assert.ok(addon.getDefaultPrinterName, 'getDefaultPrinterName function should exist');
|
|
12
|
-
assert.strictEqual(typeof addon.getDefaultPrinterName, 'function', 'getDefaultPrinterName should be a function');
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
test('Ensure getDefaultPrinterName returns a string', (t) => {
|
|
16
|
-
const result = addon.getDefaultPrinterName();
|
|
17
|
-
assert.strictEqual(typeof result, "string", 'getDefaultPrinterName should return a string');
|
|
18
|
-
});
|