Re: Otnovo command line
7 отговора
167 прегледа
Re: Otnovo command line
Като напухаш няколко файла като параметри би трябвало да се обходят по следния начин:
for i:=1 to ParamCount do
PlayList.Add (ParamStr (i))
чети и дишай по-леко
for i:=1 to ParamCount do
PlayList.Add (ParamStr (i))
чети и дишай по-леко
Re: Otnovo command line
Loshoto e samo 4e parametrite sa razdeleni ot prazni mesta i trqbwat dopylnitelni prowerki za nali4ieto na space-owe w imeto na pesenta
Важно е да се знае каде се намира 'Any Key'
Важно е да се знае каде се намира 'Any Key'
Re: Otnovo command line
Мдааа... но няма нещо особенно страшно. Малко гърч с текстообработка, например да се хване поредица ххх.ххх(интервал)...
чети и дишай по-леко
чети и дишай по-леко
Re: Otnovo command line
Towa e taka
Po kofti e ako e xxx xx xx x xxx.xxx.xxx.mp3 :))
wse pak trqbwea da se hwashtat wsi4ki slu4ai w jiwota :)
Важно е да се знае каде се намира 'Any Key'
Po kofti e ako e xxx xx xx x xxx.xxx.xxx.mp3 :))
wse pak trqbwea da se hwashtat wsi4ki slu4ai w jiwota :)
Важно е да се знае каде се намира 'Any Key'
Re: Otnovo command line
Хихихи... без напън нема кеф... Между другото, кой е Роджър? И ако не е нетактично, каква е рибата - сом, шаран, цаца? 
чети и дишай по-леко
чети и дишай по-леко
Re: Otnovo command line
Muhaha haha
Stranno ti si pyrwiq koito me pita towa
Poger e edin zaek
a ribata e Pechena 
Важно е да се знае каде се намира 'Any Key'
Stranno ti si pyrwiq koito me pita towa
Poger e edin zaek
Важно е да се знае каде се намира 'Any Key'
Re: Otnovo command line
S risk da se powtorq:
Problema ti ne e w towa kak parcewash command lina a w towa kak shella interpretira nejnite komandi, a nejnite komandi sa za wseki selektiran faj da pusne otdelen instance na appa ti s edinstwen parametar imeto na fajla.
Problema se rasheawa s detekciq na rabotreshto kopie + mejduprocesna komunikaciq za prehwarlenq na zaqwkata/fajla kam po-stariq proces.
btw ako si mnogo nawitak pishi - sha kacha malko kod nekade da widish az kak go prawq :)) (FindWindow/PostMessage/OpenProcess/ReadProcessMemory/PostMessage)
------------------------------
I got a COMPILER, and I'm not afraid to use it!
Problema ti ne e w towa kak parcewash command lina a w towa kak shella interpretira nejnite komandi, a nejnite komandi sa za wseki selektiran faj da pusne otdelen instance na appa ti s edinstwen parametar imeto na fajla.
Problema se rasheawa s detekciq na rabotreshto kopie + mejduprocesna komunikaciq za prehwarlenq na zaqwkata/fajla kam po-stariq proces.
btw ako si mnogo nawitak pishi - sha kacha malko kod nekade da widish az kak go prawq :)) (FindWindow/PostMessage/OpenProcess/ReadProcessMemory/PostMessage)
------------------------------
I got a COMPILER, and I'm not afraid to use it!
moje bi tova e koeto ti trqbva :)
Privet otnovo,
radvam se , che predishnata funkcia ti varshi rabota.
a za drugoto az javno ne sum razbral kakuv tochno ti e problema.
Ti se opitvash da startirash ot explorera, a ne da gi podavash directno kato paramerti.
Predi vreme popadnah na edno reshenie na takuv problem s edin component - i to sas source, i sled malko kopaene i podrezdane mi stana jasno kak raboti, slozih komentari na bulgarski i si napravih modulche s edno classche.
edinstvenoto, koeto trqbva da napravish e da si napravish edin obekt ot toja class, da Assign-esh edin EventHandler i da startirash edin method.
Nqkoj beshe reshil da sharne opita i poznaniata si (tova programistite sme zadrujni kopeleta ... pone povecheto koito poznavam ;)p
i az nqmam pravo da go zadarzam za sebe si , nito da si prisvojvam avtorstvoto za idejata. prosto ja prigodih za moite nuzdi.
mislq che shte ti varshi rabota.
prosto pravish slednoto:
var
one : TOneInstance;
.....
one := TOneInstance.Create;
one.OnInstanceStarted := AnotherInstanceStarted; /// !!! Vazno
one.Load; // !!! Vazno
--------------------------------------- source--------------------------------------------------------
unit OneInstParam;
interface
uses
Windows, SysUtils, Messages, Classes, Forms;
type
//
TInstanceStartedEvent = procedure(Sender :TObject; slParams: TStringList) of object;
const
MAX_PARAM_SIZE = MAX_PATH;
MAX_PARAM_COUNT = 20;
MSG_NEW_INSTANCE = WM_USER + 300; // Идентифициращо съобщение
WAIT_TIME = 5000; // 5 sec
type
// Обща структура за данните
PCommonData = ^TCommonData;
TCommonData = packed record
FirstInstanceWnd : HWND;
ParamCount : Integer;
Params : Array[0..MAX_PARAM_COUNT-1, 0..MAX_PARAM_SIZE] of Char;
end;
TOneInstance = class
private
FMappingHandle : THandle;
HWNDHandle : THandle;
HSemaphore : THandle;
FOnInstanceStarted : TInstanceStartedEvent;
procedure DestroySemaphore;
function Lock() : Boolean;
function Unlock() : Boolean;
procedure RunAsFirstInstance(lpData: PCommonData);
procedure RunAsSecondInstance(var lpData : PCommonData);
procedure OnHWNDEvent(var Message: TMessage);
function IsFirstInstance() : Boolean;
protected
procedure InstanceStarted(params:TStringList); virtual;
public
constructor Create;
destructor Destroy; override;
procedure Load;
published
property OnInstanceStarted : TInstanceStartedEvent
read FOnInstanceStarted write FOnInstanceStarted;
end;
implementation
const
STANDARD_RIGHTS_REQUIRED = $000F0000;
SYNCHRONIZE = $00100000;
SEMAPHORE_MODIFY_STATE = $0002;
SEMAPHORE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $3);
var
SingleInstInstance : TObject = nil;
//**************************************************
// Първият екземпляр ще получи event , когато се стартира друг екземпляр
procedure TOneInstance.InstanceStarted(params:TStringList);
begin
if assigned(FOnInstanceStarted) then
FOnInstanceStarted(Self, params);
end;
//**************************************************
function TOneInstance.IsFirstInstance() : Boolean;
begin
result := HWNDHandle <> 0;
end;
//**************************************************
constructor TOneInstance.Create;
begin
// В приложението трябва да има НЕ ПОВЕЧЕ ОТ ЕДИН обект от този клас !
if SingleInstInstance <> Nil then
raise Exception.Create('В приложението трябва да има НЕ ПОВЕЧЕ ОТ ЕДИН обект от този клас !');
SingleInstInstance := Self;
end;
//**************************************************
destructor TOneInstance.Destroy;
begin
// Освобождава общата структура данни
if FMappingHandle <> 0 then
CloseHandle(FMappingHandle);
// Освобождава паметта
if HWNDHandle <> 0 then
DeallocateHwnd(HWNDHandle);
// Семафора
DestroySemaphore;
SingleInstInstance := Nil;
end;
//**************************************************
procedure TOneInstance.DestroySemaphore;
begin
if HSemaphore <> 0 then
CloseHandle(HSemaphore);
HSemaphore:=0;
end;
//**************************************************
// window proc на "вътрешния" прозорец
procedure TOneInstance.OnHWNDEvent(var Message: TMessage);
var
tmp: String;
params: TStringList;
lpData: PCommonData;
i:Integer;
begin
if (message.Msg = MSG_NEW_INSTANCE) then
begin
// Стартиран е друг екземпляр
if FMappingHandle <> 0 then
begin
lpData := MapViewOfFile(FMappingHandle,
FILE_MAP_WRITE OR FILE_MAP_READ, 0, 0, sizeof(TCommonData));
if lpData <> nil then
try
// get Parameters
params := TStringList.Create;
try
for i:=0 to lpData^.ParamCount-1 do
begin
SetString(tmp, PChar(@(lpData^.Params[i,0])),StrLen(@(lpData^.Params[i,0])));
params.Add(tmp);
end;
// Известява, че е стартиран
InstanceStarted(params);
finally
params.Free;
end;
finally
UnmapViewOfFile(lpData);
// Освобождава семафора
Unlock;
end;
end;
end
else
with Message do
Result := DefWindowProc(HWNDHandle, Msg, wParam, lParam);
end;
//**************************************************
function TOneInstance.Lock(): Boolean;
begin
// Ако резултата е FALSE то текущия екземпляр ще играе ролятя ня ПЪРВИ !!!
if HSemaphore = 0 then
HSemaphore := OpenSemaphore(SEMAPHORE_ALL_ACCESS, false, PChar(ExtractFileName(ParamStr(0))+'Sem'));
result:=HSemaphore<>0;
if result then
begin
// Изчакваме WAIT_TIME семафора
result:=(WaitForSingleObject(HSemaphore, WAIT_TIME)=WAIT_OBJECT_0);
end;
end;
//**************************************************
function TOneInstance.Unlock(): Boolean;
begin
// Връщаме семафора
result := false;
if HSemaphore <> 0 then
begin
result := ReleaseSemaphore(HSemaphore, 1, nil);
end;
end;
//**************************************************
procedure TOneInstance.RunAsFirstInstance(lpData : PCommonData);
begin
// Инициализира "вътрешен" прозорец
HWNDHandle:=AllocateHwnd(OnHWNDEvent);
// Създава се семафор, който ограничава достъпа до общия блок памет до един екземпляр
Unlock;
DestroySemaphore;
HSemaphore := CreateSemaphore(nil, 0, 1, PChar(ExtractFileName(ParamStr(0))+'Sem'));
assert(HSemaphore <> 0 ,'Unable to create semaphore');
// Съхранява се Handle към "вътрешния" прозорец в обия блок памет
lpData^.FirstInstanceWnd := HWNDHandle;
// Освобождава семафора
Unlock;
end;
//**************************************************
procedure TOneInstance.RunAsSecondInstance(var lpData : PCommonData);
var
i : Integer;
tmp : String;
begin
if not Lock() then
begin
// ТО това е първият екземпляр
RunAsFirstInstance(lpData);
Exit;
end;
// Това е втори укземпляр
// Поставя параметрите в общия блок памет
lpData^.ParamCount := ParamCount;
if lpData^.ParamCount > MAX_PARAM_COUNT then
lpData^.ParamCount := MAX_PARAM_COUNT;
for i := 0 to lpData^.ParamCount-1 do
begin
tmp := ParamStr(i+1);
if Length(tmp) > MAX_PARAM_SIZE then
SetLength(tmp, MAX_PARAM_SIZE);
StrCopy(@(lpData^.Params[i,0]), PChar(tmp));
end;
// и съобщава на първия екземпляр
PostMessage(lpData^.FirstInstanceWnd, MSG_NEW_INSTANCE, 0, 0);
// той от своя страна отговаря като отпуска семафора
if not Lock() then
begin
// Няма отговор (Не е получен семафора)
RunAsFirstInstance(lpData);
Exit;
end;
Unlock;
// разрушава се семафора
DestroySemaphore;
// освобождава се общия блок памет
UnmapViewOfFile(lpData);
lpData := nil;
// Не се показва формата на приложението
Application.ShowMainForm:=false;
// Изход
Application.Terminate;
end;
//**************************************************
procedure TOneInstance.Load;
var
lpData : PCommonData;
begin
// Създава се общия блок памет
FMappingHandle := CreateFileMapping(0, NIL, PAGE_READWRITE, 0, sizeof(TCommonData),
PChar(ExtractFileName(ParamStr(0))));
if FMappingHandle <> 0 then
begin
// указател към блока
lpData := MapViewOfFile(FMappingHandle, FILE_MAP_WRITE OR FILE_MAP_READ, 0, 0, sizeof(TCommonData));
if lpData <> Nil then
try
if GetLastError = ERROR_ALREADY_EXISTS then
begin
// Има стартиран екземпляр
RunAsSecondInstance(lpData);
end
else
begin
// Това е първия екземпляр
RunAsFirstInstance(lpDAta);
end;
finally
if lpData <> nil then
UnmapViewOfFile(lpData);
end;
end;
end;
initialization
SingleInstInstance := nil;
finalization
if SingleInstInstance <> Nil then
SingleInstInstance.Free;
end.
----------------------------------------
Щом не върви от първия път, значи има шанс
radvam se , che predishnata funkcia ti varshi rabota.
a za drugoto az javno ne sum razbral kakuv tochno ti e problema.
Ti se opitvash da startirash ot explorera, a ne da gi podavash directno kato paramerti.
Predi vreme popadnah na edno reshenie na takuv problem s edin component - i to sas source, i sled malko kopaene i podrezdane mi stana jasno kak raboti, slozih komentari na bulgarski i si napravih modulche s edno classche.
edinstvenoto, koeto trqbva da napravish e da si napravish edin obekt ot toja class, da Assign-esh edin EventHandler i da startirash edin method.
Nqkoj beshe reshil da sharne opita i poznaniata si (tova programistite sme zadrujni kopeleta ... pone povecheto koito poznavam ;)p
i az nqmam pravo da go zadarzam za sebe si , nito da si prisvojvam avtorstvoto za idejata. prosto ja prigodih za moite nuzdi.
mislq che shte ti varshi rabota.
prosto pravish slednoto:
var
one : TOneInstance;
.....
one := TOneInstance.Create;
one.OnInstanceStarted := AnotherInstanceStarted; /// !!! Vazno
one.Load; // !!! Vazno
--------------------------------------- source--------------------------------------------------------
unit OneInstParam;
interface
uses
Windows, SysUtils, Messages, Classes, Forms;
type
//
TInstanceStartedEvent = procedure(Sender :TObject; slParams: TStringList) of object;
const
MAX_PARAM_SIZE = MAX_PATH;
MAX_PARAM_COUNT = 20;
MSG_NEW_INSTANCE = WM_USER + 300; // Идентифициращо съобщение
WAIT_TIME = 5000; // 5 sec
type
// Обща структура за данните
PCommonData = ^TCommonData;
TCommonData = packed record
FirstInstanceWnd : HWND;
ParamCount : Integer;
Params : Array[0..MAX_PARAM_COUNT-1, 0..MAX_PARAM_SIZE] of Char;
end;
TOneInstance = class
private
FMappingHandle : THandle;
HWNDHandle : THandle;
HSemaphore : THandle;
FOnInstanceStarted : TInstanceStartedEvent;
procedure DestroySemaphore;
function Lock() : Boolean;
function Unlock() : Boolean;
procedure RunAsFirstInstance(lpData: PCommonData);
procedure RunAsSecondInstance(var lpData : PCommonData);
procedure OnHWNDEvent(var Message: TMessage);
function IsFirstInstance() : Boolean;
protected
procedure InstanceStarted(params:TStringList); virtual;
public
constructor Create;
destructor Destroy; override;
procedure Load;
published
property OnInstanceStarted : TInstanceStartedEvent
read FOnInstanceStarted write FOnInstanceStarted;
end;
implementation
const
STANDARD_RIGHTS_REQUIRED = $000F0000;
SYNCHRONIZE = $00100000;
SEMAPHORE_MODIFY_STATE = $0002;
SEMAPHORE_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $3);
var
SingleInstInstance : TObject = nil;
//**************************************************
// Първият екземпляр ще получи event , когато се стартира друг екземпляр
procedure TOneInstance.InstanceStarted(params:TStringList);
begin
if assigned(FOnInstanceStarted) then
FOnInstanceStarted(Self, params);
end;
//**************************************************
function TOneInstance.IsFirstInstance() : Boolean;
begin
result := HWNDHandle <> 0;
end;
//**************************************************
constructor TOneInstance.Create;
begin
// В приложението трябва да има НЕ ПОВЕЧЕ ОТ ЕДИН обект от този клас !
if SingleInstInstance <> Nil then
raise Exception.Create('В приложението трябва да има НЕ ПОВЕЧЕ ОТ ЕДИН обект от този клас !');
SingleInstInstance := Self;
end;
//**************************************************
destructor TOneInstance.Destroy;
begin
// Освобождава общата структура данни
if FMappingHandle <> 0 then
CloseHandle(FMappingHandle);
// Освобождава паметта
if HWNDHandle <> 0 then
DeallocateHwnd(HWNDHandle);
// Семафора
DestroySemaphore;
SingleInstInstance := Nil;
end;
//**************************************************
procedure TOneInstance.DestroySemaphore;
begin
if HSemaphore <> 0 then
CloseHandle(HSemaphore);
HSemaphore:=0;
end;
//**************************************************
// window proc на "вътрешния" прозорец
procedure TOneInstance.OnHWNDEvent(var Message: TMessage);
var
tmp: String;
params: TStringList;
lpData: PCommonData;
i:Integer;
begin
if (message.Msg = MSG_NEW_INSTANCE) then
begin
// Стартиран е друг екземпляр
if FMappingHandle <> 0 then
begin
lpData := MapViewOfFile(FMappingHandle,
FILE_MAP_WRITE OR FILE_MAP_READ, 0, 0, sizeof(TCommonData));
if lpData <> nil then
try
// get Parameters
params := TStringList.Create;
try
for i:=0 to lpData^.ParamCount-1 do
begin
SetString(tmp, PChar(@(lpData^.Params[i,0])),StrLen(@(lpData^.Params[i,0])));
params.Add(tmp);
end;
// Известява, че е стартиран
InstanceStarted(params);
finally
params.Free;
end;
finally
UnmapViewOfFile(lpData);
// Освобождава семафора
Unlock;
end;
end;
end
else
with Message do
Result := DefWindowProc(HWNDHandle, Msg, wParam, lParam);
end;
//**************************************************
function TOneInstance.Lock(): Boolean;
begin
// Ако резултата е FALSE то текущия екземпляр ще играе ролятя ня ПЪРВИ !!!
if HSemaphore = 0 then
HSemaphore := OpenSemaphore(SEMAPHORE_ALL_ACCESS, false, PChar(ExtractFileName(ParamStr(0))+'Sem'));
result:=HSemaphore<>0;
if result then
begin
// Изчакваме WAIT_TIME семафора
result:=(WaitForSingleObject(HSemaphore, WAIT_TIME)=WAIT_OBJECT_0);
end;
end;
//**************************************************
function TOneInstance.Unlock(): Boolean;
begin
// Връщаме семафора
result := false;
if HSemaphore <> 0 then
begin
result := ReleaseSemaphore(HSemaphore, 1, nil);
end;
end;
//**************************************************
procedure TOneInstance.RunAsFirstInstance(lpData : PCommonData);
begin
// Инициализира "вътрешен" прозорец
HWNDHandle:=AllocateHwnd(OnHWNDEvent);
// Създава се семафор, който ограничава достъпа до общия блок памет до един екземпляр
Unlock;
DestroySemaphore;
HSemaphore := CreateSemaphore(nil, 0, 1, PChar(ExtractFileName(ParamStr(0))+'Sem'));
assert(HSemaphore <> 0 ,'Unable to create semaphore');
// Съхранява се Handle към "вътрешния" прозорец в обия блок памет
lpData^.FirstInstanceWnd := HWNDHandle;
// Освобождава семафора
Unlock;
end;
//**************************************************
procedure TOneInstance.RunAsSecondInstance(var lpData : PCommonData);
var
i : Integer;
tmp : String;
begin
if not Lock() then
begin
// ТО това е първият екземпляр
RunAsFirstInstance(lpData);
Exit;
end;
// Това е втори укземпляр
// Поставя параметрите в общия блок памет
lpData^.ParamCount := ParamCount;
if lpData^.ParamCount > MAX_PARAM_COUNT then
lpData^.ParamCount := MAX_PARAM_COUNT;
for i := 0 to lpData^.ParamCount-1 do
begin
tmp := ParamStr(i+1);
if Length(tmp) > MAX_PARAM_SIZE then
SetLength(tmp, MAX_PARAM_SIZE);
StrCopy(@(lpData^.Params[i,0]), PChar(tmp));
end;
// и съобщава на първия екземпляр
PostMessage(lpData^.FirstInstanceWnd, MSG_NEW_INSTANCE, 0, 0);
// той от своя страна отговаря като отпуска семафора
if not Lock() then
begin
// Няма отговор (Не е получен семафора)
RunAsFirstInstance(lpData);
Exit;
end;
Unlock;
// разрушава се семафора
DestroySemaphore;
// освобождава се общия блок памет
UnmapViewOfFile(lpData);
lpData := nil;
// Не се показва формата на приложението
Application.ShowMainForm:=false;
// Изход
Application.Terminate;
end;
//**************************************************
procedure TOneInstance.Load;
var
lpData : PCommonData;
begin
// Създава се общия блок памет
FMappingHandle := CreateFileMapping(0, NIL, PAGE_READWRITE, 0, sizeof(TCommonData),
PChar(ExtractFileName(ParamStr(0))));
if FMappingHandle <> 0 then
begin
// указател към блока
lpData := MapViewOfFile(FMappingHandle, FILE_MAP_WRITE OR FILE_MAP_READ, 0, 0, sizeof(TCommonData));
if lpData <> Nil then
try
if GetLastError = ERROR_ALREADY_EXISTS then
begin
// Има стартиран екземпляр
RunAsSecondInstance(lpData);
end
else
begin
// Това е първия екземпляр
RunAsFirstInstance(lpDAta);
end;
finally
if lpData <> nil then
UnmapViewOfFile(lpData);
end;
end;
end;
initialization
SingleInstInstance := nil;
finalization
if SingleInstInstance <> Nil then
SingleInstInstance.Free;
end.
----------------------------------------
Щом не върви от първия път, значи има шанс