Two similar functions for writing data to binary file using BinaryWriter
Both methods are public so I would like to suggest doing proper argument validation up front which enables you to throw the correct exceptions and return early.  
Use the var type if the right hand side of an assignment makes the type obvious.  

For instance  

var isDone = false;  
var quitTime = DateTime.Now.AddMilliseconds(500);


instead of  

bool isDone = false; 
DateTime quitTime = DateTime.Now.AddMilliseconds(500);  

use braces {} although they might be optional. This makes your code less error prone and the intent of the code is more clear.  
Don't talk to Program but let Program pass any needed parts to your class and use it then. A child object should only talk to its parent by using events.  
you should pass the 500 ms as a optional parameter to that method. This will make your code more flexible in case you need to adjust the timeout.  
you should always try to code against interfaces rather than against concrete implementations. So either use IList&lt;RollHeader&gt; or better IEnumerable&lt;RollHeader&gt; as the passed in type of WriteHeadersToIndexer(). This enables you to pass for instance either an List&lt;RollHeader&gt; or RollHeader [] to that method. In fact each type which implements IEnumerable&lt;T&gt; will be good to pass.  


From the comments of the question  


  I am using different FileModes and Seek() because in the first case, I write single data object to existing file, in the second case, I create new file and write all data objects from List to this file.  


Based on the above I would like to suggest adding another method which is called from the former 2 methods. This new method will have one method argument being a FileMode value like so  

private void WriteToIndexer(string path, IEnumerable&lt;RollHeader&gt; headers, FileMode mode, double timeOutMs = 500d)
{
    if (path == null) { throw new ArgumentNullException($"{path}"); }
    if (headers == null) { throw new ArgumentNullException($"{headers}"); }
    if (string.IsNullOrWhiteSpace(path)) { throw new ArgumentException("Parameter may not be empty", $"{path}"); }

    if (!headers.Any()) { return; }

    bool isDone = false;
    bool error = false;

    DateTime quitTime = DateTime.Now.AddMilliseconds(timeOutMs);

    while (!isDone &amp;&amp; DateTime.Now &lt; quitTime)
    {
        try
        {

            using (var stream = File.Open(path, mode))
            using (var writer = new BinaryWriter(stream))
            {
                writer.Seek((int)writer.BaseStream.Length, new SeekOrigin());
                foreach (RollHeader header in headers)
                {
                    WriteSingleHeader(writer, header);
                }

                isDone = true;

                if (error)
                {
                    Program.logger.Write(LogLevel.Error, "Done after timeout.");
                }
            }

            SetReadRightToFileForEveryone(path);
        }
        catch (IOException ex)
        {
            if (!error)
            {
                Program.logger.Write(LogLevel.Error, ex.Message);
            }
            error = true;
        }
    }
}  


this takes advantage of the string interpolation of C# 6.0.  

No you can call this like so  

public void AddHeaderToIndexer(string path, RollHeader header)
{
    WriteToIndexer(path, new RollHeader[] { header }, FileMode.OpenOrCreate);
}
public void WriteHeadersToIndexer(string path, IEnumerable&lt;RollHeader&gt; headers)
{
    WriteToIndexer(path, headers, FileMode.Create);
}