Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.01.2011, 19:52   #1
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию Ошибка Unable to write to ECustomIniException

Всем привет!

Смотрел отчёты ою ошибках, нарвался на это:
Код:
Unable to write to C:\Program Files\HLR\Data\Settings.ini
В результате выяснил что нельзя писать на системный диск из под пользователя.

Хатя программу то туда юзер поставил, а проге нужно писать свои настройки рядом с собой.

Собственно выкопал функцию проверки прав администратора

как пределить находится ли программа на системном диске и есть ли пользователя права админа?
Человек_Борща вне форума Ответить с цитированием
Старый 07.01.2011, 20:23   #2
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Нус собственно вот что получилось:
Код:
unit Unit1;

interface

uses
  Windows, SysUtils, Classes, Controls, Forms;

type
  TForm1 = class(TForm)
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

function UserIsAdmin: Boolean;
function CheckAppInWinDisk: Boolean;

implementation

{$R *.dfm}

const
  SECURITY_NT_AUTHORITY: TSIDIdentifierAuthority =
  (Value: (0, 0, 0, 0, 0, 5));
  SECURITY_BUILTIN_DOMAIN_RID = $00000020;
  DOMAIN_ALIAS_RID_ADMINS = $00000220;

function UserIsAdmin: Boolean;
var
  hAccessToken: THandle;
  ptgGroups: PTokenGroups;
  dwInfoBufferSize: DWORD;
  psidAdministrators: PSID;
  x: Integer;
  bSuccess: BOOL;
begin
  Result := False;
  bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True,
    hAccessToken);
  if not bSuccess then
  begin
    if GetLastError = ERROR_NO_TOKEN then
      bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY,
        hAccessToken);
  end;
  if bSuccess then
  begin
    GetMem(ptgGroups, 1024);
    bSuccess := GetTokenInformation(hAccessToken, TokenGroups,
      ptgGroups, 1024, dwInfoBufferSize);
    CloseHandle(hAccessToken);
    if bSuccess then
    begin
      AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2,
        SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS,
        0, 0, 0, 0, 0, 0, psidAdministrators);
{$R-}
      for x := 0 to ptgGroups.GroupCount - 1 do
        if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then
        begin
          Result := True;
          Break;
        end;
{$R+}
      FreeSid(psidAdministrators);
    end;
    FreeMem(ptgGroups);
  end;
end;

function GetFirstChar(Path: string): string;
begin
  Result := copy(Path, 0, 1);
end;

function GetSystemDir: string;
var
  s: array[0..MAX_PATH] of Char;
begin
  GetWindowsDirectory(s, SizeOf(S));
  Result := string(S);
end;

function CheckAppInWinDisk: Boolean;
var
  s1, s2: string;
  myDir: string;
begin
  myDir := ExtractFilePath(ParamStr(0));
  s1 := GetFirstChar(MyDir);
  s2 := GetFirstChar(GetSystemDir);
  if (AnsiCompareStr(s1, s2) = 0) then
  begin
    Result := True;
  end
  else
    Result := False;
end;

end.
в DPR файле:
Код:
program Project1;

uses
  Forms,
  Windows,
  Unit1 in 'Unit1.pas' {Form1};

{$R *.res}

begin
  Application.Initialize;
  if CheckAppInWinDisk and not UserIsAdmin then
  begin
    MessageBox(0, 'Программа запущена под учётной записью пользователя на одном диске с системой. Дальнейшая работа программы невозможна. Перенесите программу на другой диск.', 'Внимание!', MB_OK or MB_ICONWARNING);
    Application.Terminate;
  end
  else
  begin
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end;

end.
Думаю пригодиться кому-нибудь =)
Человек_Борща вне форума Ответить с цитированием
Старый 08.01.2011, 03:51   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

ОМФГ.

Не надо проверять права администратора. Программа должна хранить свои настройки в правильном месте. И это правильное место - реестр, либо файл конфигурации в папке Application Data пользователя.

Если вопрос про то, что нужно делать мобильную версию, которая хранит настройки в файле рядом с собой, то логика проста: пытаемся открыть файл конфигурации для записи (или пытаемся его создать, если его вообще нет). Успешно? Используе это место. Не успешно? Копируем файл в Application Data и там его используем.

А ещё лучше - выпускать две версии программы: мобильную и стационарную. Либо использовать одну версию, но как-то указывать в каком режиме ей работать.

А проверка на админа ничего не даст. Я могу тупо заблокировать запись в папку группе Админов.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 08.01.2011, 11:20   #4
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

огромное спасибо за ценный, совет. А вот допустим такая ситуация.... У меня есть много файлов рядом с программой и куда программа что-то записывает, предлогаете переместить все это в Application Data?

