PDA

View Full Version : [C] avviare un nuovo processo con win7


rab
21-01-2014, 17:05
Buongiorno a tutti :)

il mio problema è il seguente: ho guardato a questo (http://msdn.microsoft.com/en-us/library/windows/desktop/ms682512%28v=vs.85%29.aspx) indirizzo per come creare un nuovo processo in windows usando il C.
Il listato è questo

#include <windows.h>

int main()
{
STARTUPINFO StartupInfo;
PROCESS_INFORMATION ProcessInformation;
ZeroMemory( &StartupInfo, sizeof(StartupInfo) );
StartupInfo.cb = sizeof(StartupInfo);
ZeroMemory( &ProcessInformation, sizeof(ProcessInformation) );
LPWSTR comando = L"del ciao";

CreateProcess
(
NULL,
comando,
NULL,
NULL,
false,
0,
NULL,
NULL,
&StartupInfo,
&ProcessInformation
);

CloseHandle ( ProcessInformation.hProcess );
CloseHandle ( ProcessInformation.hThread );
return 0;
}

il problema è che lanciando questo programma da cmd, quest'ultimo mi dice che l'applicazione ha smesso di funzionare, se avvio un debug con Visual Studio 2012 mi dice che si verifica una violazione d'accesso nel file

Eccezione non gestita in 0x76DCB733 (kernel32.dll) in ConsoleApplication1.exe: 0xC0000005: violazione di accesso durante la scrittura del percorso 0x0115585E.

dove sbaglio?

lorenzo001
21-01-2014, 18:10
Prova a cambiare

LPWSTR comando = L"del ciao";

in

WCHAR comando[] = L"del ciao";

rab
21-01-2014, 19:04
non so come hai fatto però abbiamo risolto il problema, grazie mille! ;)
ora però non mi esegue il comando del (che era quello che mi ero preposto di fare) :eek:
invece se provo i comandi cmd e help funziona (?)

lorenzo001
21-01-2014, 21:59
del è un comando interno dell'interprete DOS e non un eseguibile. E' il cmd.exe che devi lanciare per eseguire il del.

Ma non capisco perché tutto questo casino per cancellare un file quando esistono le funzioni apposite ...

vendettaaaaa
21-01-2014, 23:38
non so come hai fatto però abbiamo risolto il problema, grazie mille! ;)
ora però non mi esegue il comando del (che era quello che mi ero preposto di fare) :eek:
invece se provo i comandi cmd e help funziona (?)
Perchè
LPWSTR comando = L"del ciao";
è un WCHAR* e non è null terminated, mentre agli array di char inizializzati con una stringa viene silenziosamente aggiunto il carattere '\0' alla fine. Se scrivi
LPWSTR comando = L"del ciao\0";
dovrebbe funzionare.

lorenzo001
22-01-2014, 10:15
Perchè
LPWSTR comando = L"del ciao";
è un WCHAR* e non è null terminated,

Ma no, non è così ...

Quella stringa è regolarmente terminata. Ci pensa il compilatore ad aggiungere il NULL.

Il problema deriva dal fatto che la funzione CreateProcessW ha la necessità di variare il valore della stringa. Quando la funzione tenta di farlo, dato che la LPWSTR è una costante e quindi allocata nel "testo" del codice, avviene la violazione di accesso.

Usando invece un vettore regolarmente allocato in memoria, la funzione lavora correttamente.

Daniels118
22-01-2014, 11:01
Eh, c'è scritto a caratteri cubitali :D
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
The Unicode version of this function, CreateProcessW, can modify the contents of this string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation.

lorenzo001
22-01-2014, 11:11
Eh, c'è scritto a caratteri cubitali :D
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx

Esatto ... non mi è chiaro al momento perché solo per la versione W della funzione e non per la A ... misteri ...

Daniels118
22-01-2014, 11:24
Perché la funzione A accetta una stringa ANSI, la converte in Unicode in un'area allocata dinamicamente e la passa alla funzione W, quindi la funzione W riceve sempre una stringa allocata dinamicamente, mentre la stringa originale non viene modificata.

rab
22-01-2014, 11:42
cavoli, la sapete lunga :)

allora ho provato a dare da riga di comando
cmd del C:\Users\user\ciao.txt

ma non succede niente, allora ho provato con
start del C:\Users\user\ciao.txt
e così funziona

il problema è che se modifico il sorgente in questo modo
WCHAR comando[] = L"start del C:\\Users\\user\\ciao.txt";
non succede niente, qualche consiglio?
se no scrivo un'applicazione java che me lo faccia xD

Daniels118
22-01-2014, 11:48
Anche start è un comando built in del cmd. Per passare un comando al cmd, devi specificare l'opzione /C, così:
cmd /C del pippo

Daniels118
22-01-2014, 11:50
Comunque quoto Lorenzo:
[..]
Ma non capisco perché tutto questo casino per cancellare un file quando esistono le funzioni apposite ...

vendettaaaaa
22-01-2014, 12:16
Ah,io di recente ho avuto un problema con l'api di Windows per cambiare lo sfondo del desktop. A questa funzione passavo una wstring.c_str() ma non andava, poi ho aggiunto il null ed ha funzionato, quindi pensavo fosse quello il problema... non conosco nient'altro delle api di Windows.

lorenzo001
22-01-2014, 13:23
Perché la funzione A accetta una stringa ANSI, la converte in Unicode in un'area allocata dinamicamente e la passa alla funzione W, quindi la funzione W riceve sempre una stringa allocata dinamicamente, mentre la stringa originale non viene modificata.

Questa è una convincente spiegazione ... :D

lorenzo001
22-01-2014, 14:07
dove sbaglio?

Lascia stare quel tipo (strano) di approccio e usa la funzione

remove

http://www.cplusplus.com/reference/cstdio/remove/

rab
23-01-2014, 16:25
oddio, non conoscevo quella funzione xD
Grazie mille, stavo cercando di mangiare uno yogurt con lo scolapasta, se mi consentite la metafora xD

Daniels118
23-01-2014, 16:30
oddio, non conoscevo quella funzione xD
Grazie mille, stavo cercando di mangiare uno yogurt con lo scolapasta, se mi consentite la metafora xD
Sono 2 giorni che te lo ripetiamo :muro:

lorenzo001
23-01-2014, 17:28
Mi chiedo come si possa pensare di programmare in C senza conoscerne le basi ...
...

Ma tu pensavi che tutti i programmi C che vogliono cancellare un programma lo facciano con il Del del DOS ?