Color scheme: Dark
You are here: start » en » Documentation » Microsoft Access development tools » WKL Office SDK » WKL Office SDK reference » Command-line reference: wkl-office

Command-line reference: wkl-office

wkl-office is the command-line tool of the WKL Office SDK. Every other tool of the SDK (the MSBuild tasks, the tasks of Visual Studio Code) calls the same code, so a command decides the same way wherever it runs.

Signature

wkl-office <command> <project.acproj | folder | file> [options]
wkl-office diff <project.acproj> <object | file> [options]
wkl-office call <project.acproj | database> <function> [argument ...] [options]
wkl-office test <project.acproj> [options]
wkl-office texts export | import <project.acproj> [<file.csv>]
wkl-office addin install | remove | status
wkl-office settings list | get <key> | set <key> [<value>]
CommandPurpose
`new`Creates an empty project.
`check`Checks the sources and the machine without starting Access.
`build`Builds the database of a configuration.
`rebuild`Removes the results of a configuration, then builds.
`run`Builds and opens the database in a visible Access.
`open`The command a double-click on a project file runs: opens the database built earlier, builds only when there is none.
`validate`Checks a database built earlier against the sources.
`accde`Makes the ACCDE from the ACCDB built earlier.
`export`Writes a database into the sources.
`import`Loads changed object sources into the database open in Access.
`status`Lists the objects that changed in the database or in the sources.
`sync`Carries changes over in both directions.
`changes`The overview of changes: Access against the sources, the sources against the last commit, the branch against its remote, with the next step for each row.
`diff`The full difference of one object or source file, against Access or against the last commit.
`commit`Checks again, exports, then commits the project's files into git or svn.
`push`Pushes the commits of the branch.
`addin`Registers, removes or reports the Access developer add-in for the current user.
`settings`Lists, reads or writes the settings of the SDK for the current user.
`roundtrip`Builds a copy (without ACCDE) and exports it, to show that the sources are stable.
`migrate`Converts a project of the DATEC Access SDK or of the build tool of WKL Forms Object Library; without -o, moves a project to WKL Forms Object Library 2.0 in place.
`deliver`Builds the delivery profiles of the project and puts each together for WKL Bootstrapper.
`msi`Builds the Windows Installer package of a delivered target.
`call`Calls a public VBA function of the built database in a hidden Access and prints its return value.
`test`Builds, then runs the test procedures of the application in a hidden Access and reports each check.
`texts`Exchanges the application texts of the project with one CSV file for Excel.

Options

OptionCommandsDefaultMeaning
-c, --configuration <name>all with a projectDebugThe build configuration; its results go to build/<name>/.
--accde, --no-accdebuild, rebuildthe project's AccdeMakes the ACCDE or not, regardless of the project.
-d, --database <file>export, import, status, sync, commit, changes, diffbuild/<configuration>/<name>.accdbThe database to read or change.
--changedexport, importoffCarries only the objects that changed since the last common state (change tracking).
--keep access | --keep sourcesyncnoneDecides objects changed on both sides.
--diffsyncoffShows the first differing line of each object changed on both sides; decides nothing.
-m, --message <text>commit (required)–The commit message.
--against access | --against gitdiffaccess when Access and the source differ, else gitWhat the source is compared with.
--part design | --part codediffbothOnly the design or only the code of a form or report.
-n, --name <name>newthe folder nameThe name of the application.
-o, --output <folder>migrate (to convert)–The folder of the new project. Without it, migrate moves the project to WKL Forms Object Library 2.0 in place.
--runtimerunoffStarts Access with /runtime and opens the ACCDE when one was built.
--no-buildrun, testoffUses the database built earlier without building.
-p, --profile <name>deliver, msi (required for msi)every profileThe delivery profile (delivery\<name>.profile.json; in format 1 the mode of a target) to deliver, or whose package to build.
-t, --target <name>deliver, msievery profileThe same as -p.
--version <x.y.z>deliver, msiversion of delivery-settings.json; for msi the starter'sThe version written into the manifests, or of the package.
--dependenciesdeliveroffOnly lists what a delivery carries along and where it comes from; builds nothing.
--whatifdeliver, migrate without -ooffdeliver: after the delivery, the starter's dry run (/whatif) of each target. migrate: lists the changes and writes nothing.
--sign <thumbprint>msiunsignedSigns the package with this code signing certificate.
-t, --target accdb | accdecall, testaccdbWhich build result of the project to use; test builds the ACCDE for accde.
--work <folder>call, testcall: a temporary folder, deleted afterwards; test: build/<configuration>/testThe folder for the copy of the database; it is kept, together with what the function or the tests wrote there.
--timeout <s>call, test120The time limit of the call, or of each test procedure, in seconds (1 to 86400).
--only <names>testallRuns only these test procedures and groups, separated by commas; a name also selects the procedures that start with it and an underscore (Orders selects Orders_Create).
--no-count-guardtestoffDoes not fail a run that has fewer checks than the last green one.
--language <code>test, texts exporttest: the language Access chooses; texts export: all languagestest: the language of the run for the application texts and the WKL components. texts export: the language of the translation package. Any language code such as de, fr or sl-SI (counts as sl).
--replacetexts importmergeOne CSV file is the whole set of texts; keys missing in it are removed.
--lock-file <file>the commands that start Access (see below)WKL_ACCESS_LOCK_FILE, else noneThe machine lock: one Access run at a time on this computer (one Access run at a time per computer).
--lock-wait <s>the commands that start Access600How long to wait for the machine lock, in seconds (0 to 86400); 0 gives up at once.
--jsonalloffPrints the result as one JSON object (JSON output).
--format msbuildalloffPrints each problem as an MSBuild line (problem lines).

