Hej http://www.google.se/search?q=LPCWSTR ;-) Fick inte riktigt ShellExecute att fungera som jag ville så jag kör väl på system ändå (kändes lite onödigt att starta fler processer än nödvändigt). Nu kommer jag fram till nästra problem då. System returnerar ingen "FILENOTFOUND" eller liknande vad jag har förstått det som (den skriver iof ut att filen inte finns, men jag måste få reda på det i koden också). Jag har testat följande kod: Det är för att c_str är en pekare. Du måste antingen kopiera innehållet eller använda string. Fast det borde fungera ändå, eftersom c_str-pekare fortfarande bör fungera. Å andra sidan tilldelar du till en const char, vilket känns lite halvt wacky i det här fallet. Överhuvudtaget skall man inte blanda string och char på det sättet som du gör. Håll dig till string och konvertera till char* så sent som möjligt. Grymt, nu funkar det med koden: Grundprincipen är att du bör låta bli gamla C-grejer. Det som ligger i headerfiler som börjar med "c" är såna.Problem med ShellExecute
Försöker köra ett enkelt Shellexecute-kommando men får det inte att fungera:
HINSTANCE a = ShellExecute(NULL,"open","calc.exe","","", SW_SHOW );
ger felet
error C2664: 'ShellExecuteW' : cannot convert parameter 2 from 'const char [5]' to 'LPCWSTR'
skriver jag
HINSTANCE a = ShellExecute(NULL, (LPCWSTR) "open", (LPCWSTR) "calc.exe","","", SW_SHOW );
blir a==ERROR_FILE_NOT_FOUND
Har testat mängder med olika sätt, filer, sökvägar mm men inget verkar funka. system("start calc.exe") funkar, men jag vill inte använda system...
Någon som har en idé?
Tack!
/FredrikSv: Problem med ShellExecute
Så länge det är hårdkodade strängar kör du bara med
L"open"
istället för
"open"
EDIT:
För övrigt - varför vill du inte använda "system"?
ShellExecute fungerar bara i windows, medan system är någorlunda standard.Sv:Problem med ShellExecute
FILE* fp = NULL;
const char* filename = (clientPackage.getMessage()).c_str();
fp = fopen(filename, "rb");
if( fp != NULL )
{
fclose( fp );
//FILE EXIST
const char* systemMessage = ("start " + clientPackage.getMessage()).c_str();
system (systemMessage);
}else{
//FILE DOESN´T EXIST
cout << "File doesn´t exist" << endl;
}
Där clientPackage.getMessage() returnerar en string innehållande hela sökvägen till filen (ex, "c:\windows\notepad.exe"). Problemet är att fp alltid verkar bli NULL vad jag än anger för sökväg. När jag debugade verkade det som om filename blev "0". Men jag hittar inget fel på
const char* filename = (clientPackage.getMessage()).c_str();
/FredrikSv: Problem med ShellExecute
Sen är frågan varför du kör med fopen istället för fstream?
Det känns som att du gör för mycket på en gång, gör små steg och få varje del att funka först. Lägg en fil i aktuell mapp, kalla den "text.txt", och använd:
fp = fopen("text.txt", "rb");
Om det funkar, testa då med
const char *filename = "text.txt";
fp = fopen(filename, "rb");
Testa sen med
const std::string filename = "text.txt";
fp = fopen(filename.c_str(), "rb");
Och funkar det så kör du med
const std::string filename = clientPackage.getMessage();
fp = fopen(filename.c_str(), "rb");
Och då kan du lika gärna gå över till
fp = fopen(clientPackage.getMessage().c_str(), "rb");
Sen ser den här raden:
const char* systemMessage = ("start " + clientPackage.getMessage()).c_str();
Väldigt fel ut. Använd en vanlig string, och använd c_str() efteråt.Sv:Problem med ShellExecute
c_str() returnerar en temporär pekare som (i teorin) inte gäller längre än till nästa semikolon.
följande kod är alltså "undefined behaviour"
const char* filename = (clientPackage.getMessage()).c_str();
fp = fopen(filename, "rb");
filename kan peka på vad som helst vid anropet av fopen. I praktiken fungerar det dock med de flesta std::string implementationer eftersom c_str där returnerar en pekare till en intern buffert.
Som Niklas skriver lär följande rad inte fungera.
const char* systemMessage = ("start " + clientPackage.getMessage()).c_str();
("start " + clientPackage.getMessage())
skapar en ny temporär sträng som försvinner vid semikolonet. systemMessage pekar alltså på något minne där den temporära strängen låg tidigare. Vad som ligger där när du använder systemMessage är osäkert.Sv: Problem med ShellExecute
FILE* fp = NULL;
string filename = clientPackage.getMessage();
fp = fopen(filename.c_str(), "rb");
if( fp != NULL )
{
fclose( fp );
//FILE EXIST
string systemMessage = "start " + clientPackage.getMessage();
system (systemMessage.c_str());
}else{
//FILE DOESN´T EXIST
cout << "File doesn´t exist" << endl;
}
Det är en viss omställning att gå från java till c++ vill jag säga, lättare när man inte behöver bry sig om annat än String.
Är det bättre att använda fstream istället för fopen, varför?Sv:Problem med ShellExecute
Alltså <cstdlib> <cstdio> osv. är dåliga funktioner, och ersättare finns i C++-versioner. Observera att <cstdlib> osv ibland (felaktigt) skrivs som <stdlib.h>. (Det är korrekt i C men inte i C++).
De tre vanligaste ersättningarna är:
1. char* till string
2. olika filer och i/o till strömmar. cin/cout/fstream istället för scanf, printf, fopen.
3. arrayer till vector:er, (int apa[6] till std::vector<int> apa).
I just det här fallet är ju själva filströmmen tämligen meningslös, så det spelar ingen större roll hur du gör, men det är alltid snyggare att köra med C++-versioner från början.