Can I programmatically use the OneNote printer driver? - c++

I have a system service that handles print requests, and given a printer name from the user, attaches a DC to that printer. It starts a document, ends it, and detatches.
m_PrinterDC.CreateDC (L"WINSPOOL", _printerName.c_str(), NULL, NULL)
m_DC.Attach(m_hprinter)
m_DC.StartDoc(...)
...
mDc.TextOut(...)
...
m_DC.EndDoc()
m_DC.Detatch()
This works fine for normal printers, but when using the "Print to OneNote" functionality (driver name 'Send To OneNote 2010') it doesn't seem to work. I would like to avoid custom logic just for this feature; ideally all printers would work regardless. Any thoughts what might be going wrong? I've tried updating the printer security settings to include Print rights for group everyone; not sure what else to try.

Unfortunately, I have to guess some points, because you seem to avoid detailed description of error condition.
First, if you check all return values are success, just it may be a problem about onenote itself. Check the condition of onenote by printing using other programmes.
Second, did you check if _printerName is exact? If some of users are using other language OS, the driver name, 'Send To OneNote 2010' will be different or depending on version. Of course, if you check all return values of function calls, it recorded in your log file. However, I'm worrying about you used exact printer name by using 'EnumPrinters'.
http://msdn.microsoft.com/en-us/library/windows/desktop/dd162931(v=vs.85).aspx
I hope this helps you a little.

Related

DCMTK Understand the "DIMSE No valid Presentation Context ID" error

