|
You've pretty much nailed it, but I have done some tidying up and fixed a couple of minor issues in the code as follows:
WCHAR* CA_Registry::_get_SQLServer_InstalledInstances( void )
{
HKEY keyHandle;
WCHAR rgValue[1024];
WCHAR* regPath = L"SOFTWARE\\Microsoft\\Microsoft SQL Server\\";
WCHAR* regReq = L"InstalledInstances";
DWORD size1 = sizeof(rgValue);
DWORD dwType;
DWORD regStatus;
int ndx;
WCHAR *szReturnValue = NULL;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regPath, 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) {
regStatus = RegQueryValueEx( keyHandle, regReq, NULL, &dwType, (LPBYTE)rgValue, &size1);
RegCloseKey(keyHandle); switch ( regStatus ) {
case ERROR_SUCCESS:
{
WCHAR* pszString = rgValue;
while (*pszString)
{
ndx = wcslen(pszString);
pszString += ndx;
if (pszString[1] != L'\0')
*pszString++ = L';'; }
}
ndx = wcslen(rgValue); wprintf(L" SQL Server Instance: %s %i\n", rgValue, ndx);
szReturnValue = new wchar_t[ndx + 1]; wcscpy_s(szReturnValue, ndx + 1, rgValue);
break;
case ERROR_MORE_DATA:
cout << "Buffer too small\n";
break;
default:
cout << "Could not read key\n";
}
}
else {
cout << "Can not open key";
cin.ignore();
}
return szReturnValue; }
I hope my comments make sense but please let me know if they don't. I have built and tested this code but I do not have the exact content of the registry value so it may need some minor tweaking.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I had to read it a couple of times before it soaked in, those are huge refinements, but I get it, way more optimized, and it teaches me that alot of the stuff was not needed. Let me make the mods, and I will alter the other registry function I have as well. I didn't know I had to wprintf, I thought it was just for printing to the screen in console.
Thanks
|
|
|
|
|
Works like a charm, I had to move the pszString above the switch because the compiler complained. I changed the function by hand, and only copied the ERROR_Success because it was alot to type. So I have to delete somthing in the calling function, not sure what yet.
WCHAR* CA_Registry::_get_SQLServer_InstalledInstances( void )
{
HKEY keyHandle;
WCHAR rgValue[1024];
WCHAR *regPath = L"SOFTWARE\\Microsoft\\Microsoft SQL Server\\";
WCHAR *regReq = L"InstalledInstances";
DWORD size1 = sizeof(rgValue);
DWORD dwType;
DWORD regStatus;
int ndx;
WCHAR* pszString = rgValue;
WCHAR *szReturnValue = NULL;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, regPath, 0, KEY_QUERY_VALUE, &keyHandle) == ERROR_SUCCESS) {
regStatus = RegQueryValueEx( keyHandle, regReq, NULL, &dwType, (LPBYTE)rgValue, &size1);
RegCloseKey(keyHandle);
switch ( regStatus ) {
case ERROR_SUCCESS:
{
while (*pszString)
{
ndx = wcslen(pszString);
pszString += ndx;
if (pszString[1] != L'\0')
*pszString++ = L';';
}
}
ndx = wcslen(rgValue);
wprintf(L" SQL Server Instance: %s %i\n", rgValue, ndx);
szReturnValue = new wchar_t[ndx + 1];
wcscpy_s(szReturnValue, ndx + 1, rgValue);
break;
case ERROR_MORE_DATA:
cout << "Buffer too small\n";
break;
default:
cout << "Count not read key\n";
}
}
else {
cout << "Can not open key";
cin.ignore();
}
return szReturnValue;
}
This is the calling function just for reference, I wrote it from scratch, no help, lot cleaner than the registry functions I wrote. It's a rough draft, needs more detail, but in the end, after searching by wire, then search the local machine registry, if nothing is found, I will ask if they want to download the X86 or X64 version, and install it using an automated script that I write on the fly. It's starting to shape up now.
BOOL CA_SQLServer_Scan::_scan_Enumerate_Registry( HWND txtProgress, HWND lblServers, HWND pbProgress )
{
CA_Registry caReg;
BOOL bResult = FALSE;
BOOL bInstance = FALSE;
int instanceLength;
WCHAR *szComputerName = NULL;
WCHAR *szInstanceNames = NULL;
WCHAR *szCurrentVersion = NULL;
WCHAR szServerInstance[125];
szComputerName = caReg._get_ComputerName();
szInstanceNames = caReg._get_SQLServer_InstalledInstances();
instanceLength = wcslen(szInstanceNames);
if (instanceLength > 0) {
WCHAR *szInstanceName = NULL;
WCHAR *token1, *nextToken;
WCHAR seps[] = L";";
WCHAR vSeps[] = L".";
token1 = wcstok_s(szInstanceNames, seps, &nextToken);
do {
if (token1 == NULL) {
break;
}
else {
szInstanceName = token1;
szCurrentVersion = caReg._get_SQLServer_Version(szInstanceName);
int szVerValue = wcslen(szCurrentVersion);
if ( szVerValue > 1 ) {
WCHAR *szVerMajor = NULL, *szVerMinor = NULL, *szVerBuild = NULL;
WCHAR *vToken1, *vToken2, *vToken3, *vNextToken;
int iVerMajor=0, iVerMinor=0, iVerBuild=0;
vToken1 = wcstok_s(szCurrentVersion, vSeps, &vNextToken);
if (!vToken1 == NULL) {
szVerMajor = vToken1;
iVerMajor = _wtoi(szVerMajor);
}
vToken2 = wcstok_s(NULL, vSeps, &vNextToken);
if (!vToken2 == NULL) {
szVerMinor = vToken2;
iVerMinor = _wtoi(szVerMinor);
}
vToken3 = wcstok_s(NULL, vSeps, &vNextToken);
if (!vToken3 == NULL) {
szVerBuild = vToken3;
iVerBuild = _wtoi(szVerBuild);
}
WCHAR pbMessage[80];
wcsncpy_s(pbMessage, _countof(pbMessage), L"Registered: ", wcslen(L"Registered: "));
wcsncat_s(pbMessage, _countof(pbMessage), L"\\", wcslen(L"\\"));
wcsncat_s(pbMessage, _countof(pbMessage), szInstanceName, wcslen(szInstanceName));
SetWindowText(txtProgress, pbMessage);
Sleep(500);
switch (iVerMajor)
{
case 11:
bInstance = TRUE;
break;
case 10:
bInstance = TRUE;
break;
case 9:
bInstance = TRUE;
break;
default:
bInstance = FALSE;
break;
}
if (bInstance) {
int iComputerName = wcslen(szComputerName);
int iInstanceName = wcslen(szInstanceName);
wcsncpy_s(szServerInstance, _countof(szServerInstance), szComputerName, iComputerName);
wcsncat_s(szServerInstance, _countof(szServerInstance), L"\\", wcslen(L"\\"));
wcsncat_s(szServerInstance, _countof(szServerInstance), szInstanceName, iInstanceName);
iInstanceName=wcslen(szServerInstance);
szServerInstance[iInstanceName-0]=(WCHAR)L'\0';
int iCollectionCount;
iCollectionCount = sqlSrvCollection.Count();
if (iCollectionCount > 0) {
WCHAR *szComparision = NULL;
for (int i=0; i<iCollectionCount; i++) {
szComparision = sqlSrvCollection[i];
if (wcscmp(szServerInstance, szComparision) != 0) {
int iCollection = sqlSrvCollection.Add();
sqlSrvCollection[iCollection] = szServerInstance;
}
}
}
else {
int iCollection = sqlSrvCollection.Add();
sqlSrvCollection[iCollection] = szServerInstance;
}
}
}
token1 = wcstok_s(NULL, seps, &nextToken);
}
} while (TRUE);
}
return bResult;
}
|
|
|
|
|
jkirkerx wrote: I had to move the pszString above the switch because the compiler complained.
Must be a different version than mine. In that case you can delete the extra set of curly braces around the while() loop under case ERROR_SUCCESS: . Looking at the other code you posted I think you are well in control now, you have obviously worked hard on this - time for some R&R on the beach. Good luck.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Well Thanks, I rewrote all my project code last night, and fixed everything in all my modules. I'm determined to get this program out there, so I can start getting people to use my other programs.
I still have the socket issue to fix, and the safe array with comm pointer. I will post those today.
I'll take this afternoon off and hit the sand when it warms up a little, it's 60F outside now.
jkirkerx
|
|
|
|
|
jkirkerx wrote: I'm determined to get this program out there
You must be getting close now.
jkirkerx wrote: socket issue ... and the safe array
I should think with what you have learned recently these will (should) be that much simpler.
jkirkerx wrote: it's 60F outside now.
Well the sun has just gone down here and it's about the same. Unseasonably mild for October in the UK.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I'd appreciate it if you mark my last post as Good (or Bad) answer, depending on your viewpoint.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
I am developing a ham radio logging program and using registry ( my first usage of registry) to save configuration values.
The application is based on SDI MFC document / view architecture..
The âdocumentâ (in CDocument) is a CString extracted from user's entry in CFormView.
For this document to be valid an additional âconfigurationâ data are required before the user enters any data into simple CEdit box.
The configuration data are stored in registry and than copied ( on each new start of application) to CDocument and displayed in the CFormView and in configuration ( modal) dialogs as required.
At present I am using SDI , however, would like to be able to add another views in future âimprovementsâ.
Since this is my first usage of registry I would like to hear from anybody if this approach is feasible.
Somehow I feel it is a little too complicated.
As always, thanks for reading.
Vaclav
|
|
|
|
|
It's not really that hard once you do it a few times, so it's very feasible... but if there are other options, for example, you can have a file store the configuration. This gives you the added advantage to make it easy for the user to "share" his configuration (since they can just copy the file) and if you make it plain text (which is the best option, as opposed to writing file out in binary), then they can also edit it outside of the program.
Advantage of using the registry is that it doesn't matter where the executable is, it will always find the registry keys. So if the user decides to move the executable (on purpose or by accident), then their settings will still work.
|
|
|
|
|
Hello everybody,
i am trying to create a text file and trying to write something. my problem is with the file name.
FILE *fp;
fp = fopen("c:\test_1/2.txt,"wb");
this special character "/" is not accepting and fp is returning null, and it crashes the system if i try to write something in fp.
i need to keep the file name as like this only.
is there anyway to solve this issue?
Thanks in advance.
A. Gopinath.
|
|
|
|
|
if that is a file named test_1/2.txt (and not file 2.txt in some test_1 folder) then the filename IS invalid. You'll have to choose a different name for your file. See here[^].
|
|
|
|
|
tagopi wrote: is there anyway to solve this issue?
yeah, don't call fwrite if your fp is NULL.
|
|
|
|
|
tagopi wrote: is there anyway to solve this issue?
Seeing as how that file cannot be created outside of code (e.g., right-click desktop, new text document, type name), I doubt it.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
I think everyone here missed the real issue here.
"c:\test_1/2.txt"
There is a \t in the filename, which is converted to a tab character by the compiler. The file path getting passed into fopen is "c: est_1/2.txt"
You need to escape this backslash with another backslash, so your filename becomes "c:\\test_1/2.txt".
as for the forward slash, windows will interpret this as a path slash too, but you don't need to escape it because the compiler wont change it.
So, the path you are accessing is C: > test_1 > 2.txt
Additionally, fopen will not create the folder "test_1" if it does not exist, it will just fail to open it and return NULL.
|
|
|
|
|
That however wouldn't cause a crash.
Whereas not testing the return value of the method probably does.
|
|
|
|
|
OK, you are correct. The return value should always be checked for success, but if the filename was valid (and this is where the real issue is) the OP probably would have never noticed that, because it wouldn't be returning NULL.
|
|
|
|
|
Hi,
You are not able to create file name having special characters like "/,\,*" etc. If you want to confirm, just go on your desktop and try to create file having name "test_1/2", OS will not even allow to type '/' in file name.
Happy Programming.
Regards
|
|
|
|
|
Thanks everybody for your replies.
will give a try to replace "/" with some other.
Thanks again.
A. Gopinath.
|
|
|
|
|
If any folder is open in window explorer then how to refresh its contents.
Say c:/xyz is open, it contains some files and folders, i want to progratically refresh the children.
|
|
|
|
|
Are you working on mfc?? if yes then, i think you can just redraw whatever it is that you want on the screen.
Every new day is another chance to change your life.
|
|
|
|
|
How exactly do you mean "programmatically"? With an external program or an explorer addin?
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
My program hides a file say from c: drive. If window explorer is open (c drive) i found file still display. If i refresh window explorer manually then file disappear.
|
|
|
|
|
Here you go.
HWND hExplorer = FindWindowEx(GetDesktopWindow(), NULL, L"ExploreWClass", NULL);
while(hExplorer != NULL)
{
EnumChildWindows(hExplorer, RefreshFolderSelectionCB, (LPARAM)&packet);
hExplorer = FindWindowEx(GetDesktopWindow(), hExplorer, L"ExploreWClass", NULL);
}
...
...
...
BOOL CALLBACK RefreshFolderSelectionCB(HWND hWnd, LPARAM lParam)
{
WCHAR sBuffer[MAX_PATH] = {0};
::GetClassName(hWnd, sBuffer, MAX_PATH);
if (wcscmp(L"SysTreeView32", sBuffer) == 0)
{
RefreshFolderSelectionPacket* pPacket = (RefreshFolderSelectionPacket*)lParam;
RefreshSelection(pPacket);
}
return TRUE;
}
...
...
static void UpdateItem(IShellFolder* pDesktop, const std::wstring& rsFullPath)
{
PIDLIST_RELATIVE pIDL;
if (SUCCEEDED(pDesktop->ParseDisplayName(NULL, NULL, (LPWSTR)rsFullPath.c_str(), NULL, &pIDL, NULL)))
{
SHChangeNotify(SHCNE_UPDATEITEM, SHCNF_IDLIST|SHCNF_NOTIFYRECURSIVE|SHCNF_FLUSH, pIDL, NULL);
ILFree(pIDL);
}
}
|
|
|
|
|
http://social.msdn.microsoft.com/Forums/en/windowssdk/thread/cc4a702f-1b2f-4d19-bf68-c88967544172[^]
Where do RefreshFolderSelectionPacket and RefreshSelection() come from?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
uh huh, I ripped that code from there
|
|
|
|
|