rexx-things/modules/windows/ole/oleinfo/listProgIds.rex
2025-03-12 20:50:48 +00:00

124 lines
6.0 KiB
Rexx

/*----------------------------------------------------------------------------*/
/* */
/* Copyright (c) 2002-2022 Rony G. Flatscher. All rights reserved. */
/* Copyright (c) 2023 Rexx Language Association. All rights reserved. */
/* */
/* This program and the accompanying materials are made available under */
/* the terms of the Common Public License v1.0 which accompanies this */
/* distribution. A copy is also available at the following address: */
/* https://www.oorexx.org/license.html */
/* */
/* Redistribution and use in source and binary forms, with or */
/* without modification, are permitted provided that the following */
/* conditions are met: */
/* */
/* Redistributions of source code must retain the above copyright */
/* notice, this list of conditions and the following disclaimer. */
/* Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in */
/* the documentation and/or other materials provided with the distribution. */
/* */
/* Neither the name of Rexx Language Association nor the names */
/* of its contributors may be used to endorse or promote products */
/* derived from this software without specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */
/* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */
/* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY */
/* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/*----------------------------------------------------------------------------*/
/***********************************************************************
name: listProgIds.rex
purpose: list all ProgIDs to stdout, optionally with their CLSID
usage: listProgIds.rex
listProgIds.rex needle
listProgIds.rex 1
listProgIds.rex 1 needle
... needle: optional: a string, list ProgIdDs that contain this string (caseless comparison)
... 1 optional: supply CLSID
***********************************************************************/
parse arg indicator needle .
bCLSID=(indicator=1)
if \bCLSID then needle=indicator -- shift to needle
bTiming=.false -- .true -- determines whether timings are shown
time0=.DateTime~new
.clsid~analyze_and_build -- let the class method query and analyze the registry,
all_progid= .clsid~all_progid -- get ProgID directory
time1=.DateTime~new
if bTiming then say "analyzing registry time spent:" pp(time1-time0)
-- sort all ProgID indixes caselessly
allProgIds = all_progid~allIndexes~sortWith(.CaselessComparator~new)
time2=.DateTime~new
items=allProgIds~items
if bTiming then
do
say "sorting" items "took:" pp(time2-time1)
say
end
prefix=.rexxinfo~architecture"-bit #"
len=items~length
bDots=.false
do counter i idx over allProgIds -- idx is the ProgID
if needle<>"", idx~caselessPos(needle)=0 then iterate
o=all_progid~at(idx) -- get ooRexx classid object
hint=checkProgId(idx) -- supply hint whether ProgID adheres to MS specs
if bCLSID then
do
if bDots then
say prefix i~right(len)"/"items":" "ProgId:" pp(idx)~left(70,".") || hint~left(5,".") "CLSID:" o~clsid
else
say prefix i~right(len)"/"items":" "ProgId:" pp(idx)~left(70) || hint~left(5) "CLSID:" o~clsid
bDots=\bDots
end
else
say prefix i~right(len)"/"items":" "ProgId:" pp(idx)~left(70) || hint~left(5)
end
time3=.DateTime~new
if bTiming then
do
say "output took: " pp(time3-time2)
say "total time: " pp(time3-time0)
end
::requires "reg_classids4ole.cls" -- get support for analyzing the registry
::routine pp
return "["arg(1)"]"
::routine checkProgId -- checks whether ProgID adheres to Microsoft's specifications
use arg progid
-- check validity of ProgId according to: <https://docs.microsoft.com/en-us/windows/win32/com/-progid--key>:
-- length<=39, no punctuation (except dots), not start with a digit, ..
-- also discussion at: <https://stackoverflow.com/questions/1754429/what-happens-if-i-violate-the-requirements-imposed-on-progids>
hint=""
-- too long or empty string?
if progid~length >39 then hint="l"
else if progid="" then hint="l"
-- illegal character?
if verify(progid,"ABCDEFGHIJKLMNOPQRSTUVWXYZ.abcdefghijklmnopqrstuvwxyz0123456789")>0 then hint||="c"
-- must not start with a digit
if datatype(progid[1],"W") then hint="d"
if hint<>"" then return "*"hint"*"
return hint