the issue is that writing csv file that was opened already
the environment is Visual 6.0 C++ (MFC)
time variable is executing time
int time = 1 ;
BOOL blNewXls = FALSE;
_Application objApp;
_Workbook objBook;
Workbooks objBooks;
Worksheets objSheets;
_Worksheet objSheet;
Range objRange;
LPDISPATCH lpDisp;
BOOL TestView::SaveTrxGeneration1ExcelFile(CString destFileName, MYSQL_ROW row, int num_fields)
{
COleVariant VOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
if( !objApp.CreateDispatch("Excel.Application") ){AfxMessageBox("XLS ERROR"); return FALSE;}
objApp.SetVisible(TRUE);
objApp.SetUserControl(TRUE);
lpDisp = objApp.GetWorkbooks();
objBooks.AttachDispatch(lpDisp);
lpDisp = objBooks.Open(destFileName, VOptional, VOptional, VOptional,VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional, VOptional);
lpDisp2 = lpDisp;
objBook.AttachDispatch(lpDisp);
lpDisp = objBook.GetSheets();
objSheets.AttachDispatch(lpDisp);
if(time == 2)
{
if( blNewXls )
objBook.SaveAs(COleVariant(destFileName),VOptional, VOptional, VOptional, VOptional,VOptional, FALSE, VOptional, VOptional,VOptional, VOptional);
else
objBook.Save();
objBooks.Close();
objApp.Quit();
objBooks.ReleaseDispatch(); // Release the object-IDispatch binding.
objApp.ReleaseDispatch();
objBooks = NULL; // Destroy the object references.
objApp = NULL;
time = 1;
}
else
time = 2 ;
return TRUE;
}
expected result : write 2 times
actual result : access violation when open() function executes
This is not an MFC question. Really, it is an Excel OLE automation question.
Why are you making it visible and why are you calling SetUserControl(TRUE)? Neither of those things should be necessary. For some reason, it is likely hanging onto a reference and not closing Excel because you made those calls you did which are not necessary.
After you call the first time, is there still a reference to Excel running in the background? Check task manager to verify that is it running or closed.
It seems obvious to me that it is still open. If it is open, you can't open it again.
A good news for you is that a csv file doesn't require Excel OLE, you can handle this using MFC only ... there is no need to have Excel/Office installed ... handle your csv file as text file using CStdioFile: CStdioFile
Related
I'm using the following Swift code to limit my GUI app on macOS to a single instance:
func IsAnotherInstanceRunning() -> Bool
{
let thisApp = NSRunningApplication.current
let thisBundleID = thisApp.bundleIdentifier
let thisPID = thisApp.processIdentifier
let workspace = NSWorkspace.shared
let apps = workspace.runningApplications.filter { (app) -> Bool in
if(app.bundleIdentifier == thisBundleID &&
app.processIdentifier != thisPID)
{
return true;
}
return false;
};
//Found any?
if(apps.count > 0)
{
return true
}
return false
}
I also have a console application written in C++. How can I do the same in pure C++?
Mainly how do I call anything related to NSRunningApplication and NSWorkspace?
I believe you can use named mutexes to achieve what you want.
You create a mutex with a specific name. If mutex already exists you quit.
https://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_mutexattr_getpshared.html
For crossplatform implementation make sense to take a look on https://theboostcpplibraries.com/boost.interprocess-synchronization
named_mutex.
I am using GhostScript API to test if a PDF is user password protected (You can only open the document if you have the password, what is different from owner protection that only protects the content against unauthorized copying or printing)
I am using this code in Qt:
const bool PDFTools::isUserProtected(const QString &iFilePath)
{
void *minst;
const QString filePath = iFilePath.toUtf8();
const std::string inputFile = QString( "%1" ).arg(filePath).toStdString();
int initiationCode = 0;
int executionCode = 0;
// GhostScript arguments
const int gsArgumentCount = 2;
char * gsArgumentValues[gsArgumentCount];
gsArgumentValues[0] = "-dNODISPLAY";
gsArgumentValues[1] = const_cast<char*>( inputFile.c_str() );
initiationCode = gsapi_new_instance(&minst, NULL);
if(initiationCode < 0)
return true;
initiationCode = gsapi_set_arg_encoding(minst, GS_ARG_ENCODING_UTF8);
if (initiationCode < 0)
{
gsapi_delete_instance(minst);
return true;
}
executionCode = gsapi_init_with_args(minst, gsArgumentCount, gsArgumentValues);
if(executionCode < 0)
{
gsapi_exit(minst);
gsapi_delete_instance(minst);
return true;
}
gsapi_exit(minst);
gsapi_delete_instance(minst);
return false;
}
When the document is protected it returns true because it can't open without password and Ghostscript returns a execution error, this is OK.
The problem is when the document it's not protected it opens the first page and keeps waiting for the return key to be pressed so it can pass to the next page.
>>showpage, press <return> to continue<<
You can add the "-dNOPAUSE" and "-dBATCH" to the gsArgumentValues but this will cause another problem. If I have really big PDF with big number of pages this will take to much time to pass through all pages only after that it will return false.
Anyone knows how can I exit the process when the Ghostscript prompts for return? At that stage I already know that the PDF is not protected and I can exit and return false.
I have tried with the callback function but with no success.
Thanks in advance.
Try using -dFirstPage=1 -dLastPage=1 and -dNOPAUSE -dBATCH. Then it only processes the first page.
Otherwise you'll have to intercept the press any key and interrupt the process, or modify the device to throw an error after the first page or something.
NOTE although you can use these switches with other types of input than PDF, they still have to process the entire input file because, unlike PDF, there is no easy way to find the n'th page in a PostScript or PCL file.
I'm using TaskDialogIndirect to display prompts to the user. Normally this works just fine, but sometimes, after the program has been running for a while, it begins returning an error code that the MSDN entry does not list as being one of the error codes this function can return.
0x80040001 OLE_E_ADVF "Invalid advise flags"
I have checked all the inputs to the function against previous successful calls in the same run. Aside from differences in the string to be displayed, they are identical. (the strings are even the same length.)
// create task dialog struct
TASKDIALOGCONFIG tdc;
ZeroMemory(&tdc, sizeof(TASKDIALOGCONFIG));
tdc.cbSize = sizeof(tdc);
tdc.dwFlags = (((dwMessageBoxFlags & MB_OKCANCEL) == MB_OKCANCEL) ? TDF_ALLOW_DIALOG_CANCELLATION : 0) | TDF_POSITION_RELATIVE_TO_WINDOW;
tdc.hwndParent = hwndOwner;
tdc.hInstance = LGetHInstance();
tdc.pszContent = usrText.wsz;
tdc.pButtons = _pButtons;
tdc.cButtons = nButtons;
tdc.pszMainIcon = pszTaskDialogIcon;
tdc.pszWindowTitle = usrCaption.wsz;
tdc.nDefaultButton = nDefaultButton;
// display it now
int iButton = 0;
BOOL b = 0;
HRESULT hResult = TaskDialogIndirect(&tdc, &iButton, NULL, &b);
NEW INFORMATION
At the same time that TaskDialogIndirect stops behaving correctly, ShellExecute also stops working, as does CreateFile.
This was actually caused by an event handle leak elsewhere. When the available handles ran out, no more API calls which needed to create a handle could succeed. They did return a rather odd set of error codes though, none of which was "out of handles".
I have google high and low and found examples, but none of them seems to work (Lua 5.2).
I have a simple function in Lua
function onData ( data )
print ( data )
end
I want to call onData from C++ and tried this:
// Create new Lua state
L = luaL_newstate();
// Load all Lua libraries
luaL_openlibs(L);
// Create co-routine
CO = lua_newthread(L);
// Load and compile script
AnsiString script(Frame->Script_Edit->Text);
if (luaL_loadbuffer(CO,script.c_str(),script.Length(),AnsiString(Name).c_str()) == LUA_OK) {
Compiled = true;
} else {
cs_error(CO, "Compiler error: "); // Print compiler error
Compiled = false;
}
// Script compiled and ready?
if (Compiled == true) {
lua_getglobal(CO, "onData"); // <-------- Doesn't find the function
if( !lua_isfunction(CO,-1)) {
lua_pop(CO,1);
return;
}
lua_pushlstring(CO,data,len);
lua_resume(CO,NULL,0)
}
As you can see I'm starting my script as a co-routine so I can use the lua_yield() function on it. I have tried to look for the function in both the L and CO states.
luaL_loadbuffer loads the script but does not run it. onData will only be defined when the script is run.
Try calling luaL_dostring instead of luaL_loadbuffer.
Or add lua_pcall(CO,0,0,0) before lua_getglobal.
Moreover, you need lua_resume(CO,NULL,1) to pass data to onData.
CString m_strRemorcaNmb; // value for this string is set before
CString path = "DB\\dataBase";
CDaoDatabase db;
try
{
db.Open(path, 0, 0, "");
CDaoRecordset rs(&db);
rs.Open(AFX_DAO_USE_DEFAULT_TYPE, _T("SELECT Numar_inmatriculare FROM Masini;"), 0);
COleVariant searched(m_strRemorcaNmb);
BOOL bFound = rs.Seek("=",&searched);
}
Here i try to verify if a CString value is contained in my data base (.mdb). When it reaches BOOL bFound = rs.Seek("=",&searched); a debug assertion failed error is thrown. Hitting retry on the dialog box the application triggers a breakpoint in daocore.cpp at this line ASSERT(m_nOpenType == dbOpenTable);.
To use Seek you have to have a table-type recordset. (See MSDN: http://msdn.microsoft.com/en-US/library/k3tkt1zd%28v=vs.80%29.aspx) To get this, you have to specify the type when you open the recordset.
Example:
rs.Open(CDaoRecordSet::dbOpenTable,"table1");
This way of checking, if a specific record exists, is very slow. You suck all the records over the network and then check them. It is way better to modify the filter of the recordset before opening, and then check if any records have been returned.
Method A:
sql = "SELECT count(*) AS xyz FROM table WHERE Field='value'";
rs.Open(CDaoRecordset::dbOpenSnapshot,sql);
COleVariant count = rs.GetFieldValue(0);
Method B for generated recordsets:
rs.m_strFilter.Format("Field = '%s'", value);
rs.Open(CDaoRecordset::dbOpenSnapshot,"table");
if(rs.IsEOF()) // no records returned
{
}