¿Cómo obtener códigos de error DeleteUrlCacheEntry ()? (O información adicional sobre por qué una eliminación en particular no funcionó)?

Basically, when I call DeleteUrlCacheEntry (which is part of the Wininet.dll API) I either get returned the number 1 (which means, deletion successful) or the number 0 (which meant, deletion didn't work).

My question is, how can I find out why a deletion did not work? (that is, when a 0 is returned). I heard there is a GetLastError() function in C++, however I am using VB6 and apparently the GetLastError equivalent in VB6 is the Err.LastDllError property.

After a DeleteUrlCacheEntry attempted deletion fails (returns 0) I call/query the Err.LastDllError and it always returns 0 - no matter what. It returns 0 even if DeleteUrlCacheEntry returns 0 (deletion didn't work) and even when it returns 1 (deletion did work). I also make the call/query to Err.LastDllError as soon as possible (as in, right after the DeleteUrlCacheEntry call).

I am really confused, because I don't even get a runtime error or any typical exception (or any exception for that matter). I do not have On Error Resume Next to ignore exception anywhere in my application, so every means of an error being reported to me is available but I cannot for the life of me figure out why a particular DeleteUrlCacheEntry() attempt will fail and return 0 (there doesn't seem to be a way for me to find out).

So, my question is, how do I get extended error information from the DeleteUrlCacheEntry() function (residing in the wininet.dll API)?

If you would like more information on the reason why I am looking for extended error information from the DeleteUrlCacheEntry() function, I have another question which details this (together with actual examples of cache items that work and don't work when a deletion is attempted): https://stackoverflow.com/questions/12096546/deleteurlcacheentry-function-of-wininet-api-not-deleting-some-internet-explo

Also, just to add, I am using VB6 - but principally it should be the same across most languages as it is an API call. Here is my declaration in VB6:

Public Declare Function DeleteUrlCacheEntry Lib "WININET" Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As String) As Long

Also, I am calling it like this:

Dim lReturnValue As Long

Dim cacheFileString As String

' GetStrFromPtrA turns Pointer (Long) to String. cacheFileString is the actual text/string of the lpszSourceUrlName turned from Pointer (Long) to String (human readable cache file name/string). Also, cacheFileString is retreived from FindFirst/NextEntry functions in a loop, so can't be incorrectly formatted or anything, as it also works when deleting most other items.

cacheFileString = GetStrFromPtrA(icei.lpszSourceUrlName)

lReturnValue = DeleteUrlCacheEntry(cacheFileString)

The lReturnValue ends up being 0 if deletion didn't work, and 1 when deletion does work, and that is it. Also, Err.LastDllError siempre devuelve 0.

Thank you for your anticipated assistance.

preguntado el 24 de agosto de 12 a las 01:08

@KenWhite The reason for the tags is because it applies to both C++ and Delphi as well (usage scenario is the same since it's a wininet.dll api call with error codes usually residing in a c++ .h file. So, it applies to people using these languages and those using these languages will also be able to make a contribution to this post. -

@KenWhite it is not random, this is not a "code" issue just because some people wanted to see the code, it is an error codes issue, which applies to Delphi and C++ especially, notice i didn't include javascript, .NET or Java! Those would be random tags! API is universal across many languages which can hook into the Windows API, such as delphi and C++, which is why I seek the support of those people (getting extended error codes using API, not VB6-specific code). This is why people who are not closely involved in understanding the question should not edit tags or suggest close/delete etc. -

You can call API functions from assembler, too; that doesn't make it an assembly question. And I'm quite familiar, thank you - I'm not exactly new here, if you view my profile and the tags for which I've answered questions. :-) -

@KenWhite You're right, many languages do WinAPI calls, however, I am familiar with delphi, vb.net and c# which is why I was open to solutions in those languages to get a better grasp on the problem, hence my tagging was also a way to make that inference (of me being open to solutions in those languages). I do not know how to use assembler - however, I wish I did :). -

No, you don't. :-) It's pretty nasty to work in. (I'm going to clean up some of the noise here to reduce the clutter.) -

4 Respuestas

Personally I would set a break point on the call to DeleteUrlCacheEntry(), and step through it observing what the values in the call stack are.

Other than that, there is not much that can be said without a code snippet.

Respondido 24 ago 12, 02:08

Hello, thank you for your input, I have added the code you requested (updated main question above), and I'm not sure if we get a call stack in VB6 - but when I set a breakpoint on DeleteUrlCacheEntry, there is nothing to step into since it's an API call, so pressing F8 just executes the DeleteUrlCacheEntry line and proceedes to the next line. What do you think? - Erx_VB.NExT.Coder

If Err.LastDllError is returning 0 than either GetLastError() really is returning 0, which is unlikely, or VB is not calling GetLastError(), which is more likely. Such as if the VB declaration of DeleteUrlCacheEntry() is wrong, like it is not setting the DllImport.SetLastError property to true under .NET PInvoke.

Respondido 24 ago 12, 02:08

I have updated main question (above) with code and declaration so that you may review it, since I am using VB6 - I'm not sure how (or if) .NET PInvoke would play a part in this. I have diagnostic information on items that are and aren't deleted in the linked example in my main question above, detailing which items it returns 0 on and which items it returns 1 on, if that would be useful for your review, here is the link again: stackoverflow.com/questions/12096546/… What are your thoughts? Thank you (upvoted). - Erx_VB.NExT.Coder

@KenWHite stop inferring, I am happy to do this in VB.NET as well, in order to understand the problem better, and in C# if I need to, if his suggestion is .NET I will take it, hence my vb.net and c# tags, as I am open to a vb.net and c# solution as well. Hence, you are not involved in interpreting the question, so stop altering it. thank you. - Erx_VB.NExT.Coder

@RemyLebeau I am happy to consider which-ever type of solution that you provide, as I can code in .NET, if there is any additional ideas you have or information you can shed on this problem, please do let me know, thanks. escucha - Erx_VB.NExT.Coder

Under C++ and Delphi, you can call GetLastError() directly. Under. NET, you use PInvoke to call API functions so you can use DllImport.SetLastError=true y Marshal.GetLastWin32Error(). - Rémy Lebeau

MSDN documentation says that in VB6 equivalent is to use the Err.LastDllError (same as using GetLastError()), but when I do this, I keep getting the error code 0, does anyone have any ideas on this or should I start a new question re the Err.LastDllError part? - Erx_VB.NExT.Coder

This might not be directly relevant, but it seems to me that you are doing an unecessary string copy here. Why not directly use the string pointer you already have:

Public Declare Function DeleteUrlCacheEntry Lib "WININET" Alias "DeleteUrlCacheEntryA" (ByVal lpszUrlName As Long) As Long

Dim lReturnValue As Long

lReturnValue = DeleteUrlCacheEntry(icei.lpszSourceUrlName)

(This is assuming that icei.lpszSourceUrlName is a pointer to an ANSI string.)

Also, you do realise that Err.LastDllError is overwritten everytime a command called via a VB declare or type library declare with usesgetlasterror = true? So, for instance, if I declared APIFunc1() and APIFunc2(), and then called them like this;

nRet = APIFunc1(APIFunc2)

... then LastDllError would reflect only APIFunc1().

Respondido 28 ago 12, 09:08

Mark, thank you for the clarification here. So, you're sayign that DeleteUrlCacheEntry accepts both a pointer or the string representation of that pointer, correct? (so, you can pass either one and it accepts)? Also, your note about the func1 and func2 makes sense, never thought about it in enough detail to make that realization but it would have to work in the way you mentioned for obvious reasons, so thanks again for that note, upvoted. - Erx_VB.NExT.Coder

As far as DeleteUrlCacheEntry() is concerned, you are supplying it a C type string i.e. a pointer to a series of bytes, terminated by a null character. In your original declare, you used "ByVal lpszUrlName As String". In this case, VB interpreted this as "convert the VB string passed to a temporary C type string, call the API function with the pointer to this temporary C string, then copy the C string, converted, back into the original string". In my declarem VB interpreted this as "call the API function with the supplied Long value" i.e your previously received string pointer. - Marcos Bertenshaw

It's a bit dated ... but I am interested by the subject, so I thought I would share my limited knowledge.

For me, when I called DeleteUrlCacheEntry with a wrong URL, I get an error and Err.LastDllError is set to 2 !

respondido 13 mar '15, 19:03

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.