需要在ExtendScript中为Windows系统生成UUID

时间:2019-05-24 09:07:07

标签: javascript powershell adobe extendscript

我已使用以下代码为.indd文件的链接生成DocumentIDInstanceID,这些链接在Mac系统上可以正常工作。 Windows系统上是否有任何指向类似的UUID生成代码,Windows系统上是否有可用的此类库?

function generateUUID() {
  var cmd = 'do shell script "uuidgen | tr -d " & quoted form of "-"';
  return app.doScript(cmd, ScriptLanguage.applescriptLanguage);
}

var genDocID = 'xmp.did:' + generateUUID();

2 个答案:

答案 0 :(得分:1)

TLDR; 以下是通过的ExtendScript API在Windows系统上生成UUID的几种不同方法...

  • 解决方案A “掏空” 通过VBScript到Windows Powershell的命令。但是,此解决方案确实需要安装Windows PowerShell,并具有运行VBScript的权限。

  • 解决方案B 利用InDesign本身来生成UUID。它通过创建临时.indd文档并将其提取为DocumentID来实现。该解决方案可以成功地跨平台(在MacOS和Windows上)运行,不需要其他依赖项,并且比 Solution A 更具性能,因为它不必像解决方案A 可以。


解决方案A:

Windows上的默认外壳,即cmd.exe不提供内置的实用程序来生成通用唯一标识符(UUID)。这与Mac OS和其他 * nix 平台上可用的Bash实用程序uuidgen形成对比。

但是,可以通过执行以下命令通过Windows 生成UUID:

[guid]::Newguid()

以下Adobe ExtendScript(win-generate-uuid.jsx)演示了如何利用上述PowerShell命令生成UUID。

注意:此解决方案要求:

  • 要安装的Windows PowerShell。
  • 允许Windows运行

win-generate-uuid.jsx

/**
 * Generates a unique identifier (UUID/GUID) by running a VBScript that
 * executes a PowerShell command.
 * @returns {String} - The generated unique identifier.
 */
function generateUUID() {
  var pwshCmd = '$guid = [guid]::Newguid(); $guid = [string]$guid';
  var vbScript = [
    'CreateObject("WScript.Shell").Run "powershell.exe -command ""' +
        pwshCmd + '"" | clip", 0, True',
    'guid = CreateObject("htmlfile").ParentWindow.ClipboardData.GetData("text")',
    'returnValue = Replace(guid, "-","")'
  ].join('\r');

  return app.doScript(vbScript, ScriptLanguage.visualBasic);
}

var genDocID = 'xmp.did:' + generateUUID();
$.writeln(genDocID);

说明:

  1. generateUUID中的win-generate-uuid.jsx函数利用InDesign的doScript()方法来运行VBScript。

  2. 执行的VBScript本质上是使用Run()命令运行上述PowerShell命令(尽管版本有所修改)。

    注意:有必要利用VBScript对PowerShell命令进行“ emshell” ,因为在Windows上运行的InDesign仅允许通过VBScript或JavaScript来执行{{1 }}方法。

  3. PowerShell命令的结果(即生成的UUID)通过管道(doScript)到剪贴板。

  4. 随后;

    • 从剪贴板中检索UUID。
    • 在最终|将其添加到-脚本之前,将生成的UUID中的所有连字符(return)删除。
  5. 有关使用VBScript的.jsx的原因(结合到剪贴板的管道)而不是VBScript的Exec()的更多解释,请参考this answer。原因总结如下;

    • Run()不显示PowerShell窗口。
    • Run()确实简要显示了PowerShell窗口。

解决方案B:

一种用于生成UUID的跨平台解决方案(即在MacOS和Windows上成功运行的解决方案)是利用InDesign本身。下面的Exec()中对此进行了演示。

generate-uuid.jsx

generate-uuid.jsx

说明:

#target indesign $.level=0 /** * Loads the AdobeXMPScript library. * @returns {Boolean} True if the library loaded successfully, otherwise false. */ function loadXMPLibrary() { if (!ExternalObject.AdobeXMPScript) { try { ExternalObject.AdobeXMPScript = new ExternalObject('lib:AdobeXMPScript'); } catch (e) { alert('Failed loading AdobeXMPScript library\n' + e.message, 'Error', true); return false; } } return true; } /** * Generates a unique identifier (UUID/GUID) cross-platforms (macOS/Windows). * @returns {String} - The generated unique identifier. */ function generateUUID() { var tmp_FilePath = File(Folder.temp + '/__temp__.indd'); // 1. Create temporary .indd and save it to disk. var newDoc = app.documents.add(false); newDoc.save(tmp_FilePath); newDoc.close(); // 2. Extract the DocumentID from temporay .indd var xmpFile = new XMPFile(tmp_FilePath.fsName, XMPConst.FILE_INDESIGN, XMPConst.OPEN_FOR_READ); var xmp = xmpFile.getXMP(); var documentID = xmp.getProperty(XMPConst.NS_XMP_MM, 'DocumentID', XMPConst.STRING); // 3. Delete temporary .indd tmp_FilePath.remove(); // 4. Return the DocumentID without the default `xmp.did:` prefix. return String(documentID).replace(/xmp\.did:/g, ''); } if (loadXMPLibrary()) { var genDocID = 'xmp.did:' + generateUUID(); $.writeln(genDocID); } 脚本(上面)包含一个名为generate-uuid.jsx的函数,该函数基本上执行以下操作:

  1. 创建一个新的InDesign文档(generateUUID)并将其保存到操作系统的临时文件夹中,然后将其关闭。该任务在后台执行,因此用户将不知道实际文档已创建。

    注意:操作系统的默认临时目录是通过Folder.temp确定的。为了进一步了解每个操作系统中temporay文件夹的位置,您可以将以下代码行临时添加到脚本中,并将其路径名记录到您的ExtenScript控制台中:

    .indd
  2. 接下来,我们利用XMP scripting API的功能从新创建的临时$.writeln(Folder.temp); 文件中提取DocumentID-您应该从我对先前问题的回答中熟悉这些内容; hereherehere

  3. 然后,我们删除名为.indd的临时.indd文件。
  4. 最后,从提取的__temp__.indd中删除默认的xmp.did:前缀。

    注意:documentID函数的主体中删除了默认的xmp.did:前缀,然后将其恢复了,这似乎有些奇怪!我这样做是有意的,以便使generateUUID更具可重用性。例如;您可能希望使用它来生成generateUUID等,在这种情况下,您可能需要在UUID的前面加上InstanceID

答案 1 :(得分:0)

我使用以下简单的JS函数来避免Mac和Windows的问题,并为此提供了多种功能。

// JS - Generate Global Random Unique Number
function generateJsUUID(){
    var dt = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (dt + Math.random()*16)%16 | 0;
        dt = Math.floor(dt/16);
        return (c=='x' ? r :(r&0x3|0x8)).toString(16);
    });
    return uuid;
}