No More Desktop Shortcuts
October 3, 2021
I like having a clean desktop. Whenever I install a new application on my Windows computer, I always uncheck the "Create a Desktop Shortcut" checkbox.
Unfortunately, if you install an app on Windows for "All Users" and you select
to not have a shortcut show up on your desktop, some apps will still
install a shortcut on the CommonDesktopDirectory,
which is a place where all users can see shortcuts (C:\Users\Public\Desktop
).
Or, the app will create a shortcut in that CommonDesktopDirectory when it upgrades,
which is what was happening to me.
This can get annoying. Let's do something about it.
Planning the App
First, we need a plan. This is pretty simple:
- On startup, search for any shortcuts on the common desktop directory.
- If any are found, move them to the Recycle Bin.
- In case something goes wrong, let's keep a log of what happened.
Searching for Shortcuts
On Windows, shortcut files have a file extension of .lnk
(can be upper
or lower case). So we'll be searching for files with that ending.
Where should we be looking for these files? If you ran into what I ran into with the CommonDesktopDirectory issue, the directory is most-likely:
C:\Users\Public\Desktop
Move Shortcuts to the Recycle Bin
Just in case something goes wrong and we delete something that we actually wanted to keep, we'll want to recover it. Putting the shortcut in the Recycle Bin allows us to undo something we didn't mean to do.
How do we move a shortcut to the Recycle Bin? It's not as easy as
using fs.unlink
in node.js, because that actually deletes the file
permanently.
Luckily, there's an npm package called trash written and maintained by Sindre Sorhus which handles this for us (and is cross-platform, too).
Keep a Log
We'll be using Winston to log when this app runs and what it does (or fails to do). The logs will be stored in the same directory as the app folder.
Run on Startup
Windows will run a batch file on startup when it is in the Startup directory.
To find out where this directory is for your profile, hit the
WindowsKey+r, then type in shell:startup
and press OK. The File Explorer
will pop up with the directory you need to create the batch file in.
The Code
Note, I'm using node.js v16. Also, in my package.json
file, I am using
"type": "module"
to use ECMAScript module syntax (reference).
// index.js
import * as fs from 'fs/promises';
import * as path from 'path';
import { fileURLToPath } from 'url';
import trash from 'trash';
import createLog from './logger.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
process.chdir(__dirname);
const logger = createLog();
const startPath = 'C:\\Users\\Public\\Desktop';
const files = await fs.readdir(startPath);
files.forEach(async (file) => {
const filename = path.join(startPath, file);
try {
const stat = await fs.lstat(filename);
if (stat.isFile && filename.toLowerCase().endsWith('.lnk')) {
logger.info(`Moving file to recycle bin: ${filename}`);
trash(filename);
}
} catch (error) {
logger.error(`Error moving file to recycle bin: ${filename}`);
logger.error(error);
}
});
And here's the logger file:
// logger.js
import pkg from 'winston';
const { createLogger, format, transports } = pkg;
export default () => {
const logger = createLogger({
level: 'info',
format: format.combine(
format.timestamp({
format: 'YYYY-MM-DD HH:mm:ss'
}),
format.errors({ stack: true }),
format.splat(),
format.json()
),
defaultMeta: { service: 'shortcut-killer' },
transports: [
new transports.File({ filename: 'error.log', level: 'error' }),
new transports.File({ filename: 'combined.log' })
]
});
if (process.env.NODE_ENV !== 'production') {
logger.add(new transports.Console({
format: format.combine(
format.colorize(),
format.simple()
)
}));
}
return logger;
};
If you're wondering about this part in index.js
:
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
process.chdir(__dirname);
It's because __filename
and __dirname
are
no longer available when using ECMAScript modules,
so we need to create them ourselves. The reason I needed
to change the working directory was for the logger to put
the logs where the app lives (rather than in the context
of the executing app, which could be the Windows Startup context).
Host the App
After putting this app together. I copied the entire contents to a new directory
on my machine C:\Startup_Apps
. The reason for this is because if I want to make
a change to the app, I can have a work-in-progress in my development directory
and not affect the "production" version, which the batch file refers to.
Batch File for Startup
Now we need a batch file to start this app at startup.
Here's the batch script for the app (adjust for your path names):
set NODE_ENV=production&& "C:\[path_to_node]\node.exe" "C:\Startup_Apps\[app_name_dir]\index.js"
One important note, when setting the NODE_ENV
variable in a batch script, the &&
must not have a space before it (so what you see above is not a typo).
Host this .bat
file in your Startup directory (WindowsKey+r, shell:startup
).
Note: run this code at your own risk.
Conclusion
And with that, we're done. No more desktop shortcuts on the CommonDesktopDirectory. If you use a computer that is used by others, this might not be the solution for you, but for me, I'm the only person using this computer so it's no big deal.