Here's what I think is really going on:

At the end of a process's execution, 2 things happen:
  - The process's code finishes its execution -- wait returns.
  - The OS closes the executable file.

The second item always "comes after" the first. On Windows the delay might 
be a few milliseconds, which can cause a problem, since an attempt to 
delete the executable right after wait returns can fail because the 
executable is still open. On Unix, this is not a problem because it's OK to 
"remove" an open file -- the file doesn't actually get deleted until all 
openers have closed the file.

At one time, Go's os/exec for Windows had a built-in unconditional 5ms 
delay to prevent this from happening. Not sure if it still does that.

It seems that, on Windows, if a program wants to delete the executable 
right after its process has finished, if should put the delete in a little 
retry loop:
   loop a few times (10?)
      try do delete the executable
      if the delete succeeds
          exit this loop
      wait a short time (1 ms ?)
   announce an error -- executable could not be deleted in reasonable time 
after process completion

This retry loop would be the responsibility of any Windows program that 
wants to delete the executable file after its execution finishes.
In reality, this is not done in very many places, done only by some tools 
like "go run" (build, run, delete), and the occasional user-written tool. 
The vast majority of places where external processes are run leave the 
executable file alone after process completion.

Is it the responsibility of an OS like Windows the guarantee the the 
executable is closed when a process wait returns? I would say not, because 
that might cause a (small) delay in the vast majority of external process 
executions where the executable is not deleted immediately after.


On Friday, August 14, 2020 at 8:55:55 AM UTC-7, jake...@gmail.com wrote:
>
> > Turns out it takes some time to release the lock on the folder, so we 
> should do some time.Sleep before the os.Remove, so that Windows can release 
> the lock.  
>
> I do not believe that should be the case under normal Windows operation. 
> Using a Sleep in a case like this is always a hack. Sometimes it is the 
> only way, but it can fail randomly, especially under stress. There is 
> likely something else going on. Could be poorly written antivirus software, 
> or a finalizer that has not run in your go app, or something else. If it is 
> ok for it to work "most of the time", then maybe your Sleep() solution is 
> sufficient. But if you need real reliability, I suggest figuring out what 
> is really going on. 
>
> On Friday, August 14, 2020 at 10:10:44 AM UTC-4 atakanc...@gmail.com 
> wrote:
>
>> Hello guys, I have solved the issue.
>>
>> Turns out it takes some time to release the lock on the folder, so we 
>> should do some time.Sleep before the os.Remove, so that Windows can release 
>> the lock. 
>>
>> Thank you both for replying.
>>
>> 14 Ağustos 2020 Cuma tarihinde saat 16:21:17 UTC+3 itibarıyla 
>> jake...@gmail.com şunları yazdı:
>>
>>> This works fine for me on Windows 10. 
>>> What is "my.exe" doing? 
>>> Do you have third party antivirus software? If so, try turning it off. 
>>> They are notorious for causing this kind of problem. 
>>>
>>> On Friday, August 14, 2020 at 5:02:36 AM UTC-4 atakanc...@gmail.com 
>>> wrote:
>>>
>>>> Hello dear fellow gophers, 
>>>>
>>>> I had a relatively simple yet quite inconvenient issue which I felt the 
>>>> need to ask here. In my main() function;
>>>>
>>>> os.Remove("my.exe") // err is nil, my.exe is removed
>>>>
>>>> works in Windows without any errors, but when I call exec beforehand, I 
>>>> get access is denied error;
>>>>
>>>> buffer, err := exec.Command("my.exe", myArgs...).Output() // err is 
>>>> nil here, I get desired output
>>>> os.Remove("my.exe") // remove "C:\\.......\my.exe": Access is denied
>>>>
>>>> I tried using cmd.Process.Kill(), cmd.Process.Wait(), 
>>>> cmd.Start()-ioutil.ReadlAll()-cmd.Wait() alternatives as well. I kept 
>>>> getting no errors until 'Access is denied'. 
>>>>
>>>> I'm using go1.14 linux/amd64 for my compiler and Windows 10 Enterprise 
>>>> 10.0.18362.
>>>>
>>>> Thank you.
>>>>
>>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/f0a33b3f-a342-4a9a-9ccc-b0265bd2d60ao%40googlegroups.com.

Reply via email to