An option a command does not take, an unknown option, a wrong value or a missing argument ends the run with exit code 1. Standard error then shows one line that names the command and what is wrong, and a pointer to wkl-office --help; wkl-office without anything prints the whole usage text. wkl-office --help (also -h, -?, help) prints the usage text on standard output and ends with exit code 0.

One run at a time per project. The commands that write (build, rebuild, run, open, validate, accde, export, import, status, sync, commit, roundtrip, deliver, msi, test, texts) hold the file obj/wkl-sdk.lock next to the project file while they work. A second one started meanwhile, from a terminal, from dotnet build or from the add-in, ends at once with exit code 10 and names the run that holds the project (process id, program, command, since when); nothing was done. The lock ends with the run, also when it is killed, so there is nothing to clean up: the lock is the file held open, not the file itself. The file stays behind with the details of the last run; without that run it means nothing, and the folder obj may be deleted. check, call, changes, diff, push, new, migrate and addin take no lock.

One Access run at a time per computer (optional). When several people or sessions share one desktop, their Access runs disturb each other: dialogs, the foreground, the per-user registration of components. They can agree on one lock file and name it with --lock-file <file> or the environment variable WKL_ACCESS_LOCK_FILE. Every command that starts Access (build, rebuild, run, open, validate, accde, export, import, status, sync, commit, roundtrip, migrate, deliver, msi, call, test) then creates that file before it starts Access and holds it until the run ends; the MSBuild tasks (through the environment variable only) and the operations of the add-in do the same. While another run or tool holds the file, a run waits up to --lock-wait seconds (default 600, MSBuild 600) and names the holder once on standard error; when the file is still there, the run ends with exit code 10 and nothing was done. An operation of the add-in waits as it does for the project and shows machine lock <file>: <holder>.

  • The file holds one name: value per line: holder: (WKL_ACCESS_LOCK_HOLDER, else the user name), since: (UTC), purpose: (the command and project) and process: (process id and program).
  • The SDK creates the file with delete-on-close: Windows deletes it when the run ends, also when the run is killed or crashes, so no stale lock stays behind.
  • A file another tool created (a script with the same convention: create the file exclusively before its run, delete it afterwards) is waited for and never deleted.
  • A script that holds the lock itself and then calls wkl-office sets WKL_ACCESS_LOCK_HELD to the path of the file; the SDK then works under that lock instead of waiting for it.
  • While the SDK holds the file, Test-Path sees it. Only a program that allows the deletion of the file while it reads can read it, in PowerShell [IO.File]::Open($path, 'Open', 'Read', 'ReadWrite, Delete'); Get-Content reports the file as in use.

Without a lock file nothing of this applies.

new

wkl-office new <folder> [-n <name>] [--json]

Creates an empty project in a new or empty folder: <name>.acproj, source/ with an empty references.json, a .gitignore for build/ and obj/, and .vscode/tasks.json. The name becomes the file name of the database and the name of its VBA project, so it has to be a VBA identifier: a letter first, then letters, digits and _, at most 64 characters. Exit code 1 when the name is no identifier or the folder is not empty.

The SDK settings under newProjects decide, for a new project, the folders of the sources, the build and the delivery (SourceRoot, BaseOutputPath, DeliveryRoot), the neutral language, the bitness of Access and the configurations besides Debug and Release. When the settings name a projects folder (newProjects.root), a project given by name only (wkl-office new Customers) is created in it.

check

wkl-office check <project.acproj> [-c <name>] [--json]