Последний раз редактировалось Человек_Борща; 08.01.2011 в 11:28.
Человек_Борща вне форума Ответить с цитированием
Старый 08.01.2011, 12:31   #5
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
У меня есть много файлов рядом с программой и куда программа что-то записывает, предлогаете переместить все это в Application Data?
Зачем? Почему нельзя расставить эту программу на компьютеры, и дать (это сделает администратор) папке в которой она лежит права на запись? (Лично мне часто приходилось это делать с многими популярными CAD системами, и ничего)
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.01.2011, 12:40   #6
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Ну для моего случая желательно чтобы пользователь имел права администратора.
Значит приведённый мною код во втоором сообщении уместен. Т.к. программа оповещает пользователя, о том что нужно для работы.
Человек_Борща вне форума Ответить с цитированием
Старый 08.01.2011, 13:46   #7
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
желательно чтобы пользователь имел права администратора.
Хы... Это ты дырку открываешь в системе нехилую.
можешь подробнее описать задачу? Негарно это пользункам админов раздавать бесплатно
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 08.01.2011, 14:06   #8
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Проблема такая:
Код:
date/time         : 2011-01-07, 22:46:39, 546ms
user name         : Администратор <admin>
registered owner  : gs / gazmyas
operating system  : Windows 2003 Service Pack 2 build 3790
system language   : Russian
system up time    : 1 minute 55 seconds
program up time   : 1 minute 21 seconds
processors        : 2x Intel(R) Pentium(R) 4 CPU 3.20GHz
physical memory   : 625/959 MB (free/total)
free disk space   : (C:) 69,18 GB
display mode      : 1024x768, 32 bit
process id        : $ab0
allocated memory  : 9,21 MB
exec. date/time   : 2010-12-27 13:48
version           : 1.8.0.1800
compiled with     : Delphi 7
madExcept version : 3.0l
callstack crc     : $dc884fb9, $e53aea43, $e53aea43
count             : 2
exception number  : 1
exception class   : EIniFileException
exception message : Unable to write to C:\Program Files\HLR\Data\HLR_Settings.ini.

main thread ($ac8):
0048a868 +05c HLR.exe IniFiles              TIniFile.WriteString
004896c3 +013 HLR.exe IniFiles              TCustomIniFile.WriteBool
005da520 +080 HLR.exe SettingerUnit  19  +4 SaveSettings
005dbb6f +003 HLR.exe AboutUnit      62  +1 TAboutForm.FormDestroy
004be0e5 +031 HLR.exe Forms                 TCustomForm.DoDestroy
004bdf4b +05f HLR.exe Forms                 TCustomForm.BeforeDestruction
00403ef1 +009 HLR.exe System                @BeforeDestruction
004bdf5a +006 HLR.exe Forms                 TCustomForm.Destroy
0047084a +046 HLR.exe Classes               TComponent.DestroyComponents
004bbfbb +02f HLR.exe Forms                 DoneApplication
00453062 +026 HLR.exe SysUtils              DoExitProc
004048a8 +028 HLR.exe System                @Halt0
005e1848 +324 HLR.exe HLR           129 +53 initialization
Понятно сразу что недаёт записать или создать файл на диске.

Но файлов программа создаёт и пишет много. И все это возле себя.
Найстройки программы. ещё понятно из можно вдуплить куда-нибуть, в реестр или в appData. Но вот остальные файлы, это проблема.
И их нужно хранить около себя.

Сам попробовал, создал учёт-ку юзера и сохранил программу на C диске, попытался что-либо зделать, программа защвыряла ошибками.

Пака ничего лучше, при запуске проверять адм. прова и сверять буквы дисков текущего каталога программы и папки windows, и если совпадает, выдавать проедупреждение с советами как избежать, и закрыть программу.
Ничего лучше этго в голову пака не приходит.
Человек_Борща вне форума Ответить с цитированием
Старый 08.01.2011, 14:23   #9
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Цитата:
И все это возле себя.
Зачем? А если два пользователя запустят? Получим кашу, угадал?

Ещё раз: не надо хранить изменяемые данные (и тем более настройки) в папке с программой.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 08.01.2011, 14:36   #10
Человек_Борща
Старожил
 
Аватар для Человек_Борща
 
Регистрация: 30.12.2009
Сообщений: 11,426
По умолчанию

Две копии под одним юзером нельзя.
Человек_Борща вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка Unable to invoke Code.... sisofcase Общие вопросы Delphi 16 14.07.2011 20:02
Unable to load dbexpmysql.dll >>arty<< Общие вопросы Delphi 0 05.04.2010 17:50
почему может возникать ошибка access violation...: write of address при создании динамического массива sleevman Помощь студентам 16 03.11.2009 20:49
Unable to locate file Febreze Компоненты Delphi 1 13.05.2008 22:12
Unable to build. license is invalid or has expired Viteef Свободное общение 9 19.07.2007 08:04