I'm currently developing a simple application for querying/retrieving data on a PACS. I use DCMTK for this purpose, and a DCM4CHEE PACS as test server.
My goal is to implement simple C-FIND queries, and a C-MOVE retrieving system (coupled with a custom SCP to actually download the data).
To do so, I've created a CustomSCU class, that inherits the DCMTK DcmSCU class.
I first implemented a C-ECHO message, that worked great.
Then, I tried to implement C-FIND requesting, but I got the error "DIMSE No valid Presentation Context ID" (more on that in the next paragraph) from my application, but no other log from DCM4CHEE. I've then used the command tool findscu (from dcmtk) to see if there was some configuration issue but the tool just worked fine. So in order to implement my C-FIND request, I've read the source of findscu (here) and adapted it in my code (meaning that i'm not using DcmSCU::sendCFindRequest but the class DcmFindSU).
But now, i'm facing the same problem with C-MOVE request. My code is pretty straight-forward :
//transfer syntaxes
OFList<OFString> ts;
ts.push_back(UID_LittleEndianExplicitTransferSyntax);
ts.push_back(UID_BigEndianExplicitTransferSyntax);
ts.push_back(UID_LittleEndianImplicitTransferSyntax);
//sop class
OFString pc = UID_MOVEPatientRootQueryRetrieveInformationModel;
addPresentationContext(pc, ts);
DcmDataset query;
query.putAndInsertOFStringArray(DCM_QueryRetrieveLevel, "PATIENT");
query.putAndInsertOFStringArray(DCM_PatientID, <ThePatientId>);
OFCondition condition = sendMOVERequest(findPresentationContextID(pc, ""), getAETitle(), &query, nullptr);
return condition.good();
I've also tried using UID_MOVEStudyRootQueryRetrieveInformationModel instead of UID_MOVEPatientRootQueryRetrieveInformationModel, with the same result : my application shows the error
DIMSE No valid Presentation Context ID
As I understand, a presentation context is concatenation of one or more transfer syntax and one SOP class. I read that the problem could come from the PACS that won't accept my presentation contexts. To be sure, I used the movescu tool (from DCMTK). It worked, and I saw this in the logs from de server DCM4CHEE :
received AAssociatedRQ
pc-1 : as=<numbers>/Patient Root Q/R InfoModel = FIND
ts=<numbers>/Explicit VR Little Endian
ts=<numbers>/Explicit VR Big Endian
ts=<numbers>/Implicit VR Little Endian
That means that the movescu tool does a find before attempting an actual move ?
Therefore, I changed my application context creation with :
OFList<OFString> ts;
ts.push_back(UID_LittleEndianExplicitTransferSyntax);
ts.push_back(UID_BigEndianExplicitTransferSyntax);
ts.push_back(UID_LittleEndianImplicitTransferSyntax);
OFString pc1 = UID_FINDPatientRootQueryRetrieveInformationModel;
OFString pc = UID_MOVEPatientRootQueryRetrieveInformationModel;
addPresentationContext(pc1, ts);
addPresentationContext(pc, ts);
(also tried study root)
But this didn't do the trick.
The problem seems to lie on the client side, as findPresentationContextID(pc, ""); alwasy return 0, no matter what.
I don't feel like it's possible to adapt the code of the movescu tool, as it appears to be very complex and not adequat for simple retrieve operations.
I don't know what to try. I hope someone can help me understand what's going on. That's the last part of my application, as the storage SCP already works.
Regards
It looks like you are not negotiating the association with the PACS.
After adding the presentation contexts and before sending any command, the SCU must connect to the PACS and negotiate the PresentationContexts with DcmSCU::initNetwork and then DcmSCU::negotiateAssociation.

C++ Poco ODBC Transactions - AutoCommit mode

I am currently attempting to use transactions in my C++ app, but I have a problem with the ODBC's auto commit mode.
I am using the POCO libaries to create a connection to a PostgreSQL database on the same machine. Currently, I can send data to this database as single statements, but I cannot get my head around how to use Poco's transaction libraries to be able to send this data more quickly.
As I have several thousand records to insert, and so continuing to use single insert statements is extrememly slow and inpractical - So I am trying to use Poco's transaction to speed this up a bit (a fair bit).
The error I am encountering is a theoretically a simple one - Poco is throwing the following error:
'Invalid access: Session is in auto commit mode.'
I understand, as a result of this, I should somehow set "auto commit" to false - as it only allows me to commit data to the database line by line, rather than as a single transaction.
The problem is how I set this.
Currently, I have a session created from Session.h, that looks alot like this:
session = new Poco::Data::Session(
"ODBC",
connection_data.str()
);
Where connection data is a simple stringstream with the login information, password, database, server and "Driver={PostgreSQL ANSI};" to tell ODBC to utilize PostgreSQL's driver.
I have tried just setting a property "autocommit" to false through the session's setFeature or setProperty settings, this, of course, was to no avail. (it was more of a ditch attempt at this point).
session->setFeature("AUTOCOMMIT", false);
Looking around, I saw a possible alternative method by creating a ODBC sessionImpl directly from ODBC/session/SessionImpl.h instead of using this generic method above, and then creating a new session object from this.
The benefits of this are that ODBC's sessionImpl has references to autocommit mode in the header, which would suggest it would be able to handle this:
void autoCommit(const std::string&, bool val);
/// Sets autocommit property for the session.
However, having not used sessionImpl before, I cannot garuntee if this will work or if can can get this to work with the limited documentation available.
I am using C++ 03 (Not 11), with Visual Studio 2015
Poco 1.7.5
Boost (Where needed)
Would any one know the correct way of setting this feature (above) or a alternative method to achieving this?
edit: Looking at the source of poco, at:
https://github.com/pocoproject/poco/blob/develop/Data/ODBC/src/SessionImpl.cpp#L153
The property seems be named autoCommit, and looking at
https://github.com/pocoproject/poco/blob/develop/Data/include/Poco/Data/AbstractSessionImpl.h#L120
the case of the property names seem to matter. So, does it help if you use session->setFeature("autoCommit", false);?
Cant you just call session->begin(); and session->end(); on the corresponding Session object?
What is returned by session->canTransact()?
According to the doc begin() will start a new transaction, the doc does not mention any property that needs to be set before or after.
See: https://pocoproject.org/docs/Poco.Data.Session.html
Also faced a similar issue.
First of all before begin() need:
m_ses.setFeature("autoCommit", false);
m_ses.begin();
And the second issue is that this feature stays "autoCommit" in false for all other sessions. So don't forget for the next session call
session.setFeature("autoCommit", true);

C++ Change Print Queue Owner

I want to know if it is possible to change the “Owner” name that is visible when you bring up the print queue to view the queued printer documents. I have a Windows Service that receives a document from a user and sends it a Windows printer, and the Owner is always the name of the user that logged into the workstation where the Service is running. I would like to change the “Owner” to something else, and this would be done in a C++ Windows DLL that the Windows Service loads and uses.
Added 8/30/16#9:14am ET
Thanks for the suggestion, Thomas. I should have mentioned my research, but it was long and empty. MSDN has a SetJob function which can take 1 of 4 structures (pJob = JOB_INFO_1…JOB_INFO_4). JOB_INFO_1, 2, and 4 have an LPSTR pUserName that appears to be what can be used to change the owner of the print job (Owner?). However, in the remarks section of SetJob it says:
“The following members of a JOB_INFO_1, JOB_INFO_2, or JOB_INFO_4 structure are ignored on a call to SetJob: JobId, pPrinterName, pMachineName, pUserName, pDrivername, Size, Submitted, Time, and TotalPages.”
And JOB_INFO_3 does not have this field in it. Nice.
I did not see any other functions that could maybe do this. Can you point me to something specific that I can research more? Or that is known to work? Thanks.
I'm not sure why MSDN says those fields are ignored. I change pUserName, pDocument, pStatus using SetJob with JOB_INFO_1 and it works perfectly.
Just be sure to set Position to JOB_POSITION_UNSPECIFIED.

Get rid of security message Outlook

I'm writing an application that needs to access to Outlook address book, however, every time I launch it a warning message is shown saying that an application is trying to access to your adress book. I've noticed this behaviour only with the machines where no antivirus is installed. How to get rid of this message?
Here is a part of the code I use to retreive some emails related informations
CApplication l_application;
l_application.CreateDispatch("Outlook.Application");
CNameSpace l_namespace = l_application.GetNamespace(_T("MAPI"));
CMAPIFolder l_mapiFolder = l_namespace.GetDefaultFolder(olFolderInbox);
CItems l_items = l_mapiFolder.GetItems();
m_mailItem = l_items.GetLast();
m_mailItem.Save();
//Get infos (mail's size, from, to, conversation topic...)
CApplication, CNameSpace, CItems are generated automatically, and m_mailItem is a CMailItem object.
See http://www.outlookcode.com/article.aspx?id=52 for a list of your options. Essentially you can either make sure an up-to-date antivirus app is installed or use Redemption (I am its author).

mongoDB cursor timeout in C++

I get the following error using mongoDB through its C++ API on a 64-bit installation:
getMore: cursor didn't exist on server, possible restart or timeout?
The code snippet where the error is located is the following:
std::auto_ptr<mongo::DBClientCursor> cursor =
connection.query("database.collection", mongo::BSONObj());
while (cursor->more()) {
// Do stuff
// Update contents of fields
connection.update(...);
}
What the code simply does is updating the contents of each document's fields based on a specific data structure.
The code has been tested with a small data set, and it works perfectly fine, so I assume this is not a coding error, but rather a database-side error that is related to the size of the final data set.
My error looks similar to this bug report. The solution that is proposed there is to set the cursor to have no timeout, but there is no such function for the C++ API, although it seems to exist for other languages.
Any suggestions would be much appreciated.