I am trying to connect my C++ project to SQL Server using ADO.it goes well when checking first "hr" but error encounter when opening database on the second "if" statement, it says 'Microsoft C++ exception: _com_error at memory location'.
i wonder what is the problem and how can i open database? or is there another way to open database?
i have already tried to change _ConnectionPtr pConnection = NULL; into this _ConnectionPtr pConnection("ADODB.Connection"). here is my code:
HRESULT hr = S_OK;
_ConnectionPtr pConnection = NULL;
_RecordsetPtr pRecordset = NULL;
_bstr_t strCon("Data Source=...\\SQLEXPRESS;Initial Catalog=TestDB;Integrated Security=True");
hr = pConnection.CreateInstance((__uuidof(Connection)));
if (FAILED(hr))
{
printf("Error instantiating Connection objectn");
}
//Open the SQL Server connection
hr = pConnection->Open(strCon, "", "", 0);
if (FAILED(hr))
{
printf("Error Opening Database object using ADO _ConnectionPtr n");
}
For a web application, in the msi installer, I used a custom dll and trying the following C++ code to enable 32-bit application on win64 for an application pool, the hr result shows success but still the Enable32BitAppOnWin64 is false for the application pool. pSiteElem is IAppHostElement type and already validated by getting the name of the application pool successfully.
VARIANT vtEnable32Bit;
vtEnable32Bit.vt = VT_BOOL;
vtEnable32Bit.boolVal = true;
hr = pSiteElem->SetMetadata(L"Enable32BitAppOnWin64", vtEnable32Bit);
if(FAILED(hr))
{
MessageBox(NULL, L"Enable32BitAppOnWin64: ",L"FAILED", MB_OK);
}
else
{
MessageBox(NULL, L"Enable32BitAppOnWin64: ",L"success", MB_OK);
}
I'm working on a project that needs to install a series of Windows Task Scheduler tasks and for that I created a Wix project and a Custom Action that takes care of all the details. That Custom Action was created using C++ to avoid dependencies on the .NET Framework.
At first I started executing SCHTASKS.EXE from a Wix custom action but, after I managed to create the correct command line to install a task correctly, I realized I couldn't set the Action's Working Directory ('Start in' in the Task Scheduler UI) from the SCHTASKS.EXE command line, because it simply didn't have the option...
I decided then to use COM in C++ (#import <taskschd.dll> raw_interfaces_only) to get to the Task Scheduler and tweak the WorkingFolder using the API after installing the Task using SCHTASKS.EXE which was working fine besides that detail.
I managed to get to the task and read its values after installing the task correctly but when I executed put_WorkingDirectory method with the current value that didn't fail actually, but the value wasn't saved into the task.
Does anyone have a clue why I couldn't get there? This is part of the code I used to get to the ExecAction and set the value successfully. Remember this is within a Wix Custom action so some of the methods calls are Wix's.
This code is actually working and the log shows the correct path I intend to set, but the task doesn't get changed. What am I doing wrong?
HRESULT UpdateWorkingDirectory(TaskScheduler::ITaskFolderPtr rootFolder, BSTR taskName, BSTR installFolder)
{
HRESULT hr = S_OK;
TaskScheduler::IRegisteredTaskCollectionPtr taskCollection;
LONG numTasks = 0;
TaskScheduler::IRegisteredTaskPtr thisTask;
TaskScheduler::ITaskDefinitionPtr definition;
TaskScheduler::IActionCollectionPtr actions;
TaskScheduler::IActionPtr action;
TaskScheduler::IExecActionPtr execAction;
long actionCount;
hr = rootFolder->GetTasks(NULL, &taskCollection);
ExitOnFailure(hr, "Cannot get task collection pointer");
hr = taskCollection->get_Count(&numTasks);
ExitOnFailure(hr, "Cannot get task collection item count");
for (LONG taskIdx = 0; taskIdx < numTasks; taskIdx++) {
TaskScheduler::IRegisteredTaskPtr registeredTask;
bstr_t taskIdxName;
hr = taskCollection->get_Item(variant_t(taskIdx + 1), ®isteredTask);
ExitOnFailure(hr, "Cannot get task item %d", taskIdx + 1);
hr = registeredTask->get_Name(&taskIdxName.GetBSTR());
ExitOnFailure(hr, "Cannot get task name");
WcaLog(LOGMSG_STANDARD, " registered task name = %s", (LPCSTR)taskIdxName);
if (strcmp(bstr_t(taskName), taskIdxName) == 0) {
thisTask = registeredTask;
break;
}
}
if (thisTask == NULL) {
hr = E_FAIL;
ExitOnFailure(hr, "task {%S} not found", taskName);
}
hr = thisTask->get_Definition(&definition);
ExitOnFailure(hr, "error getting task definition for {%S}", taskName);
hr = definition->get_Actions(&actions);
ExitOnFailure(hr, "error getting actions for {%S}", taskName);
WcaLog(LOGMSG_STANDARD, " got actions from %S", taskName);
hr = actions->get_Count(&actionCount);
ExitOnFailure(hr, "error getting action count for {%S}", taskName);
WcaLog(LOGMSG_STANDARD, " got count = %d from {%S}", actionCount, taskName);
if (actionCount > 0) {
bstr_t actionId;
bstr_t arguments;
bstr_t path;
hr = actions->get_Item(1, &action);
ExitOnFailure(hr, "error getting action[1] for {%S}", taskName);
hr = action->QueryInterface(&execAction);
ExitOnFailure(hr, "error getting ExecAction for {%S}", taskName);
hr = execAction->get_Id(&actionId.GetBSTR());
ExitOnFailure(hr, "error getting Exec Action id for first exec action of {%S}", taskName);
WcaLog(LOGMSG_STANDARD, " first Exec Action Id is %s", (LPCSTR)actionId);
hr = execAction->get_Arguments(&arguments.GetBSTR());
ExitOnFailure(hr, "error getting Exec Action arguments for first exec action of {%S}", taskName);
WcaLog(LOGMSG_STANDARD, " first Exec Action arguments are %s", (LPCSTR)arguments);
hr = execAction->get_Path(&path.GetBSTR());
ExitOnFailure(hr, "error getting Exec Action path for first exec action of {%S}", taskName);
WcaLog(LOGMSG_STANDARD, " first Exec Action path is %s", (LPCSTR)path);
hr = execAction->put_WorkingDirectory(installFolder);
ExitOnFailure(hr, "error putting working directory for {%S}", taskName);
WcaLog(LOGMSG_STANDARD, " successful put working directory to %S", installFolder);
}
LExit:
return hr;
}
NOTE: All C++ samples I found used simple interface pointers instead of smart pointers, I preferred smart pointers to avoid taking care of release by myself
It seems to me that this is a good example:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa446854(v=vs.85).aspx
More specifically, it shows that you call ITask::Activate before changing things like the working directory, and that you call IPersistFile to save the changes. I can't see any of these in that posted code sample. I've not looked at these interfaces for a while, but that might be the issue.
I found the answer
I had to change my method signature to accommodate username and password
HRESULT UpdateWorkingDirectory(TaskScheduler::ITaskFolderPtr rootFolder, BSTR taskName, BSTR installFolder, variant_t username, variant_t password)
and add these five lines
thisTask = NULL;
hr = rootFolder->RegisterTaskDefinition(taskName, definition, TaskScheduler::_TASK_CREATION::TASK_UPDATE, username, password, TaskScheduler::_TASK_LOGON_TYPE::TASK_LOGON_PASSWORD, variant_t(), &thisTask);
ExitOnFailure(hr, "error updating task regisration for {%S}", taskName);
WcaLog(LOGMSG_STANDARD, " successful update of task regisration to %S", taskName);
after executing put_WorkingDirectory.
This updates the registration of the task definition with the updated value, that was what I wanted to do, and it worked!!!!
I'm tryind to run HttpCalculatorServiceExample located in MSDN. Function WsOpenServiceHost returns error code 0x803d0021. This error means
MessageId: WS_E_OTHER
Unrecognized error occurred in the Windows Web Services framework.
Printed error:
Unable to add URL to HTTP URL group.
Unrecognized error occurred in the Windows Web Services framework.
The process cannot access the file because it is being used by another process.
How to solve this problem?
int __cdecl wmain(int argc, __in_ecount(argc) wchar_t **argv)
{
UNREFERENCED_PARAMETER(argc);
UNREFERENCED_PARAMETER(argv);
HRESULT hr = NOERROR;
WS_SERVICE_HOST* host = NULL;
WS_SERVICE_ENDPOINT serviceEndpoint = {};
const WS_SERVICE_ENDPOINT* serviceEndpoints[1];
serviceEndpoints[0] = &serviceEndpoint;
WS_ERROR* error = NULL;
WS_SERVICE_ENDPOINT_PROPERTY serviceEndpointProperties[1];
WS_SERVICE_PROPERTY_CLOSE_CALLBACK closeCallbackProperty = {CloseChannelCallback};
serviceEndpointProperties[0].id = WS_SERVICE_ENDPOINT_PROPERTY_CLOSE_CHANNEL_CALLBACK;
serviceEndpointProperties[0].value = &closeCallbackProperty;
serviceEndpointProperties[0].valueSize = sizeof(closeCallbackProperty);
// Initialize service endpoint
serviceEndpoint.address.url.chars = L"http://+:80/example"; // address given as uri
serviceEndpoint.address.url.length = (ULONG)wcslen(serviceEndpoint.address.url.chars);
serviceEndpoint.channelBinding = WS_HTTP_CHANNEL_BINDING; // channel binding for the endpoint
serviceEndpoint.channelType = WS_CHANNEL_TYPE_REPLY; // the channel type
serviceEndpoint.contract = &calculatorContract; // the contract
serviceEndpoint.properties = serviceEndpointProperties;
serviceEndpoint.propertyCount = WsCountOf(serviceEndpointProperties);
// Create an error object for storing rich error information
hr = WsCreateError(
NULL,
0,
&error);
if (FAILED(hr))
{
goto Exit;
}
// Create Event object for closing the server
closeServer = CreateEvent(
NULL,
TRUE,
FALSE,
NULL);
if (closeServer == NULL)
{
hr = HRESULT_FROM_WIN32(GetLastError());
goto Exit;
}
// Creating a service host
hr = WsCreateServiceHost(
serviceEndpoints,
1,
NULL,
0,
&host,
error);
if (FAILED(hr))
{
goto Exit;
}
// WsOpenServiceHost to start the listeners in the service host
hr = WsOpenServiceHost(
host,
NULL,
error);
if (FAILED(hr))
{
goto Exit;
}
WaitForSingleObject(closeServer, INFINITE);
// Close the service host
hr = WsCloseServiceHost(host, NULL, error);
if (FAILED(hr))
{
goto Exit;
}
Exit:
if (FAILED(hr))
{
// Print out the error
PrintError(hr, error);
}
fflush(
stdout);
if (host != NULL)
{
WsFreeServiceHost(host);
}
if (error != NULL)
{
WsFreeError(error);
}
if (closeServer != NULL)
{
CloseHandle(closeServer);
}
fflush(stdout);
return SUCCEEDED(hr) ? 0 : -1;
}
I had the same error "Unrecognized error occurred in the Windows Web Services framework", while tried to debug remote target (C++ project).
I've tried all possible solutions, which I've found over internet: turn-off/uninstall antivirus(I use MS Essentials), turnoff firewall, reinstall VS etc.
But it didn't help.
So, I've deleted all programms (not windows updates) which I've installed last month, reboot computer, and the bug went away.
Uninstalled software:
Foxit PhantomPDF Standard. Версия: 7.0.5.1021.
widecap
CCleaner
Uninstall Tool
just in case, I've also uninstalled Microsoft Security Essentials and after the bug went away I've installed it again and had no problems.
Hope, this helps
Hi
I have legacy ActiveX (ATL), that works properly if loaded from the Trusted Sites security zone.
I want to add verification in code, the be sure that customer added the host of activeX to the trusted sites and if not just give a warning.
What API should I use ? (browser is IE7 and UP).
Thank you
You can map an url to a zone in native code using IInternetSecurityManager::MapUrlToZone.
The sample code from MSDN:
const char* rgZoneNames[] = { "Local", "Intranet", "Trusted", "Internet", "Restricted" };
IInternetSecurityManager* pInetSecMgr;
HRESULT hr = CoCreateInstance(CLSID_InternetSecurityManager, NULL, CLSCTX_ALL,
IID_IInternetSecurityManager, (void **)&pInetSecMgr);
if (SUCCEEDED(hr))
{
DWORD dwZone;
hr = spInetSecMgr->MapUrlToZone(szUrl, &dwZone, 0);
if (hr == S_OK) {
if (dwZone < 5) {
printf("ZONE: %s (%d)\n", rgZoneNames[dwZone], dwZone);
} else {
printf("ZONE: Unknown (%d)\n", dwZone);
}
} else {
printf("ZONE: Error %08x\n", hr);
}
pInetSecMgr->Release();
}