uses
  SHFolder, ShlObj, ComObj, ActiveX;

 

 

// lnk 구조체
type
  PShellLinkInfoStruct=^TShellLinkInfoStruct;
  TShellLinkInfoStruct=record
    FullPathAndNameOfLinkFile: array [0..MAX_PATH] of Char;
    FullPathAndNameOfFileToExecute: array [0..MAX_PATH] of Char;
    ParamStringsOfFileToExecute: array [0..MAX_PATH] of Char;
    FullPathAndNameOfWorkingDirectory: array [0..MAX_PATH] of Char;
    Description: array [0..MAX_PATH] of Char;
    FullPathAndNameOfFileContainingIcon: array [0..MAX_PATH] of Char;
    IconIndex: Integer;
    HotKey: WORD;
    ShowCommand: Integer;
    FindData: TWIN32FINDDATA;
  end;

 

 

 

 

 

 

// lnk 구조체에 해당 정보를 박아 넣기
procedure GetLinkInfo(lpShellLinkInfoStruct: PShellLinkInfoStruct);
var
  ShellLink: IShellLink;
  PersistFile: IPersistFile;
  AnObj: IUnknown;

 

begin
  // 준비작업...
  AnObj:=CreateComObject(CLSID_ShellLink);
  ShellLink:=AnObj as IShellLink;
  PersistFile:=AnObj as IPersistFile;

 

  // 바로가기 파일이름으로 불러오기
  PersistFile.Load(PWChar(WideString(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile)), 0);

 

  with ShellLink do begin
    // 실행파일 경로
    GetPath(lpShellLinkInfoStruct^.FullPathAndNameOfFileToExecute,
            SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile),
            lpShellLinkInfoStruct^.FindData,
            SLGP_UNCPRIORITY);

    // 설명
    GetDescription(lpShellLinkInfoStruct^.Description,
                   SizeOf(lpShellLinkInfoStruct^.Description));

    // 실행파라메터
    GetArguments(lpShellLinkInfoStruct^.ParamStringsOfFileToExecute,
                 SizeOf(lpShellLinkInfoStruct^.ParamStringsOfFileToExecute));

    // 디렉토리
    GetWorkingDirectory(lpShellLinkInfoStruct^.FullPathAndNameOfWorkingDirectory,
                        SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfWorkingDirectory));

    // 아이콘
    GetIconLocation(lpShellLinkInfoStruct^.FullPathAndNameOfFileContainingIcon,
                    SizeOf(lpShellLinkInfoStruct^.FullPathAndNameOfFileContainingIcon),
                    lpShellLinkInfoStruct^.IconIndex);

    // 핫키
    GetHotKey(lpShellLinkInfoStruct^.HotKey);

    // 커맨드
    GetShowCmd(lpShellLinkInfoStruct^.ShowCommand);
  end;
end;

 

 

 


// 바로가기 구조체 포인터를 받아서 실행파일 세팅
procedure SetLnkExePath(lpShellLinkInfoStruct: PShellLinkInfoStruct; Path: String);
var
  ShellLink: IShellLink;
  PersistFile: IPersistFile;
  AnObj: IUnknown;

 

begin
  // 준비작업
  AnObj:=CreateComObject(CLSID_ShellLink);
  ShellLink:=AnObj as IShellLink;
  PersistFile:=AnObj as IPersistFile;

 

  // 불러오기
  PersistFile.Load(PWChar(WideString(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile)), 0);

 

  // 실행파일 변경
  ShellLink.SetPath(PChar(Path));

 

  // 변경사항 저장
  PersistFile.Save(PWChar(WideString(lpShellLinkInfoStruct^.FullPathAndNameOfLinkFile)), False);
end;

 

 

 

 


// 시작메뉴 > 프로그램에서 .lnk 파일들을 뒤져 실행파일이 TEST.EXE 인 것을 찾아
// TESTTEST.EXE 로 변경

procedure FindTestEXE(FindPath: String);
var
  SR: TSearchRec;
  retInt: Integer;
  lnkInfo: TShellLinkInfoStruct;


begin
  retInt:=FindFirst(FindPath+'\*.*', faAnyFile, SR);
  while retInt=0 do begin
    // 현재 디렉토리, 상위 디렉토리가 아닐 때
    if SR.Name[1]<>'.' then begin
      // 만약 디렉토리면 재귀호출
      if (SR.Attr and faDirectory)=faDirectory then FindTestEXE(FindPath+'\'+SR.Name)
      // 파일일 경우
      else begin
        // .lnk 파일 (=바로가기 파일) 일 경우 의심을 해봄
        if LowerCase(ExtractFileExt(SR.Name))='.lnk' then begin
          ZeroMemory(@lnkInfo, SizeOf(lnkInfo));
          StrPCopy(lnkInfo.FullPathAndNameOfLinkFile, FindPath+'\'+SR.Name);
          GetLinkInfo(@lnkInfo);
          // 연결된 실행파일이 TEST.EXE 일 경우 TESTTEST.EXE 로 변경
          if Pos('TEST.EXE', UpperCase(lnkInfo.FullPathAndNameOfFileToExecute))>0 then begin
            SetLnkExePath(@lnkInfo, 'C:\경로명\TESTTEST.EXE');
            break;
          end;
        end;
      end;
    end;
    retInt:=FindNext(SR);
  end; // while
  FindClose(SR);
end;

 

 

 

 

 

 

procedure TForm1.Button1Click(Sender: TObject);
var
  Path: array [0..255] of Char;
begin
  // 시작메뉴 > 프로그램 경로를 얻어와서
  SHGetFolderPath(0, CSIDL_PROGRAMS, 0, 0, Path);

  // 원하는 바를 이룸
  FindTestEXE(Path);
end;









Posted by bloodguy
,