Vamos a ver, tengo esta aplicacion cuyo objetivo es el de ejecutar un archivo externo (.txt, .pdf, etc) con ShellExecute, ahora, lo que quiero es que, una vez ejecutado y cerrado dicho archivo, se borre del HD sin mas. Lo que quiero es algo asi como un fichero temporal, suponiendo que sea un txt, pues que una vez mi aplicacion lo abra con el bloc de notas y luego el usuario lo cierre, que este se elimine. La cuestion esta en que, como muchos pensaran, podria programar un DeleteFile justo antes de salir de mi aplicacion y listo, pero lo que quiero hacer es lo siguiente:
Variante#1
========
1- Ejecuto mi aplicacion
2- Mi aplicacion ejecuta el archivo (txt, pdf, doc, etc)
3- Mi aplicacion se cierra
4- Se continua abriendo el archivo con su programa predeterminado
5- Se termina de trabajar con el archivo abierto y se cierra
6- El archivo se elimina automaticamente
Ahora, otra variante que pudiera hacer seria moviendo el punto 3:
Variante#2
========
1- Ejecuto mi aplicacion
2- Mi aplicacion ejecuta el archivo (txt, pdf, doc, etc)
3- Se continua abriendo el archivo con su programa predeterminado
4- Se termina de trabajar con el archivo abierto y se cierra
5- Mi aplicacion sabe que se cerro el archivo y lo elimina
6- Mi aplicacion se cierra
Ahora, la cosa se complica al no ser un .exe el que se ejecuta, sino cualquier tipo de archivo que depende de una segunda aplicacion para abrirse, por lo que no puedo hacer nada con WaitForSingleObject o cualquier API para el trabajo con procesos y su monitoreo (corriganme si estoy equivocado).
Variante#1
========
Para esto que quiero he estado investigando un poco las API's CreateFile y ShellExecuteEx. En cuanto a la primera, he visto un parametro muy interesante, me refiero a:
Código
DWORD dwFlagsAndAttributes
especificamente en la bandera:
FILE_FLAG_DELETE_ON_CLOSE: The system deletes a file immediately after all of its handles are closed, which includes the specified handle and any other open or duplicated handles. If there are existing open handles to a file, the call fails unless they were all opened with the FILE_SHARE_DELETE share mode. Subsequent open requests for the file fail, unless the FILE_SHARE_DELETE share mode is specified.
Y yo tengo esto:
Código
SECURITY_ATTRIBUTES secAttr; ZeroMemory(&secAttr, sizeof(SECURITY_ATTRIBUTES)); secAttr.nLength = sizeof(SECURITY_ATTRIBUTES); secAttr.bInheritHandle = true; // Para que sea el mismo handle para todos los procesos HANDLE hFile = CreateFile(filename, GENERIC_ALL, // GENERIC_READ FILE_SHARE_DELETE + FILE_SHARE_READ, &secAttr, // 0 OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, // FILE_ATTRIBUTE_NORMAL NULL);
Como ven eso es justo lo que necesito, pero aqui viene el otro problema, y es que una vez tomado el handle del archivo con estos valores, no tengo acceso permitido a el por una segunda aplicacion al no ser para eliminarlo, por lo que las llamadas con ShellExecute sobre el mismo daran error de acceso al intentar abrirlo.
Variante#2
========
Para la segunda variante, he investigado sobre la API ShellExecuteEx, exactamente hay un valor interesante en la estructura de parametro SHELLEXECUTEINFO, me refiero al valor:
Código
HANDLE hProcess;
Handle to the newly started application. This member is set on return and is always NULL unless fMask is set to SEE_MASK_NOCLOSEPROCESS. Even if fMask is set to SEE_MASK_NOCLOSEPROCESS, hProcess will be NULL if no process was launched. For example, if a document to be launched is a URL and an instance of Microsoft Internet Explorer is already running, it will display the document. No new process is launched, and hProcess will be NULL.
Note ShellExecuteEx does not always return an hProcess, even if a process is launched as the result of the call. For example, an hProcess does not return when you use SEE_MASK_INVOKEIDLIST to invoke IContextMenu.
Y yo tengo esto:
Código
SHELLEXECUTEINFO execInfo; ZeroMemory(&execInfo, sizeof(SHELLEXECUTEINFO)); execInfo.cbSize = sizeof(SHELLEXECUTEINFO); execInfo.fMask = SEE_MASK_FLAG_DDEWAIT + SEE_MASK_FLAG_NO_UI + SEE_MASK_NOCLOSEPROCESS; execInfo.lpVerb = "open"; execInfo.lpFile = filename; execInfo.nShow = SW_SHOWNORMAL; ShellExecuteEx(&execInfo);
Pero por lo que dicen de el, vemos que no seria confiable para esto, ademas que lo he intentado con el si exito alguno.
Perdon por este post tan largo, y gracias por el simple hecho de haber llegado hasta aqui (si es que llegaste...jeje), pero aqui es donde estoy detenido, y es que no se de que forma lograr lo que quiero,...si es con alguna combinacion exacta de valores en los parametros de CreateFile o en ShellExecuteEx que me permitan alguna de las dos variantes que expuse al principio.
Bueno, no doy mas lata...ya esta...alguien tiene alguna idea o me puede guiar a lo que quiero???
Saludos y gracias de antemano