Teste se o disco tem acesso de gravação
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"?
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