Skip to main content
5-Regular Member
June 15, 2026
Solved

Web.Link - Recursive Save As Workflow

  • June 15, 2026
  • 7 replies
  • 114 views

Hi all,

I'm working on a Windchill-integrated template library for Creo Parametric (currently on Creo 8, i am updating to 12). The setup is a web-based app (HTML + JavaScript using Pro/Web.Link) that displays a catalog of assembly templates stored in Windchill and allows users to insert them into an active assembly 

The core problem:

When a user selects a template from the catalog, the app needs to do a recursive "Save As" of the entire template hierarchy — renaming every template-owned component to a new order-specific name — before assembling it. This is necessary because each insertion must be independent and order-specific (e.g., MY_PART_0001_CC1234 instead of the original MY_PART_TEMPLATE_CC0000).

In Creo 8 we used a Rename → Save → Rename-back pattern via the API (pfcModel.RenamepfcModel.Save), which worked well:

  1. Check out the template root (pulling all children via CheckoutMultipleObjects with includeDependencies = true)
  2. Build a bottom-up dependency graph
  3. Rename each model to its new target name
  4. Save all renamed models (creating the new files on disk/Windchill)
  5. Rename everything back to the original names in session
  6. Undo-checkout the originals so they are not modified
  7. Retrieve and assemble the newly saved copies

This approach gives us the copies we need without permanently modifying the templates.

The issue in Creo 12:

With Creo 12, it appears that pfcModel.Rename now requires the model to be checked out from Windchill before renaming in session — even temporarily. This works, but it creates a workflow risk: if anything goes wrong between rename and undo-checkout, the templates are left in a checked-out state and other users are locked out. The undo-checkout cleanup works most of the time, but it feels fragile, especially for assemblies with 20+ dependent models.

More importantly, from a governance perspective, we'd prefer a workflow where the original templates are never checked out at all. They are managed, released designs — we don't want them appearing as modified or locked, even temporarily.

What I've tried / considered:

  • pfcModel.CopyAndRetrieve — works for single drawing files, but not for recursive assembly hierarchies where child references need updating
  • ExecuteFeatureOps(CreateReplaceOp) — throws XToolkitBadContext in Creo's default no-resolve mode, so that's a dead end
  • Windchill server-side copy — pfcWCSServer has some object management methods, but I haven't found a CopyAndRename at the tree level. Is there something in the server API I'm missing?
  • Save to a local workspace first — might avoid the Windchill checkout requirement, but we lose Windchill tracking

What I'm looking for:

Is there an official or recommended workflow in the toolkits, ideally weblink, for doing a non-destructive recursive copy of an assembly, where:

  • The originals are never checked out (or if they must be, are immediately undone with zero modifications)
  • The copies are independently stored and named
  • The child references within the copies point to the new renamed copies, not the originals

Has anyone implemented something like this via Web.Link or toolkit? Is there a Windchill PDMLink server-side API (OOTB or REST) that handles recursive copy-rename that we could call from the browser side?

Any pointers to the right API surface would be hugely appreciated. Thanks in advance!
BR Philipp

Best answer by DaJunti_SE

Hi all,

Following up on my own question — we found the root cause and have a working solution. Sharing it here in case others hit the same wall when migrating from Creo 8 to Creo 12.

Root cause

The Rename → Save → Rename-back pattern still works in Creo 12, but there's one new hard requirement: every model must be explicitly checked out before pfcModel.Rename() is called, not just the root.

In Creo 8, calling CheckoutMultipleObjects on the root with SERVER_DEPENDENCY_ALL was sufficient — renaming worked on the downloaded-but-not-checked-out children. In Creo 12, Windchill enforces a strict checkout gate on Rename(), even for a temporary in-session rename.

The key thing I missed: SERVER_DEPENDENCY_ALL only downloads dependents to the workspace cache — it does not check them out. From the Creo 12.4 Web.Link docs:

SERVER_DEPENDENCY_ALL — All the objects that are dependent on the selected object are downloaded, that is, they are added to the workspace.

The fix

After building the dependency graph and rename plan, add a second checkout pass for all sub-models before the rename phase:

// After buildTargetMap() — checkout every sub-model that needs renaming
function checkoutSubModelsForRename() {
var server = session.GetActiveServer();
var workspace = LibraryState.runtime.workspace;
var urlsToCheckout = [];

for (var i = 0; i < LibraryState.copyOrder.length; i++) {
var fileName = LibraryState.copyOrder[i];
var entry = LibraryState.targetMap[fileName];
if (!entry || !entry.shouldCopy) continue;

// Skip already checked-out models (root was checked out in step 1)
var alreadyCheckedOut = false;
try { alreadyCheckedOut = server.IsObjectCheckedOut(workspace, fileName); } catch(e) {}
if (alreadyCheckedOut) continue;

try { urlsToCheckout.push(server.GetAliasedUrl(fileName)); } catch(e) {}
}

if (urlsToCheckout.length) {
// shouldCheckout=true, includeDependencies=false (already downloaded)
checkoutObjects(urlsToCheckout, false, true);
}
}

