Pergunta

Eu preciso saber se o meu programa pode gravar arquivos no disco (HDD, disquete, flash, CD), de onde ele está sendo executado. Eu tentei algo como:

     {$I-}
     Rewrite(myFile);                                       
     {$I+}
  Result:= (IOResult = 0);

O problema é que se o disco é só de leitura, o Windows dá-me uma mensagem de erro me que

dizendo

"appname.exe -. Erro Protect gravar o disco não pode ser escrito porque é protegido contra gravação Remova a proteção contra gravação do volume de USB_BOOT na unidade D :. Anular TryAgain Continuar "

Como posso testar para acesso de gravação sem levantar qualquer erro / mensagens de aviso? Obrigado.


Editar:

Ok. O "bug" não tem nada a ver com a peça mencionado acima do código. Eu só pensei que ele aparece lá. I mover o código para o disco somente leitura e correu-lo de lá. O erro aparece em uma função chamada "CreateShortcutEx", nesta linha:

 MyPFile.Save(PWChar(WFileName),False);

MyPFile é declarada como este:

var
 MyObject  : IUnknown;
 MySLink   : IShellLink;
 MyPFile   : IPersistFile;
 Directory : String;
 WFileName : WideString;
 MyReg     : TRegIniFile;
begin
 MyObject := CreateComObject(CLSID_ShellLink);
 MySLink  := MyObject as IShellLink;
 MyPFile  := MyObject as IPersistFile;
 .....
end;

Então, por que é MyPFile tentando escrever a unidade do aplicativo (o que é somente leitura) se o parâmetro WFileName é "C: \ Documents and Settings \ bla bla"?

Foi útil?

Solução

Chamar a API do Windows SetErrorMode () função para desativar a caixa de mensagem de erro.

Editar:

Eu apenas tentei, e isto:

procedure TForm1.Button1Click(Sender: TObject);
var
  Str: TStream;
  OldMode: Cardinal;
begin
  OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);

  try
    try
      Str := TFileStream.Create('z:\foo.txt', fmOpenReadWrite);
      try

      finally
        Str.Free;
      end;
    except end;
  finally
    SetErrorMode(OldMode);
  end;
end;

funciona como esperado.

Outras dicas

Não é realmente bonita, mas isso parece funcionar para mim.



function CanWrite(drive: string): boolean;
    var
        OldMode: Cardinal;
    begin
        OldMode := SetErrorMode(SEM_FAILCRITICALERRORS);
        try
            with TStringList.Create do
                try
                    SaveToFile(drive + ':\file.txt');
                    result := true;

                    try
                        deletefile(drive + ':\file.txt');
                    except
                    end;
                except
                    result := false;
                end;
        finally
            SetErrorMode(OldMode);
        end;
end;

Chamada a ele com



if CanWrite('g') = true then
    begin
        showmessage('Can Write');
    end
    else
    begin
        showmessage('Can not write');
end;

O que acontece quando você coloca o seu código dentro de um try / except?

Além disso, você pode tentar (algo como) o seguinte:

function CanWrite: boolean;
begin
  result := true;
  with TStringList.Create do
  try
    SaveToFile('file.txt');
  except
    result := false;
  finally
    Free;
  end;
end;

Desculpe, mas eu não o código em Delphi mais e eu não tenho Delphi instalado em qualquer lugar.

Não existe um pequeno gratuito "Drive está pronto?" utilitário ( dready.com ) escritas por Horst Schaeffer que também pode verificar acesso de gravação. Eu não testei, mas tanto quanto eu posso ver isso poderia ser usado como uma solução; chamá-lo, por exemplo, como "Dready C: / W". e verificar o valor de retorno

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top