is there an api call for creating a Work Area from a template work area?

just wondering if there is a API call out there to create a Work Area from a template work area.

  • "Words get in the way" again!  "Work Area" is still referred to as "Rich Projects" in the PW SDK and not likely to be renamed.

    Yes, there is an API call for creating a "Work Area" from a template, and it is a lot less work than trying to create a Work Area, and all the parts by API code (lots of decisions to be made!).

    Take a look at aaApi_CopyProjectWithHierarchy().

    A word of warning though.  When you copy the template, you can't specify a different name for the new Work Area, so you need to make sure that there isn't a folder with that name already, as well as renaming the folder after the copy.  Not as straight forward as you may like...

    Here's a method (in C#) that I have used, but it is dependent upon some objects built and populated elsewhere (to lookup some values previously determined), but it gives you an idea of the "flow" that I use. 

            /// <summary>
            /// Creates a ProjectWise Project folder of ProjectTypeLabel type. 
            /// </summary>
            /// <param name="parentFolderId">Folder Id of the parent.</param>
            /// <param name="newProjectName">New PW Project name.</param>
            /// <param name="projectTypeLabel">Project Type (label as seen in the PWA).</param>
            /// <returns></returns>
            public static int BuildProjectFolderByProjectType(int parentFolderId, string newProjectName, string projectTypeLabel)
            {
                if (!PwProjectTypeMapping.GetTemplateFolderIdFromProjectTypeLabel.ContainsKey(projectTypeLabel))
                {
                    LogIt.WriteLogError("Project Type '{0}' is not mapped to a Project Template!", projectTypeLabel);
                    return 0;
                }
    
                string parentFolderPath = PWWrapper.GetProjectNamePath(parentFolderId);
    
                if (parentFolderPath.EndsWith("\\"))
                    parentFolderPath = parentFolderPath.Remove(parentFolderPath.Length - 1, 1);
    
                string fullPathOfCopiedProject = string.Format(@"{0}\{1}", parentFolderPath, PwProjectTypeMapping.GetTemplateFolderNameFromProjectTypeLabel[projectTypeLabel]);
    
                IntPtr fpCallBack = IntPtr.Zero;
                IntPtr aauserparm = IntPtr.Zero;
                int projectCount = 0;
                bool projectWasCopied;
                int newlyCreatedProjectId = 0;
    
                // unfortunately, this function doesn't return the id of the newly created folder!
                // copy options hard coded for now...
                projectWasCopied = PWWrapper.aaApi_CopyProjectWithHierarchy(
                    PwProjectTypeMapping.GetTemplateFolderIdFromProjectTypeLabel[projectTypeLabel], // Source template Project Id
                    parentFolderId,                                                     // Target (parent) Project Id
                    PWWrapper.ProjectCopyDeleteAndExportFlags.Attributes |              // ulRootFlags
                    PWWrapper.ProjectCopyDeleteAndExportFlags.Components |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyAccess |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyEnvironment |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyManager |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyResources |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopySavedSearch |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyStorage |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyWorkflow |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyWorkspaceProfile |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.DelManagedWorkspaceVars |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.SetReferences,            // ulHierarchyFlags
                    PWWrapper.ProjectCopyDeleteAndExportFlags.Attributes |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.Components |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyAccess |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyEnvironment |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyManager |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyResources |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopySavedSearch |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyStorage |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyWorkflow |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.CopyWorkspaceProfile |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.DelManagedWorkspaceVars |
                    PWWrapper.ProjectCopyDeleteAndExportFlags.SetReferences,
                    fpCallBack,
                    aauserparm,
                    ref projectCount                                                    // how many folders were created
                    );
    
                // capture any pw errors...
                if (!projectWasCopied)
                {
                    LogIt.WriteLogError(string.Format("Could not copy template to: '{0}'.", fullPathOfCopiedProject));
                    LogIt.WriteLogPwError();
                }
    
                // get new folder info if one was created
                if (projectCount > 0)
                {
                    LogIt.WriteLogOnlyInfo("{0} folders were copied from Template '{1}'.", projectCount, projectTypeLabel);
                    uint uFlag = 32;
                    int bogusTargetDocId = 0;
                    IntPtr hBuf = IntPtr.Zero;
    
                    if (!PWWrapper.aaApi_SelectSubProjectChainByNameDataBuffer(uFlag, fullPathOfCopiedProject, null, null, ref newlyCreatedProjectId, ref bogusTargetDocId, ref hBuf))
                    {
                        LogIt.WriteLogError(string.Format("Problem selecting newly copied project '{0}'.", fullPathOfCopiedProject));
                        LogIt.WriteLogPwError();
                        return 0;   // no point in continuing...
                    }
                }
    
                // return if copied failed, but first clean up if at least one folder was created
                if (!projectWasCopied)
                {
                    if (projectCount > 0)
                    {
                        int folderCount = 0;
                        if (!PWWrapper.aaApi_DeleteProject(newlyCreatedProjectId, 0, IntPtr.Zero, IntPtr.Zero, ref folderCount))
                        {
                            LogIt.WriteLogError(string.Format("Problem deleting partially copied project '{0}'.", fullPathOfCopiedProject));
                            LogIt.WriteLogPwError();
                        }
                    }
    
                    return 0;
                }
    
                // copy worked, but we need to rename it
                PWWrapper.VaultDescriptor vaultDescriptor = new PWWrapper.VaultDescriptor();
                vaultDescriptor.projFlags = 0x00000080 | 0x00000100;        // AADMSPROJF_NAME   0x00000080,  AADMSPROJF_DESC   0x00000100
                //vaultDescriptor.projFlagMask = (uint)0x00004000;
                vaultDescriptor.Flags = (uint)(
                    PWWrapper.VaultDescriptorFlags.Name |
                    PWWrapper.VaultDescriptorFlags.VaultID);
    
                vaultDescriptor.Name = newProjectName;
                vaultDescriptor.VaultID = newlyCreatedProjectId;
    
                if (!PWWrapper.aaApi_ModifyProject2(ref vaultDescriptor))
                {
                    LogIt.WriteLogError(string.Format("Problem renaming newly copied project '{0}'.", fullPathOfCopiedProject));
                    LogIt.WriteLogPwError();
    
                    // delete the newly copied project so that it doesn't get in the way next time
                    int folderCount = 0;
                    if (!PWWrapper.aaApi_DeleteProject(newlyCreatedProjectId, 0, IntPtr.Zero, IntPtr.Zero, ref folderCount))
                    {
                        LogIt.WriteLogError(string.Format("Problem deleting newly copied project '{0}'.", fullPathOfCopiedProject));
                        LogIt.WriteLogPwError();
                    }
                    return 0;
                }
    
                LogIt.WriteLogInfo(@"Project '{0}\{1}' created.", fullPathOfCopiedProject, newProjectName);
    
                return newlyCreatedProjectId;
            }
    

    Oh, and the "PWWrapper" class, is really just "MostOfDavesClasses" as mentioned in other postings! 

    You can get MostOfDavesClasses from here:

    https://github.com/DaveBrumbaugh/MostOfDavesClasses-CSharp-Wrappers-For-ProjectWise 

    You will need to distribute the included .dll's in order to use all of the methods.

    You can get DllExporterNet4 from nuget.org.

    DllExporterNet4 makes it possible to call static methods from unmanaged code, i.e. ProjectWise .mrr files, ProjectWise Custom Modules, etc. 

    Hope this helps!

    Dan Williams
    Solution Consultant
    Bentley Systems, Incorporated
    Portland, OR, USA (Pacific Time UTC-08:00)

    Answer Verified By: John Drsek