Delphi не может выполнить brcc32 через shellexecute

Я начал писать компоненты и хочу написать программу для создания файлов DCR. Изображение компонента должно быть растровым изображением 24x24, поэтому мне нужно создать файл ресурсов, а затем использовать brcc32 для создания DCR.

Шаги:

  1. Создайте растровое изображение 24x24 (Paint, старое, но золотое)
  2. Создайте RC-файл
  3. Создайте DCR, используя brcc32

Итак, я хочу написать программу, чтобы сделать все это для меня, и это форма. Внутри полей редактирования я написал их свойство Name.

изображение

Это код:

unit uBmp2rc;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, System.IOUtils,
  Vcl.ExtDlgs, Vcl.ExtCtrls, ShellApi;

type
  TBitmapConverter = class(TForm)
    Label1: TLabel;
    edtClassName: TEdit;
    Label2: TLabel;
    edtSource: TEdit;
    Label3: TLabel;
    Label4: TLabel;
    edtDirectory: TEdit;
    OpenPicture: TOpenPictureDialog;
    Label5: TLabel;
    edtBitmap: TEdit;
    Button1: TButton;
    Button2: TButton;
    Label6: TLabel;
    Preview: TImage;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
    path: string;
  public
    { Public declarations }
  end;

var
  BitmapConverter: TBitmapConverter;

implementation

{$R *.dfm}

procedure TBitmapConverter.Button1Click(Sender: TObject);
begin

 if OpenPicture.Execute then
  begin
   edtBitmap.Text := OpenPicture.FileName;
   Preview.Picture.LoadFromFile(OpenPicture.FileName);
  end;

end;

procedure TBitmapConverter.Button2Click(Sender: TObject);
var sw: TStreamWriter;
    tmpName, source, command: string;
begin

 path := edtDirectory.Text;
 source := edtSource.Text;

 tmpName := TPath.Combine(path, source+'.rc');
 Preview.Picture.SaveToFile(TPath.Combine(path, source + '.bmp'));

 sw := TStreamWriter.Create(tmpName, False, TEncoding.UTF8);
 try
  sw.Write(edtClassName.Text + ' BITMAP "' + source + '.bmp"');
 finally
  sw.Free;
 end;

 command := '/C brcc32 -fo"' + TPath.Combine(path, source) + '.dcr" "' + TPath.Combine(path, source) + '.rc"';
 ShellExecute(0, nil, PChar('cmd.exe'), PChar(command), nil, SW_HIDE);

end;

procedure TBitmapConverter.FormCreate(Sender: TObject);
begin
 edtDirectory.Text := TPath.GetDocumentsPath;
end;

Я могу правильно создать файл RC, но не создается DCR. Я что-то не так делаю в команде?

Я добавил PChar() после поиска в Google и нашел подсказку в StackOverflow, но все же не уверен.


person Raffaele Rossi    schedule 01.08.2017    source источник
comment
Почему бы вам не проверить ошибки возврата? Вероятно, вам нужно указать весь путь к brcc32.exe. Я также думаю, что весь пролог не имеет отношения к вопросу.   -  person kobik    schedule 01.08.2017
comment
Хм, у меня есть подозрение, что проблема в вашем файле rc. Я воспроизведу ваш код и проверю, я думаю, что UTF8 - это не то, что вы ищете. В гугле тоже что-то есть по этому поводу   -  person Alberto Miola    schedule 01.08.2017
comment
@kobik Нет, это не бесполезно. Шаги, которые я показал с помощью 1 2 3, — это то, что я делаю в Button2Click. Это для лучшего понимания, так как я вижу, что люди здесь жалуются на то, что дают слишком мало деталей.   -  person Raffaele Rossi    schedule 01.08.2017
comment
@RaffaeleRossi, достаточно честно, но почему вы не проверяете на ошибки? Ошибка (даже от cmd.exe в самой оболочке Windows могла дать наводку)   -  person kobik    schedule 01.08.2017
comment
Raffaele, чтобы найти ответ, как говорит @kobik, вы могли бы проверить ошибку. Чтобы найти его, я просто сохранил код UTF8 и проверил его с помощью brcc32. Это дало мне плохой символ ошибки в исходном вводе, я погуглил и нашел решение (= UTF8 плохо, ANSI хорошо).   -  person Alberto Miola    schedule 01.08.2017
comment
kobik и Alberto Miola: хорошо, но в начале я не знал, что ошибка была в потоке записи. Как я мог это проверить? Я понятия не имел об этом!   -  person Raffaele Rossi    schedule 01.08.2017
comment
Бессмысленно просить оболочку создать процесс cmd для создания процесса brcc32. Вызовите CreateProcess, чтобы создать процесс brcc32.   -  person David Heffernan    schedule 01.08.2017


Ответы (1)


Когда я создаю образ для своих компонентов, я использую блокнот и сохраняю файл как filename.rc с кодировкой по умолчанию (ANSI, а не UTF8). Вы используете UTF8, и вы должны изменить:

sw := TStreamWriter.Create(tmpName, False, TEncoding.UTF8);

с этим:

sw := TStreamWriter.Create(tmpName, False, TEncoding.ANSI);

Если вы используете кодировку ANSI, ваша программа будет работать. Ваша команда верна; если вы попытаетесь запустить cmd.exe и вызвать brcc32 с этими параметрами, вы увидите, что кодировка UTF8 выдает ошибку. Вместо этого отлично работает кодировка ANSI, и у вас будет файл *.drc, готовый к использованию.

См. здесь что-то подобное, речь идет о построителе c++, но он показывает что проблема связана с кодировкой UTF8.

person Alberto Miola    schedule 01.08.2017
comment
Но в чем разница между ANSI и UTF8? Как они хранят символы? - person Raffaele Rossi; 01.08.2017
comment
@RaffaeleRossi Google может полностью ответить на ваш вопрос - person Alberto Miola; 01.08.2017
comment
Ok. В любом случае переход на ANSI решил мою проблему, спасибо - person Raffaele Rossi; 01.08.2017