Reads the project file and every source, then checks the machine. Starts no Access.

  • Sources: the project file, references.json, application/properties.json, every table schema (and that its file name matches the table), the data files of tables with the policy SeedData or FullData line by line, the relationships, the object folders (unexpected files, a standard and a class module of the same name), the page settings of reports, the finishing function, AppMode, and the placeholders of WKL controls; when the project has a delivery, delivery-settings.json and every delivery profile, including the mode its build configuration sets (delivery-settings.json).
  • Credentials and machine state: every object, data, ribbon and model file (also those of a template), line by line. A password in a connection text (PWD= or Password= with a value) is an error; an empty value is not, and a value that starts with { or contains $ anywhere counts as a placeholder and is not reported either, so an ODBC password in braces (PWD={s3cret}) or one with $ passes; see A password is in the sources. An absolute path into a user profile (C:\Users\<name>\...) is a warning.
  • Machine: the Access that COM starts and its bitness against TargetAccess; every reference against the registered type libraries (same major version, equal or higher minor version, file present for the bitness of Access); every ODBC driver named by the connection profile of the configuration.

Something that cannot be read (a registry key without permission) is reported as unreadable, never as missing. Warnings do not stop a build.

build

wkl-office build <project.acproj> [-c <name>] [--accde | --no-accde] [--json]

Builds build/<configuration>/<name>.accdb and, when the configuration makes one, <name>.accde. Runs check first; nothing is created when it finds an error. The new database is made in build/<configuration>/.building/ and replaces the previous result only when every step succeeded, so a failed build keeps the last good one. The ACCDB and the ACCDE are moved one after the other: when the previous ACCDE is open, the new ACCDB has already replaced the old one and the new ACCDE stays in .building (exit code 5). Do not deliver from build/<configuration>/ after such a failure; build again. The steps are described in Source layout and formats.

When the VBA code does not compile, the build names the objects that break it (exit code 4), without showing a dialog. When the previous result is open in Access or another program, the build fails with “The database is open …” and keeps the new database in .building/ (exit code 5).

rebuild

wkl-office rebuild <project.acproj> [-c <name>] [--accde | --no-accde] [--json]

Removes the ACCDB, the ACCDE and the work folder of the configuration, then builds: nothing of an earlier build survives a failed one. A database that is open is refused.

run

wkl-office run <project.acproj> [-c <name>] [--runtime] [--no-build] [--json]

Builds (unless --no-build) and opens the database in a visible Access, as a double-click would: its start form and startup code run, and that Access belongs to the developer from then on. With --runtime, Access starts with /runtime and opens the ACCDE when one was built; without --runtime the build makes no ACCDE. The only command that shows a window, together with open.

open

wkl-office open <project.acproj> [-c <name>] [--json]

The command a double-click on a project file in Explorer runs, once addin install has set it up. It opens the database built earlier for the configuration in a visible Access without building it again, so changes made in Access and not exported yet stay as they are. Only when that database does not exist yet (a fresh clone) does open build it first. After a git pull that changed the sources, run build or rebuild yourself (export your changes in Access first).

The database opens for development, and nothing starts by itself: the start form and the AutoExec macro do not run, and the startup properties (a custom ribbon, a hidden navigation pane, the Access special keys turned off) do not apply to this start. You see the navigation pane and the Access ribbon with the WKL SDK tab. To do this, open removes the startup properties in a hidden Access before the start and replaces AutoExec with a stand-in that only sets a TempVar; as soon as the database is open, open puts both back. AutoExec is then in the navigation pane again, unchanged, and you can run it yourself right away. The usual ways of opening a database in Access are unchanged: a double-click on the .accdb, File › Open and `run` run the start form and AutoExec as before.

Until they are put back, the backup is kept in the folder <database>.wkl-open next to the database, for example Customers.accdb.wkl-open. When Access ends before that (a crash, ended in Task Manager), the folder stays, and until then the database holds the stand-in instead of your AutoExec and no startup properties, also when you open it with a double-click on the .accdb. The next time the SDK works with that database (open, export, sync, switching projects in the add-in) it first puts the original state back, so the temporary state never reaches the sources. A build that replaces the database drops the backup, because it belongs to the old file. Do not delete the folder yourself: it holds your AutoExec and the startup properties. When Access has not opened the database after 90 seconds, open reports a warning and leaves putting them back to the next time the SDK works with the database.

A build runs VBA code of the project (its finish function) in a hidden Access, without the security warning Access otherwise shows when it opens a database. When the project file is marked as downloaded from the internet (Mark of the Web; a ZIP file downloaded in a browser or received by mail passes the mark on to the files extracted from it), open asks before it builds. Without an answer, also when standard input is redirected, it builds nothing and ends with exit code 8. A clone of a repository carries no such mark.

After a double-click, the console window stays open on a failure until you press Enter, so you can read the problems. Started from a terminal, open never waits.

validate

wkl-office validate <project.acproj> [-c <name>] [--json]

Checks the ACCDB built earlier: the VBA project compiles, no reference is broken, every table and object of the sources is in the database. Works on a copy whose startup properties are removed first, so no start form or ribbon code runs. A database with an AutoExec macro is refused: the database engine cannot switch a macro off.

accde

wkl-office accde <project.acproj> [-c <name>] [--json]

Makes the ACCDE from the ACCDB built earlier. Access reports no error when it makes none, so the command checks that the file exists afterwards and fails with exit code 9 otherwise. The startup properties of AppMode are written only by build.

export

wkl-office export <project.acproj> [-c <name>] [-d <database>] [--changed] [--json]

Writes the database into the sources. A database open in Access is exported from that Access; otherwise from a copy in a hidden Access. Refused while that Access shows a dialog or holds something unsaved, naming each object. A file is rewritten only when its content changed; files of managed folders whose object is gone are deleted and listed. What is written and what is left out: Source layout and formats.

import

wkl-office import <project.acproj> [-c <name>] [-d <database>] [--changed] [--json]

Loads the queries, modules, classes, forms, reports and macros whose source differs from the object into the database open in Access, and adds missing references. Refused while that Access shows a dialog or holds something unsaved. An object to be replaced must be closed. Nothing is deleted; tables, data, relationships, properties and models are not changed in an open database. Does not compile: use Debug > Compile in Access.

status and sync

wkl-office status <project.acproj> [-c <name>] [-d <database>] [--json]
wkl-office sync   <project.acproj> [object ...] [-c <name>] [-d <database>] [--keep access|source] [--diff] [--json]

Compares each query, module, class, form, report and macro on both sides with the last common state, which a full export writes into obj/wkl-state.json (per workstation, not part of the repository).

StatusMeaningCarried over by
ChangedInDatabase, NewInDatabase, DeletedInDatabaseonly the database changedexport --changed, sync
ChangedInSource, NewInSource, DeletedInSourceonly the source changedimport --changed, sync
Renamedan object of another name has the text the old one hadthe matching direction
Conflict, DeletedAndChangedboth sides changed, or there is no common state and they differsync --keep access or --keep source

status changes nothing. Nothing changed on both sides is overwritten: such objects end the run with exit code 7 until --keep decides. Objects named after the project file (form:frmCustomers, module:basLists, the keys that changes --json prints) restrict sync to them: every object is still compared and listed, only the named ones are carried over or decided, so conflicts can be decided one by one. A name that is neither in the database nor in the sources ends the run with exit code 5 and changes nothing. A rename is carried over as a rename only when exactly one object of the same kind has the old text. Carrying changes into the database needs it open in Access. Tables, data, relationships, references, properties and models are not tracked object by object: the full export writes them, build makes them.

changes

wkl-office changes <project.acproj> [-c <name>] [-d <database>] [--json]

Checks the project now and lists every object or source file that is not in step, in one table. Three comparisons are kept apart, because each asks for a different step:

ColumnComparesValues
Access ↔ sourcethe database with the sources, against the last common state (status)changed in Access, changed in source, both changed, in step
Version controlthe source file with the last commit (git or svn status)committed, modified, added, deleted, renamed, untracked, conflicted, - (not a file of the project)
Branch (last line)the local commits with the remote branch, as of the last git fetchcommits to push, commits to pull, or no remote branch

The next step of a row follows from the first two columns, in this order:

Next stepWhen
resolve merge conflictthe version control reports a merge conflict for the file
decide (both sides changed)Access and the source both changed the object
exportonly Access changed it
importonly the source changed it
review diff, commitAccess and the source are in step, the file differs from the last commit

The first line states the time of the check. When a part of the check failed (Access did not answer, the version control reported an error), the first line reads NOT CURRENT, names what failed, and the exit code is 5: the list may be incomplete and never reads as “no changes”. The branch line uses what the last fetch brought; changes does not contact the remote.

diff

wkl-office diff <project.acproj> <object | file> [--against access|git] [--part design|code] [-c <name>] [-d <database>] [--json]

Prints the full difference (unified format, every changed line with three lines of context) of one object or source file. Name the object as changes --json does (form:frmCustomers, module:basLists) or the source file relative to the project (source/forms/frmCustomers.form.txt); the end of the path is enough when it is unique.

  • --against access compares the source (old) with the text Access has now (new): what an export would write.
  • --against git compares the last commit (old) with the source file (new): what a commit would record.
  • --part code keeps only the module of a form or report (from CodeBehindForm on), --part design only the rest.

Without --against, an object that differs between Access and the source is compared with Access, anything else with the last commit. Prints no difference when the texts are the same.

commit

wkl-office commit <project.acproj> -m <message> [<file> ...] [-c <name>] [-d <database>] [--json]

Checks the state again as changes does and refuses, with exit code 7 and nothing written, when a row needs import, decide or resolve merge conflict, or when the check failed: the full export of the commit would overwrite a source changed outside Access, or half-commit a merge. Then exports (refused while something is unsaved), hands the project file, its .gitignore and the source folder to the version control client on the PATH (git or svn; the nearest working copy above the project decides) and commits them. Files the export removed are deleted in the version control as well. Other files of the working copy are not touched, and nothing is pushed. When the sources are as committed, nothing is committed.

Files named after the project (paths relative to the project folder, for example source/forms/frmCustomers.form.txt) commit only those: a partial commit. The check and the export still cover the whole project, so a row that needs import blocks also when its file is not named; the files not named stay changed in the working copy for a later commit. Only the project file, its .gitignore and files under the source root can be named; any other file is refused with exit code 1 before anything happens. A deleted source is named like any other file and is committed as a deletion.

push

wkl-office push <project.acproj> [--json]

Runs git push for the branch of the working copy and prints what git printed. Never part of commit: publishing stays a separate decision. In a Subversion working copy there is nothing to push; the command says so.

addin

wkl-office addin install | remove | status [--json]

Registers the developer add-in of the SDK for the current user (no administrator), removes it, or reports its state. install takes the add-in of the bitness of the installed Access from the folder addin next to the bin folder of the SDK, or from the folder in the environment variable WKL_OFFICE_ADDIN. install also copies WKL Bootstrapper Manager from the folder bootstrapper-manager next to that add-in folder to %LOCALAPPDATA%\Programs\WKL\Bootstrapper Manager\<version>, unless that version is installed already; remove leaves it in place. A build never registers the add-in; only this command does.

install also lists the add-in for the VBA editor of the installed Office, per user under HKEY_CURRENT_USER\Software\Microsoft\VBA\VBE\6.0\Addins (Addins64 for 64-bit Office), so the editor loads it when it opens; remove takes that entry back, and status reports it (editorListed and editorLoadBehavior in JSON).

install also associates project files (.acproj) with the SDK for the current user. A double-click in Explorer runs `open`, and the menu of a project file gets the submenu “WKL Office SDK” with Open, Build and run, Check, Build and Rebuild (the commands open, run, check, build and rebuild); in Windows 11 it is under “Show more options”. The commands use the wkl-office.exe that ran the install, so installing a new version moves them to it. Windows does not let a program make itself the default: at the first double-click on a .acproj it asks once which app opens it; choose “WKL Office SDK” and “Always”. As long as no choice has been made, install says so. The submenu is there whatever program opens the file. Project files show the icon of Access. When .acproj already belongs to another program, it stays with that program, and the SDK is only listed under “Open with”. After Check, Build and Rebuild the window stays open until you press Enter, after Open and Build and run only when something failed. remove takes the association and the submenu back, status reports both (projectFiles and projectFilesChosen in JSON).

The add-in loads with the next start of Access. See Use the Access add-in.

settings

wkl-office settings list | get <key> | set <key> [<value>] [--json]

Shows and changes the SDK settings of the current user (%APPDATA%\WKL\Office SDK\settings.json), as Settings in the add-in does. list shows every setting, get one, each with the value that applies and where it comes from: default, settings or environment with the name of the variable. set writes a value; without a value it removes the entry, so the default applies again. When an environment variable overrides the value written, set warns. Exit code 1 for an unknown setting or a value that does not fit it, 3 when the settings file cannot be read or written; the file is then left as it is.

roundtrip

wkl-office roundtrip <project.acproj> [-c <name>] [--json]

Copies the project into a temporary folder, builds the copy, exports it into the copy and compares the result with the sources. Text files are compared with line ends unified; every other byte counts. Each differing file is listed as changed: <path>:<line>, added: <path> or removed: <path>, the copy is kept for comparison, and the exit code is 6. Paths of differing files are relative to the folder of the project file (changed: source/forms/frmA.form.txt:3). Run it on sources written by export: the first export after migrate rewrites files once. Exit code 0 shows that the sources are stable: the export of the built database writes exactly the sources. It does not show that the sources hold everything the original database had, nor that the application behaves the same (see What the export does not keep). The copy is built without ACCDE and with the connection profile of the configuration; warnings of the export do not fail the roundtrip.

VBA keeps one spelling per identifier across the whole project, including the modules of the template and the names of the referenced libraries: when the built database compiles, Static done As Boolean becomes Static Done As Boolean if Done is spelled that way elsewhere. roundtrip then reports changed: in a module that nobody edited. Use the spelling that the export writes, or rename the identifier.

migrate

wkl-office migrate <old.acproj | access-app.json> -o <folder> [--json]

Converts a project into a new project in <folder>, which must be empty or not exist yet; each setting without a place in the new project is printed as a note. It starts a hidden Access to read the old table definitions (DATEC) or to run the SQL scripts (build tool). See Migrate a project of the DATEC Access SDK and Migrate a project of the build tool of WKL Forms Object Library.

wkl-office migrate <project.acproj | access-app.json> [--whatif] [--json]

Without -o, moves the project in its folder from WKL Forms Object Library 1.x (type library WklComponents) to 2.0 (WklForms), without Access. Release 2.0 renamed the type library and its ProgIDs and kept the class IDs, so forms keep their controls, but every place that names the library changes:

  • the reference in source/references.json (or references of access-app.json): name WklForms, major version 2, minor version 0;
  • the name WklComponents as a whole word in every other text file of the project: modules, forms and reports (Class ="WklComponents.TreeView"), queries, macros, ribbons, models (WklComponents.Texts becomes WklForms.Texts);
  • packages.components of delivery/delivery-settings.json when it names a package of 1.x: the newest package of 2.0 or later below WKL_PACKAGES; without one it stays, with a note.

Files keep their encoding, byte order mark and line ends. Not changed, only named in a note: documentation (*.md) and table data (source/data). The folders build, out, obj, bin and every folder whose name begins with a dot (.git, .vs) are skipped. Each changed file is printed as changed: <file> (<count>) with its changed lines; --whatif prints would change: and writes nothing. Run it once, build the project with release 2.0 registered, and commit. See WKL Forms Object Library, “How to: Move an application to release 2.0”.

deliver

wkl-office deliver <project.acproj> [-p <name>] [--version <x.y.z>] [--dependencies] [--whatif] [--json]

Delivers the delivery profiles of the project (reference), one after the other: in format 2 each file delivery\<name>.profile.json, ordered by name; in format 1 each target of delivery\delivery-settings.json, named after its mode. For each profile it builds the database in the profile's build configuration in a hidden Access (an ACCDE with the startup properties of the mode the configuration sets; Development an ACCDB), then writes build\Delivery\<name>:

build\Delivery\production\
  Wkl.Bootstrapper.exe               the starter, from the bootstrapper release named in delivery-settings.json
  bootstrapper.json                  the starter's project file, a copy of delivery\production.bootstrapper.json
  deploy\
    <name>.accde                     the built database
    app-manifest.json                product, version, target, file, SHA-256, size, bitness, runtime, requires, built
    components\x86\, components\x64\  WKL Forms Object Library from its release package, when the project references it
    json\x86\, json\x64\              WKL Office JSON, when the project references it

To deliver a profile into a different folder, set output in its profile file (format 1: targets[].output in delivery-settings.json; absolute, with environment variables, or relative to the project folder). The folder is written anew every time; a folder chosen with output is emptied only when an earlier delivery wrote it. A missing delivery\<name>.bootstrapper.json is written by the starter from its templates (access, components, json) and kept in the sources; edit it with Bootstrapper Manager. The starter then checks it (/check). requires names the version Access records in the database when it builds: the highest version registered on the build machine with the major version of the reference. Each entry also names the LIBID of the type library (guid): from WKL Bootstrapper 3.2 on, the starter recognizes the library by it; earlier starters ignore it. When a profile fails, the command stops and neither builds nor delivers the profiles after it. Exit code 11 when the delivery could not be put together (a package, the starter or its project file); the build errors keep their codes. See Deliver an application from the SDK.

msi

wkl-office msi <project.acproj> -p <name> [--version <x.y.z>] [--sign <thumbprint>] [--json]

Builds the Windows Installer package of a profile delivered before, with tools\New-StarterMsi.ps1 of the bootstrapper release: the starter and its project file of build\Delivery\<name>, installed once per computer by the IT. Needs the WiX Toolset command line (wix) and, for --sign, signtool.exe of the Windows SDK. Exit code 11 when the profile was not delivered, the tool is missing or it failed; its output is printed.

call

wkl-office call <project.acproj | database> <function> [argument ...] [-c <name>] [-t accdb|accde] [--work <folder>] [--timeout <s>] [--json]

Calls a public function of a standard module of the built database and prints its return value, so a script or a test run can use the code of the application without opening it. With a project file, the database is build\<configuration>\<name>.accdb (with -t accde the .accde); a database file (.accdb, .accde) is used as given. call does not build: run build first.

The function runs in a hidden Access, in a copy of the database:

  • The startup properties of the copy are removed first, so no start form, no ribbon callback and no AutoExec macro runs; a database with an AutoExec macro is refused (exit code 5). A function that needs the setup of the start form calls that code itself.
  • The database itself stays unchanged. The copy is made in a temporary folder and deleted afterwards; with --work <folder> it is made in that folder and kept, together with what the function wrote there.
  • {work} in an argument stands for the full path of the folder of the copy (also of the temporary one): wkl-office call app.acproj ExportOrders "{work}\orders.csv" --work out.
  • The arguments are passed as text. VBA converts them where the function declares a parameter ByVal ... As Long, ByVal ... As Date and so on; a ByRef parameter of another type than String or Variant makes Access refuse the call. At most 30 arguments. Arguments that start with a dash follow --: wkl-office call app.acproj Twice -- -5.
  • The SDK does not hand environment variables to Access. Whether an Access started this way sees those of the calling process depends on how Windows starts it (on Windows 11 it does); a function must not rely on it. Pass such values as arguments.

The return value goes to standard output: text as it is, numbers with a decimal point, True or False, a date as yyyy-MM-dd (with THH:mm:ss when it has a time), Null for Null, nothing for Empty, and the elements of an array on lines of their own.

The call …Exit codeOutput
returned0The value.
raised an error the function does not handle (Err.Raise, a run-time error)12The text of the VBA error.
was refused by Access (no public function of this name, wrong number or type of arguments)12The message of Access.
showed a dialog (MsgBox, InputBox, a form opened as a dialog)14Title and text of the dialog.
did not return within --timeout seconds13The time limit; that Access was ended.
found no database or build result2The path.
could not open the copy (an AutoExec macro)5The reason.
found no Access that starts3The message of Windows.

Dialogs are answered without keyboard input: the VBA error dialog with End, any other dialog with Escape and, when it stays open, with Cancel, No or OK. Access shows a VBA error dialog or a message box on the desktop also when it runs hidden; it disappears within about a second. A function written for call therefore handles its errors and shows no dialogs.

test

wkl-office test <project.acproj> [-c <name>] [-t accdb|accde] [--only <names>] [--timeout <s>] [--work <folder>] [--no-build] [--no-count-guard] [--language <code>] [--json]

Builds the configuration (unless --no-build; with -t accde also the ACCDE), then runs the test procedures of the application in a hidden Access, on a copy of the database in the work folder (default build\<configuration>\test). The project names its test function in <Test> (project file); it returns the names of the test procedures. How to write them: Test an application.

Each procedure runs on its own, with the time limit of --timeout (default 120 seconds):

  • Its checks (WklTest.Check) are printed as OK <procedure>: <check> or FAIL <procedure>: <check> :: <message>. A procedure that returns without a check of its own passes as one line.
  • A run-time error it does not handle is a failed line with the text of the VBA error; the next procedure runs.
  • A dialog that does not go through WklTest.Answer is answered as with `call` and fails the procedure.
  • A procedure that passes its time limit ends its Access; the run stops.
  • When Access ends during a procedure (a crash), the run stops with “Access ended” and names the last line written.

The work folder keeps the copy, wkl-test-run.jsonl (one line per check, written at once, so the lines before a crash are kept) and wkl-test-report.xml (JUnit XML for CI servers, one test case per check). A summary line closes the output: <n> OK, <m> FAIL (<k> test procedures).

Count guard. A run of all procedures that has fewer checks than the last green run of the same configuration, target and language fails with the line check count: tests that stopped running are noticed. The counts are kept in obj\wkl-test-count.json; --only skips the guard, --no-count-guard turns it off.

Language. --language <code> (any language code such as de or fr; a regional code such as sl-SI counts as its language) runs the procedures with the application texts and the WKL components in that language, whatever language Office uses: the SDK sets WklTexts.Language once at the start of the run. It needs WKL Forms Object Library 1.65 or later, a code other than en, de, sl, hr and it 1.67 or later; with an older release the run stops with exit code 2.

The run …Exit code
passed every check0
has a failed check15
stopped at a procedure that passed its time limit13
stopped because Access ended16
found no test function, no procedure (also after --only), or no test module in the database2
could not open the copy (an AutoExec macro)5
did not get past the buildthe code of the build (2, 3, 4, 5, 9)

texts

wkl-office texts export <project.acproj> [<file.csv>] [--language <code>]
wkl-office texts import <project.acproj> [<file.csv> ...] [--replace]

Exchanges the application texts of the project (source/texts/*.json, format) with CSV files that Excel opens directly. Needs no Access.

  • export writes one row per key of any language with the columns key, then one per language present, neutral first (key,neutral,de,fr); the default file is texts.csv next to the project file. An empty cell means “no text in this language”.
  • export --language <code> writes the translation package of one language instead (default texts.<code>.csv): one row per key of the application with the columns key, source (the neutral text, else the English one), the language, and review (for a translation marked for review, the source text it was made from). neutral has no package.
  • import merges one or more CSV files, packages or full exports, in any order (default texts.csv). Only the language columns are written; source and review are not. An empty cell and a missing row change nothing, and no key is removed. A key the application does not have is skipped with a warning; new keys come only from the neutral column (or en in a project without neutral texts). When two files give different texts for the same key and language, nothing is written. A translation whose source differs from the neutral text now, and every translation of a key whose neutral text the import changes, is marked for review in source/texts/review.<code>.json. One line per language names how many texts are new, changed, still untranslated and marked for review.
  • import --replace <file.csv> takes exactly one CSV as the whole set: a key missing in it is removed. A language column that is empty in every row leaves its file as it is. One line per language names the number of texts and how many are new, changed and removed.
  • All files are UTF-8; export writes a byte order mark, commas and CR LF, import reads comma or semicolon separated files as Excel saves them in the regional settings of Windows. Each text file is written in its canonical form, only when its content changes.
  • Exit code 2 when the text files or a CSV cannot be read (no header starting with key, a column that is no language code, neutral, source or review, a key twice), when files contradict each other, or when the CSV of --replace has neither neutral nor English texts. Exit code 1 for --replace with more than one file.

Exit codes

CodeMeaning
0Done (ready to build, built, exported …). Warnings may have been printed.
1The command line is wrong.
2The project file or the sources are invalid.
3The machine cannot build the project (Access, bitness, type libraries, drivers).
4VBA code does not compile.
5Another step failed (a file another program holds names the file and the program: A file is in use), or a failure the SDK did not expect (its type and message are reported).
6roundtrip found differences.
7status or sync left objects changed on both sides undecided, or commit was refused before anything was written.
8The run was canceled with Ctrl+C, or the build of a project from the internet was not confirmed for open.
9The ACCDE was not made.
10Another run works on the project, or the machine lock stayed held for --lock-wait seconds; nothing was done (The project is busy).
11deliver or msi: the delivery could not be put together (a package, the starter, its project file or the package tool).
12call: the function raised a VBA error it does not handle, or Access refused the call.
13call: the function did not return within the time limit; its Access was ended.
14call: the function showed a dialog, which was answered.
15test: at least one check failed.
16test: Access ended during a test procedure; the run stopped.

Codes a command uses beyond 0, 1 and 10:

CommandCodes
check, build, rebuild, validate2, 3, 4, 5; build and rebuild also 9
texts2 (text files or CSV cannot be read)
export2 (project or sources invalid), 5
import2 (project or sources invalid, also a password in the sources), 5
status, sync5 (also when the sources are invalid or hold a password), 7
changes5 (also when the sources are invalid or hold a password)
diff2 when the check against Access failed
commit7 (refused, nothing written), 5
push5
migrate2 for every problem, also a failure of the hidden Access; without -o, 2 when a file cannot be read or written
addin3 when installing, removing or reading the state fails
roundtrip2, 3, 4, 5 when the build of the copy fails; 5 when its export fails; 6 for differences
call2 (no database), 3, 5 (the copy could not be opened), 12, 13, 14
testthe codes of build; 2 (no test function, procedure or test module), 5 (the copy could not be opened), 13, 15, 16
openthe codes of build; 8 when the build of a project from the internet was not confirmed
every command8 after Ctrl+C

JSON output

With --json a command prints one JSON object on standard output instead of text. Exceptions:

  • A command line the parser refuses prints what is wrong on standard error and no JSON (exit code 1). new and addin with an unknown action also end with exit code 1, but print their JSON; commit with a file outside the project prints an error: line on standard error, no usage text and no JSON (exit code 1).
  • diff --against access prints text when Access and the source of the object are in step (exit code 0) or the check failed (exit code 2).
  • Ctrl+C prints only the cancel message on standard error (exit code 8).

The fields differ per command:

FieldCommandsContent
exitCodeallThe exit code.
problemsall except push and call; test only when the project or its build failedObjects with severity (error, warning), phase, object, file (with :<line> for data), cause; for changes and diff a list of texts. push and call have no problems.
project, configuration, access, tables, objects, database, accde, dialogscheck, build, rebuild, validate, accdeName, configuration, bitness of Access (x86, x64; filled by check only, empty for the others), counts, the files made, and the dialogs Access showed and the build canceled.
written, deletedexport, commitFiles written and deleted, relative to the project.
imported, unchangedimportObjects loaded, and the number left as they were.
objects, done, diffsstatus, syncEach object with key and status (and renamedTo), what was carried over, the differences shown.
folder, differencesroundtripThe kept copy and the differing files.
projectnew, migrateThe project file created (migrate also notes).
whatIf, changes, notesmigrate without -oWhether it was a preview; each changed file with file, count and lines; the places left as they are. problems is a list of texts.
processrun, openThe process id of the Access started.
outputcommit, pushThe messages of the version control.
checkedAt, current, clean, rows, branchchangesThe time of the check, whether it succeeded, whether nothing differs, each row with object, file, accessSource (InStep, ChangedInAccess, ChangedInSource, Conflict), vcs (Committed, Modified, Added, Untracked, Deleted, Renamed, Conflicted, or an empty text outside version control), next (None, Export, Import, Decide, ReviewAndCommit, ResolveMerge), and the branch with name, hasUpstream, ahead, behind. The values are these names in every language. The text output shows the Access ↔ source state and the next steps Decide, ReviewAndCommit and ResolveMerge in the user's language; the version control state and the next steps export and import are printed in English.
file, against, diffdiffThe file compared, the side, the difference in unified format.
registered, listed, loadBehavior, projectFiles, projectFilesChosenaddinWhether the add-in is registered, whether Access lists it, its load behavior (3 = loads at start), whether a double-click on a project file runs open, and what you chose in Windows for .acproj (projectFilesChosen: sdk, other or none).
editorListed, editorLoadBehavioraddinWhether the VBA editor lists the add-in, and its load behavior there (3 = loads when the editor opens).
database, function, outcome, value, type, durationMs, problemcallThe database called; the function; how the call ended (returned, vbaError, failed, timeLimit, dialog, notOpened, noAccess, cancelled); the return value as a JSON value (text, number, true/false, null for Null and Empty, a date as ISO 8601 text, an array as an array); its VBA type (String, Long, Double, Currency, Date, Boolean, Null, Empty, Array …; empty when the call failed); the time of the call in milliseconds; the message of a failed call.
database, work, language, end, passed, failed, durationMs, procedures, checks, problem, junittestThe database tested and the work folder; the language of --language (empty without); how the run ended (completed, noTests, noTestModule, timeLimit, accessEnded, notOpened, noAccess, cancelled); the numbers of passed and failed checks; the time of the run in milliseconds; the procedures that ran; each check with test, name, ok, message, ms and utc; why the run stopped; the path of the JUnit report.

Problem lines

Without --json, problems print as <severity> [<phase>] <object>, <file>: <cause>; a part that is empty is left out. With --format msbuild each problem is a line <file>(<line>): <error|warning> WKL<nnn>: <object>: <cause> with a full path, which Visual Studio Code and other editors list at its place. The number is the phase, the same in the MSBuild tasks:

CodePhase (phase in JSON)What runs
WKL000ProjectReading the project file
WKL001SourcesReading and checking the sources
WKL002EnvironmentChecking the machine: Access, bitness, type libraries, ODBC drivers
WKL003DatabaseCreating the database: references, properties, tables, data, relationships
WKL004ObjectsLoading queries, modules, forms, reports, macros
WKL005ModelsThemes, resources, models of WKL Forms Object Library
WKL006CompileCompiling the VBA project
WKL007ValidateChecking the built database
WKL008AccdeMaking the ACCDE
WKL010-MSBuild only: another run works on the project
WKL011-MSBuild only: a file is held by another program
WKL900-MSBuild only: roundtrip found a difference

Remarks

  • No dialogs. Apart from run and open, no command shows a window of its own. Access runs hidden; a dialog it shows during a step is recorded with its text and canceled with Esc, and the step fails. In a developer's Access (see below) the same holds for a dialog that opens during the step; dialogs that were open before stay.
  • Time limits. Every step has a fixed limit, not configurable: 60 seconds for most steps, 90 for moving one object, 120 for models, export and opening a copy, 180 for compiling and making the ACCDE, 5 minutes for the data of one table and for the finishing function. The time limits and the dialog watch cover the steps in Access: git and svn run as they do on the command line, without a time limit, and a credential prompt, a credential manager window or a hook can stop commit or push. On build machines configure authentication that needs no input. When a step of the hidden Access exceeds its limit, that Access is ended at once and the step fails. A step in the developer's Access is not interrupted: the run waits until Access answers and then reports that the step took longer than its limit.
  • No Access left behind. Every Access the SDK starts is ended when the run ends: asked to quit, ended hard only after 30 seconds (reported). When wkl-office is killed or crashes, Windows ends its Access as well (through a job object; when Windows refuses to add Access to it, which has not been observed, this net is missing). Windows starts Access through COM, and the SDK adds it to the job as soon as Access answers, within about a second: an Access whose wkl-office is killed in that first moment stays running and has to be closed by hand. Ctrl+C asks the Access of the run to close and ends with exit code 8 at once. An Access a developer opened is never quit.
  • After an interrupted run (Ctrl+C, a killed process, a time limit): export leaves the files it wrote, possibly one cut off, and neither deletes stale files nor writes the common state; sync writes the common state only at its end, so objects it had already carried over show as changed on both sides; build leaves .building, which the next build removes; commit may leave files staged but not committed; import into the developer's Access leaves the objects loaded so far. Run wkl-office changes. After an interrupted export or sync, run a full wkl-office export while Access holds the wanted state, or decide the rows with sync --keep; after an interrupted build, build again; after an interrupted commit, check git status and run commit again.
  • The database open in Access. export, import, status, sync and commit find the Access that has the database open through the Running Object Table, by the full path of the database (not case-sensitive), and work in it. changes and diff look there as well. Only an Access of the same user is found (not one started as administrator). That Access is never quit or ended, also not when a step takes longer than its time limit.
  • Terminal host. wkl-office terminal-host is used by the terminal of the add-in and is not meant to be called by hand.
  • Bitness. The tool automates Access out of process, so one installation serves 32-bit and 64-bit Office.
en/wiki/msaccess/sdk/reference/command-line.txt · Last modified: by Wolfgang van der Stille