PDAclub.pl - Forum użytkowników technologii mobilnych
Windows Mobile (Classic, Professional, Standard), Windows Phone 6.x oraz 7/8.x/10 => Oprogramowanie PPC => Dla programistów => Wątek zaczęty przez: makler2006 w Luty 13, 2006, 14:00:55
-
Witam!
Czy ktoś może mi powiedzieć jak odczytać stringa z rejestru? Zrobiłem funkcję, która ma to realizować, kompiluje sie ale sie wywala. Funkcja jest typu char i w return ma zwracać tego stringa. Wiem, że przy odczycie należy dwa razy wywołać "RegQueryValueEx" jeden raz dla rozmiaru a kolejny dla pobrania samego stringa. Poniżej jest mój kod, co jest źle? Wielkie dzięki za pomoc!
char ReadStringRegistryKey(LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hKey;
TCHAR szData[200];
DWORD dwType = REG_SZ, dwSize = sizeof(TCHAR)*200, dwDisp = 0;
DWORD dwRet = -1;
DWORD dwDataSize = 0;
LONG res = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey);
if (ERROR_SUCCESS != res)
{
return FALSE;
}
if (RegQueryValueEx( hKey, lpValueName, 0, &dwType, (PBYTE)NULL, &dwDataSize ) == ERROR_SUCCESS)
{
RegQueryValueEx( hKey, lpValueName, 0, &dwType, (PBYTE)(LPTSTR)dwSize, &dwDataSize );
RegCloseKey(hKey);
}
// RegCloseKey(hKey);
return dwSize;
}
-
Po pierwsze zdecyduj sie co funkcja ma zwracac, bo
a. w deklaracji char
b. w ciele return FALSE
c. a pozniej return dwSize
po drugie w linii
RegQueryValueEx( hKey, lpValueName, 0, &dwType, (PBYTE)(LPTSTR)dwSize, &dwDataSize );
Nastepuje przypisanie zawartosci rejestrow (napisu) do adresu, sizeof(TCHAR)*200 czyli do adresu 400 !!!!!. To chyba nie jest obszar RAM. Kompilator pewnie wypisywal 100 bledow, ze zle typy, ale w koncu tym rzutowaniem go udobruchales. Zamiast tego co tam wpisales, uzyj zmiennej szData, ktora pewnie do tego zadeklarowales.
Po trzecie, sadzac po nazwie funkcji, pewnie chcialbys uzyc zawartosci odczytanej z rejestrow na zewnatrz funkcji. Czas zycia zmiennej szData konczy sie w momencie zakonczenia funkcji wiec nie mozesz jej uzyc do tego celu. Pozostaje dodanie dodatkowego parametru do funkcji lub zadeklarowanie zmiennej szdata jako static.
Zycze wielu wzruszen i pozdrawiam
-
Przerobiłe to na taką funkcję, ale nadal nie działa.
PS: Faktycznie chciałbym mieć możliwość wyciągnięcia na zewnątrz z tej funkcji zwracany string. Niestety debuger mi nie działa i nie mam zabardzo jak tego zdiagnozować. Czy wie ktoś co jest jeszcze źle?
char ReadStringRegistryKey(LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hKey;
static TCHAR szData[200];
DWORD dwType = REG_SZ;
DWORD dwDataSize = 0;
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &hKey)==ERROR_SUCCESS)
{
if (RegQueryValueEx( hKey, lpValueName, 0, &dwType, (PBYTE)NULL, &dwDataSize ) == ERROR_SUCCESS)
{
RegQueryValueEx( hKey, lpValueName, 0, &dwType, (PBYTE)(PTSTR)szData, &dwDataSize );
RegCloseKey(hKey);
}
}
// RegCloseKey(hKey);
return (TCHAR)szData;
}
-
Zrobiłe to również tak, ale też nie działa, co jest źle? Czy ktoś wie? Jest mi to bardzo potrzebne. Za pomoc bardzo dziękuję!
char ReadStringRegistryKey(LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY klucz;
DWORD Typ = REG_SZ;
char zwracana_wartosc_klucza[255];
//otwieramy klucz i jeśli istnieje przeprowadzamy operacje
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &klucz) == ERROR_SUCCESS)
{
//deklaracja zmiennej na wartość typu string
static char wartosc_klucza[255];
//deklaracja zmiennej na wartość liczbową
int wartosc_klucza2;
//definiujemy zmienną z wielkością bufora tekstowego
unsigned long wartosc_klucza_len = sizeof(wartosc_klucza);
//odczytujemy string
RegQueryValueEx(klucz, lpValueName, 0,&Typ,(unsigned char*) wartosc_klucza, &wartosc_klucza_len);
zwracana_wartosc_klucza[255]=wartosc_klucza[255];
//zamykamy klucz bo już z niego nie korzystamy
RegCloseKey(klucz);
}
return zwracana_wartosc_klucza[255];
}
-
Jesli nie masz debug-a, to skad wiesz, ze to ci akurat nie dziala??? Dodaj w takim razie jakies messageboxy pomiedzy kolejnymi liniami , zeby sprawdzic, co ci faktycznie nie dziala.
-
Wiem bo używam wywołania tej funkcji w C# przez P/Invoke i przypisuje ją do pola: this.textBox9.Text = ReadStringRegistryKey("Software\\Test", "Nazwa").ToString();
I jak włączam program (ten w C#) to sie wysypuje z komentarzem Nie oczekiwany błąd : NotSupportedException,
Przypisanie jest chyba prawidłowe w /Invoke funkcja wygląda tak:
[DllImport("library.dll")]
static extern string ReadStringRegistryKey(string lpSubKey, string lpValueName);
A nie mogę Debugować bo eVC i Visual Studio 2003 .NET nie stabilizują mi połączenia z Pocketem.
Dodam, iż zapis tego stringa do rejestru odbywał się za pomocą poniższej funkcji (i jak sprawdzam w regEdytorze to wpis istnieje i jest prawidłowy):
int WriteStringRegistryKey(LPCTSTR lpSubKey, LPCTSTR lpValueName, const unsigned char* lpData, DWORD dwSize)
{
HKEY hKey;
DWORD dwType = REG_SZ, dwDisp = 0;
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, NULL,
0, KEY_WRITE, NULL, &hKey, &dwDisp) == 0)
{
if (RegSetValueEx(hKey, lpValueName, 0, dwType, lpData, dwSize) == 0)
{
RegCloseKey(hKey);
return 0;
}
RegCloseKey(hKey);
}
RegCloseKey(hKey);
return -1;
}
Ale funkcja pobierająca ten wpis, o której cały czas mowa, nie pobiera go prawidłowo. Czy wiesz może jak naprawić tę funkcję tak aby zwracała faktycznie tego stringa??
-
A funkcja ma zwracac unicode czy ascii ?
Z deklaracji funkcji wynika ze ascii, a z deklaracji zmiennej szData, ze unicode.
Nie znam VS net, ale czy zapis ("Software\\Test", "Nazwa") powoduje przekazanie parametrow jako unicode czy jako ascii ?
Bardzo zakrecony ten Twoj program.
A w ogole, czy trzeba mieszac kod net i evc po to by pobrac i zapisac rejestry ?
Sprobuj to zadanie rozebrac na mniejsze czesci tzn. nie pobieraj wartosc z rejestrow tylko przypisz na stale cos do szData po to by sprawdzic czy problem przypadkiem nie lezy w samym wywolaniu i przekazywaniu wyniku pomiedzy evc a net.
Nastepnie sprobuj dodac pomiedzy kolejnymi liniami msgboxy, zeby zobaczyc w czym naprawde jest problem
-
Ma być Unicode.
"ale czy zapis ("Software\\Test", "Nazwa") powoduje przekazanie parametrow jako unicode czy jako ascii ? "
to są zwykłe stringi, przekazuje je jako text i z nimi jest wszystko OK, przekazuje je prawidłowo.
Ok, spróbuję.
-
Zrobiłem mały programik na Pocketa, który ma pokazać komunikat z treścią o zwracanym stringu, w miejscy gdzie ma wyświetlić stringa zwracanego przez tę funkcję - nie wyświetla nic, nawet kwadracików.
Oto ten program:
#include <stdlib.h>
#include <shellapi.h>
#include <winioctl.h > // need for Hard reset function
#include <sip.h> // need for word completion
#include <aygshell.h> // need for ShSipInfo
#include <stdio.h> // for strlen function
#include "stdafx.h"
char ReadStringRegistryKey(LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY klucz;
DWORD Typ = REG_SZ;
char zwracana_wartosc_klucza[255];
//otwieramy klucz i jeśli istnieje przeprowadzamy operacje
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &klucz) == ERROR_SUCCESS)
{
//deklaracja zmiennej na wartość typu string
static char wartosc_klucza[255];
//deklaracja zmiennej na wartość liczbową
int wartosc_klucza2;
//definiujemy zmienną z wielkością bufora tekstowego
unsigned long wartosc_klucza_len = sizeof(wartosc_klucza);
//odczytujemy string
RegQueryValueEx(klucz, lpValueName, 0,&Typ,(unsigned char*) wartosc_klucza, &wartosc_klucza_len);
zwracana_wartosc_klucza[255]=wartosc_klucza[255];
//zamykamy klucz bo już z niego nie korzystamy
RegCloseKey(klucz);
}
return zwracana_wartosc_klucza[255];
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd = FindWindow(NULL, TEXT("Nazwa_programu"));
if (hWnd == NULL)
{
return E_FAIL;
}
LPCTSTR regValue;
regValue = (LPCTSTR)ReadStringRegistryKey(TEXT("Software\\Test"), TEXT("Nazwa"));
MessageBox(hWnd, regValue, TEXT("Info"), MB_OK);
// TODO: Place code here.
return 0;
}
-
Wydaje mi się, że funkcja sie kaszani podczas jednej z konwersji typów, ale nie wiem dokładnie podczas której.
-
A moim zdaniem program konczy sie tutaj :).
Moze troche spokojniej...
-
"A moim zdaniem program konczy sie tutaj Smile.
Moze troche spokojniej..."
Co masz na myśli jak mogę zapytać? Fakt ten kod nie jest wielki bo ma tylko pobraćinformację z funkcji i wyświetlić jąw message boxie.
a text: "nazwa_programu" to nazwa okna programu, bo ten message box podpina się pod byle co co jest w procesach, zresztą napewno to wiesz, więc sorki :)
Chodzi o to, że już kolejny dzień ślęczę nad tą funkcją, przetrzepałem całego neta i wszystko jest na jedno kopyto, nie znalazłem żadnej gotowej funkcji, która zwraca tego stringa z rejestru poprzez return tak aby można było go używać poza ciałem funkcji. Ta funkcja trzyma cały mój projekt i muszę ją jakoś pogonić. Jak możesz to bardzo proszę Cię o pomoc. Defakto rzadko piszę coś na tym forum, bo rzadko mam z czyś powazne problemy, albo sie po kilkunastu godzinach je rozwiązuje, ale jak już są to trzeba się poradzić, a z tym mam spory problem. Dlatego zapytam, czy jesteś wstanie poprawić mi tę funkcję tak aby zwracała prawidłowo ten parametr? Cały czas nad tym ślęczę i dedukuje i już mam dołek.
Raz jeszcze dzięki, ze się zainteresowałeś moim problemem i starasz się mi pomóc.
-
"A moim zdaniem program konczy sie tutaj Smile.
Moze troche spokojniej..."
Co masz na myśli jak mogę zapytać? Fakt ten kod nie jest wielki bo ma tylko pobraćinformację z funkcji i wyświetlić jąw message boxie.
a text: "nazwa_programu" to nazwa okna programu, bo ten message box podpina się pod byle co co jest w procesach, zresztą napewno to wiesz, więc sorki :)
Chodzi o to, że już kolejny dzień ślęczę nad tą funkcją, przetrzepałem całego neta i wszystko jest na jedno kopyto, nie znalazłem żadnej gotowej funkcji, która zwraca tego stringa z rejestru poprzez return tak aby można było go używać poza ciałem funkcji. Ta funkcja trzyma cały mój projekt i muszę ją jakoś pogonić. Jak możesz to bardzo proszę Cię o pomoc. Defakto rzadko piszę coś na tym forum, bo rzadko mam z czyś powazne problemy, albo sie po kilkunastu godzinach je rozwiązuje, ale jak już są to trzeba się poradzić, a z tym mam spory problem. Dlatego zapytam, czy jesteś wstanie poprawić mi tę funkcję tak aby zwracała prawidłowo ten parametr? Cały czas nad tym ślęczę i dedukuje i już mam dołek.
Raz jeszcze dzięki, ze się zainteresowałeś moim problemem i starasz się mi pomóc.
-
Jestem już blisko, ta funkcja zwraca stringa tylko go jeszcze obcina, pewnie bufor jest za mały.
char * ReadStringRegistryKey(LPCTSTR SubKey, LPCTSTR Name)
{
HKEY hRegistryKeyHandle;
DWORD dKeyValueType = REG_SZ;
// long ulKeyValueLength = ENV_VALUE_BUFFERSIZE;
long lRegOpenStatus = NULL;
char *EnvValue = NULL;
//definiujemy zmienną z wielkością bufora tekstowego
long ulKeyValueLength = sizeof(EnvValue);
// ENV_VALUE_BUFFERSIZE is a constant declared elsewhere in my application
// EnvValue = new char[ENV_VALUE_BUFFERSIZE];
EnvValue = new char[ulKeyValueLength];
if (! EnvValue)
{
// Could not allocate memory for the configuration paramemter.
}
// Replace MYAPP in the following line with whatever path you have for your application
lRegOpenStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,SubKey,NULL,KEY_QUERY_VALUE,&hRegistryKeyHandle);
if((ERROR_SUCCESS == lRegOpenStatus))
{
if((ERROR_SUCCESS == RegQueryValueEx(hRegistryKeyHandle,Name, NULL, &dKeyValueType,(unsigned char *)EnvValue, (unsigned long *)&ulKeyValueLength)))
{
// Queried the value successfully.
}
else
{
// Problem in reading the registry variable.
}
}
else
{
// Your registry variable is not available in this path
}
if (ERROR_SUCCESS == lRegOpenStatus)
RegCloseKey(hRegistryKeyHandle);
return EnvValue;
}
-
Da Da!! A oto sprawna funkcja, która pobiera stringa z wpisu w rejestrze i zwraca go przez return, dzięki czemu, można uzywać tego stringa gdzie sie chce, np. w checkBox'ach.
char * ReadStringRegistryKey(LPCTSTR SubKey, LPCTSTR Name)
{
HKEY hRegistryKeyHandle;
DWORD dKeyValueType = REG_SZ;
long lRegOpenStatus = NULL;
char *EnvValue = NULL;
long ulKeyValueLength = NULL;
long ulKeyValueLength2 = NULL;
lRegOpenStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE,SubKey,NULL,KEY_QUERY_VALUE,&hRegistryKeyHandle);
if((ERROR_SUCCESS == lRegOpenStatus))
{
if((ERROR_SUCCESS == RegQueryValueEx(hRegistryKeyHandle,Name, NULL, &dKeyValueType,(unsigned char *)EnvValue, (unsigned long *)&ulKeyValueLength)))
{
ulKeyValueLength2=ulKeyValueLength;
EnvValue = new char[ulKeyValueLength];
if((ERROR_SUCCESS == RegQueryValueEx(hRegistryKeyHandle,Name, NULL, &dKeyValueType,(unsigned char *)EnvValue, (unsigned long *)&ulKeyValueLength2)))
{
}
}
else
{
}
}
else
{
}
if (ERROR_SUCCESS == lRegOpenStatus)
RegCloseKey(hRegistryKeyHandle);
return EnvValue;
}
-
A oto sprawna funkcja
Jak nie bedziesz o pewnej rzeczy pamiętał, to zabraknie ci pamięci...
-
Co masz na myśli ??
Acha mam pytanko, funkcja w C++ działa ale nie wiem jak typ char * przedefiniować w C#, jak daje jako string w deklaracji funkcji w P/Invoke i potem tej funkcji użyję to program nadal mi sie wywala. Wiesz może jak deklaruje się typ char * w C# ??
-
Co masz na myśli ??
Wywolaj te funkcje w petli 1000 razy a zobaczysz, co PiKNew mial na mysli.
To, ze ten kod dziala, nie oznacza, ze jest ok... bo nie jest.
W c++ mozesz uzyc TEXT("AAA") lub L"AAA" zeby wymusic na kompilatorze uzycie unicode, co do net, to nie wiem.
-
Czy ktoś wie jak prawidłowo wywołać w C# poprzez P/Invoke funkcję C++: char * ReadStringRegistryKey(LPCTSTR SubKey, LPCTSTR Name)
tak aby potem przy przypisaniu:
string zwracana;
zwracana = ReadStringRegistryKey("Software\\Test", "Tekst");
this.textBox1.Text = zwracana.ToString();
Nie wyskakiwał błąd, tylko aby dobrze została zwrócona wartość zwracana przez tę funkcję.
?????????????????