The full workflow then becomes:

  1. CheckoutMultipleObjects([rootUrl], checkout=true, SERVER_DEPENDENCY_ALL) — checks out root, downloads all children
  2. Build dependency graph recursively
  3. Build rename plan / target name map
  4. checkoutSubModelsForRename() ← new step for Creo 12
  5. Rename each model bottom-up (pfcModel.Rename)
  6. Save all renamed models (new files created in workspace)
  7. Rename all models back to original names
  8. UndoCheckout all source models — restores originals, discards any local changes

 

Thanks a lot, to everyone for your support.

7 replies

18-Opal
June 15, 2026

What about a local save-as?  Then load the saved-as model and do the recursive rename?

 

This would be quite possible in several tools - Nitro-CELL (costs money, but obvious workflows using Excel and Tables to orchestrate the process and renaming) -- CREOSON (open source - could likely do similar - python library available or JS - Browser accessible if you setup correctly).

 

Just some thoughts.

 

Dave

20-Turquoise
June 15, 2026

The config option let_proe_rename_pdm_objects may affect pfcModel.Rename.

 

Windchill has some api’s that also do this. Check out the EnterpriseHelper.service.newMultiObjectCopy and EnterpriseHelper.service.saveMultiObjectCopy api’s:

https://www.ptc.com/en/support/article/CS59135

https://www.ptc.com/en/support/article/CS430811

https://www.ptc.com/en/support/article/CS108185

RPN
18-Opal
June 15, 2026

I think your approach will not work until your template assemblies are stored in Windchill. Just use a Shared folder to retrieve the assembly. After opening you can rename as long the template folder does not match the current working directory. If you need to keep a model windchill reference, make sure this is not in session, and not found in the folder or search path info, in this case it will be opened from the Server.

 

You could implement in Toolkit ProMdlReadonlyIgnore, but this may still force some popups. If these are templates, believe me, a dfs folder is enough, or just copy from the know location to the local folder and open from here.

 

Oh, I forgot, with the Advanced License and setting the ProMdlReadonlyIgnore Flag, you should be able to do this with temporary created family tables. I guess this is similar to what PTC is doing on coping an assembly and doing some renaming on components. 
You can add an instance of one member and replace this in your structure. For the last step just delete the new member or the whole table and it is independent of the table. 
This is useful for related drawings as well, because you can replace the reference link.

Just add instance on the fly, substitute your models and clean up later.

 

Also check

CS44835

Set config

dm_auto_conflict_resolution yes
dm_checkout_on_the_fly continue

 

If the new assembly is created do an UndoCheckout.

 

5-Regular Member
June 16, 2026

Thanks everyone for the detailed responses! To clarify the constraints:

  • Config changes (let_proe_rename_pdm_objects) are not an option due to company policy
  • Third-party tools and local Save As aren't what I'm looking for — the whole point is building our own zero-deployment webapp (pure HTML + JS in the Creo embedded browser, no backend, no installer)
  • Windchill server-side Java APIs (EnterpriseHelper.service.newMultiObjectCopy) look promising conceptually, but they require a backend component (custom servlet), which breaks the "pure frontend" deployment model

What I'm really after is something I can call directly from Pro/Web.Link JavaScript — no server-side component, no additional infrastructure.

Interestingly, the Web.Link API does have a class called pfcCopyInstructions which looks like exactly what I need. However, its documentation says:

"Not used. Reserved for the future."

Presumably this was intended to be passed to something like a pfcModel.Copy() or similar — but it seems it was never implemented. Does anyone know:

  1. Was pfcCopyInstructions ever actually wired up to a callable method in any Creo version?
  2. Is there any undocumented workaround or Creo command mapper (mapkey/pfcCommand) that could trigger a recursive Save As programmatically from the embedded browser without requiring a checkout?

BR Philipp

18-Opal
June 16, 2026

😂 Ha!  We have seen that “Not used. Reserved for the future.” statement before (in various forms and across multiple languages from PTC - they were literally doing that 15 years ago).  I wish they never did this in their APIs or docs… it is just awful when you find a hint of a solution - but does not even work yet. 😡

 

Just for fun - It would be really interesting to know “how long” we have been waiting on the future.  Specifically, what year did that function show up in the docs as a thing?  That might help us determine when the future is - or is not.

 

It sounds like you are working on something that is a “nice to have” - not a “critical” or “urgent” thing - with an extreme preference for one (1) implementation path. I like the approach and philosophy, but you will find that some PTC interfaces are very limited vs other tools and approaches.

 

I recommend submitting a support ticket with PTC on this - and ask when the future arrives.  It might be in Creo 13.x 🤔

 

Alternatively, as you indicated, think outside the box (mapkeys, trail files) to find a path - these are fragile over multiple versions of Creo.   Hence, if the problem is here and needs to be solved, then you need to look at alternative paths like using CREOSON (you can use JS with that) - but you need to run a server (that comes with it to provide access to the kernel) to provide the interface for commands (not what you don’t want).  If you want more portability, flexibility, and maintainability then Nitro-CELL is an excellent choice - you can use Excel and Excel Tables with Power Query to solve this quickly - and the software and workbooks are portable and only need JLINK installed on each Creo location. (you can download Nitro-CELL and try it for FREE on some small projects to validate).

 

I know this is not the post you wanted - but I think your objectives are clashing with reality on the development/deployment side. ObjectTookit is the ultimate choice (you can include your functionality in Creo Menus as a first class citizen) - but the overhead jumps up quite a bit.

 

Dave

 

 

 

5-Regular Member
June 17, 2026

you are right, not quite the answer i hoped for 😂😓

Still, thanks a lot for the support! It’s actually quite comforting to know I’m not the only one fighting this battle.

RPN
18-Opal
June 16, 2026

You wrote:

let_proe_rename_pdm_objects are not an option due to company policy.

Are you aware that this is exactly what you do!

    In Creo 8 we used a Rename → Save → Rename-back pattern via the API

 Note: This is Creo and you may break a couple of Windchill rules here! And why you renaming the model back, the link to Windchill is already broken..
 

Do you have all your options in a config.sub and no one can change it, but only one godfather can do this😂 

 

Bottom Up dependency graph vs no additional infrastructure, do you really configure your tool to get the correct baseline instead just to open latest? I would just open the root assembly, else you will have fun with coding in assembly changes.


You should use the windchill API to create a copy of an assembly. Expect some time to implement 😂

… ‚which breaks the "pure frontend" deployment model‘ are you kidding here, if this may required, this is a one spot change, but changing the Production environment is a risk🧐

 

If you plan to customize a copy assembly requirement in and with Windchill in use, you can‘t use simplified methods in Creo to break your own rules.

You must decide how much time you want to spend and what is the benefits in time for a user. As far I remember rename with wildcards is supported in Windchill😏, even with WTParts. It may easier to write a help page to explain the target and how a user can archive this.

Your solution must be maintained for some versions …

 

And replace will only work for interchange and FamTabs! You can’t just replace a component.

 

Some Cents from my side 😎

DaJunti_SE5-Regular MemberAuthorAnswer
5-Regular Member
June 23, 2026

Hi all,

Following up on my own question — we found the root cause and have a working solution. Sharing it here in case others hit the same wall when migrating from Creo 8 to Creo 12.

Root cause

The Rename → Save → Rename-back pattern still works in Creo 12, but there's one new hard requirement: every model must be explicitly checked out before pfcModel.Rename() is called, not just the root.

In Creo 8, calling CheckoutMultipleObjects on the root with SERVER_DEPENDENCY_ALL was sufficient — renaming worked on the downloaded-but-not-checked-out children. In Creo 12, Windchill enforces a strict checkout gate on Rename(), even for a temporary in-session rename.

The key thing I missed: SERVER_DEPENDENCY_ALL only downloads dependents to the workspace cache — it does not check them out. From the Creo 12.4 Web.Link docs:

SERVER_DEPENDENCY_ALL — All the objects that are dependent on the selected object are downloaded, that is, they are added to the workspace.

The fix

After building the dependency graph and rename plan, add a second checkout pass for all sub-models before the rename phase:

// After buildTargetMap() — checkout every sub-model that needs renaming
function checkoutSubModelsForRename() {
var server = session.GetActiveServer();
var workspace = LibraryState.runtime.workspace;
var urlsToCheckout = [];

for (var i = 0; i < LibraryState.copyOrder.length; i++) {
var fileName = LibraryState.copyOrder[i];
var entry = LibraryState.targetMap[fileName];
if (!entry || !entry.shouldCopy) continue;

// Skip already checked-out models (root was checked out in step 1)
var alreadyCheckedOut = false;
try { alreadyCheckedOut = server.IsObjectCheckedOut(workspace, fileName); } catch(e) {}
if (alreadyCheckedOut) continue;

try { urlsToCheckout.push(server.GetAliasedUrl(fileName)); } catch(e) {}
}

if (urlsToCheckout.length) {
// shouldCheckout=true, includeDependencies=false (already downloaded)
checkoutObjects(urlsToCheckout, false, true);
}
}

The full workflow then becomes:

  1. CheckoutMultipleObjects([rootUrl], checkout=true, SERVER_DEPENDENCY_ALL) — checks out root, downloads all children
  2. Build dependency graph recursively
  3. Build rename plan / target name map
  4. checkoutSubModelsForRename() ← new step for Creo 12
  5. Rename each model bottom-up (pfcModel.Rename)
  6. Save all renamed models (new files created in workspace)
  7. Rename all models back to original names
  8. UndoCheckout all source models — restores originals, discards any local changes

 

Thanks a lot, to everyone for your support.

18-Opal
June 23, 2026

Cool - there is always an option / configuration sequence hidden in the cracks it seems.  Glad you got it working.

I am not sure why you need a dependency graph for a rename and save of files.  Just load the highest level parents in to session (Assemblies, Drawings) where these are contained - and just rename, regenerate all, and save as…

Dave