Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Catalyn45 committed Mar 16, 2024
1 parent d25955b commit 5f78b5b
Show file tree
Hide file tree
Showing 7 changed files with 345 additions and 0 deletions.
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
*.com
*.class
*.dll
*.exe
*.pdb
*.dll.config
*.cache
bin/
obj/
.vs/
25 changes: 25 additions & 0 deletions ClipboardManager.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34701.34
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClipboardManager", "ClipboardManager\ClipboardManager.csproj", "{CBC02DE6-2154-4AD1-B9E1-C785B239D760}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CBC02DE6-2154-4AD1-B9E1-C785B239D760}.Debug|x64.ActiveCfg = Debug|x64
{CBC02DE6-2154-4AD1-B9E1-C785B239D760}.Debug|x64.Build.0 = Debug|x64
{CBC02DE6-2154-4AD1-B9E1-C785B239D760}.Release|x64.ActiveCfg = Release|x64
{CBC02DE6-2154-4AD1-B9E1-C785B239D760}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B701F7F6-1E5E-4E16-9CC7-771B2EDB3EAF}
EndGlobalSection
EndGlobal
6 changes: 6 additions & 0 deletions ClipboardManager/App.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
</configuration>
62 changes: 62 additions & 0 deletions ClipboardManager/ClipboardManager.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{CBC02DE6-2154-4AD1-B9E1-C785B239D760}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>ClipboardManager</RootNamespace>
<AssemblyName>ClipboardManager</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\x64\Debug\</OutputPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\x64\Release\</OutputPath>
</PropertyGroup>
<ItemGroup>
<Reference Include="PresentationCore" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
148 changes: 148 additions & 0 deletions ClipboardManager/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Windows;

namespace ClipboardManager
{
internal class Program
{
static string helpText = "Clipboard Manager for windows files\r\n" +
"\r\n" +
"Usage\r\n" +
$"\t$ {AppDomain.CurrentDomain.FriendlyName} [--copy | --cut | --paste | --show] [-f] [<files>]\r\n" +
"\r\n" +
"Examples\r\n" +
$"\t$ {AppDomain.CurrentDomain.FriendlyName} --copy test1.txt test2.txt\r\n" +
$"\t$ {AppDomain.CurrentDomain.FriendlyName} --paste\r\n";

[STAThread]
static int Main(string[] args)
{
try
{
if (args.Length == 0 || args[0] == "--help")
{
Console.WriteLine(helpText);
return 0;
}

// Some magic bytes for the cut command, this way you can also paste with ctrl + v
byte[] moveEffect = new byte[] { 2, 0, 0, 0 };
MemoryStream dropEffect = new MemoryStream();
dropEffect.Write(moveEffect, 0, moveEffect.Length);

string command = args[0];
if (command == "--show")
{
var paths = Clipboard.GetFileDropList();
foreach (var path in paths)
{
Console.WriteLine(path);
}
}
else if (command == "--copy")
{
if (args.Length < 2)
{
Console.WriteLine("At least one path needs to be specified");
return -1;
}

StringCollection paths = new StringCollection();
for (int i = 1; i < args.Length; i++)
{
paths.Add(Path.GetFullPath(args[i]));
}

Clipboard.Clear();
Clipboard.SetFileDropList(paths);
}
else if (command == "--cut")
{
if (args.Length < 2)
{
Console.WriteLine("At least one path needs to be specified");
return -1;
}

DataObject data = new DataObject();
StringCollection paths = new StringCollection();
for (int i = 1; i < args.Length; i++)
{
paths.Add(Path.GetFullPath(args[i]));
}

data.SetFileDropList(paths);
data.SetData("Preferred DropEffect", dropEffect);

Clipboard.Clear();
Clipboard.SetDataObject(data, true);
}
else if (command == "--paste")
{
bool force = false;
int currentArgumentIndex = 1;
if (args.Length > currentArgumentIndex && args[currentArgumentIndex] == "-f")
{
force = true;
currentArgumentIndex++;
}

string destination = Directory.GetCurrentDirectory();
if (args.Length > currentArgumentIndex)
{
destination = args[currentArgumentIndex];
}

bool isCutted = false;

// Check the magic bytes to see if the file is cutted
var data = Clipboard.GetDataObject();
if (data != null &&
data.GetData("Preferred DropEffect") is MemoryStream setDropEffect &&
setDropEffect != null &&
setDropEffect.ToArray().SequenceEqual(dropEffect.ToArray()))
{
isCutted = true;
}

var paths = Clipboard.GetFileDropList();
foreach (var path in paths)
{
string destinationFileName = Path.Combine(destination, Path.GetFileName(path));

var sourceFile = new FileInfo(path);
if (isCutted)
{
// MoveTo doesn't have overwrite flag so we manually delete
if (force && File.Exists(destinationFileName))
{
var destFileInfo = new FileInfo(destinationFileName);
destFileInfo.Delete();
}

sourceFile.MoveTo(destinationFileName);
}
else
{
sourceFile.CopyTo(destinationFileName, force);
}
}
}
else
{
Console.WriteLine($"Unrecognized command: {command}");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
return -1;
}

return 0;
}
}
}
36 changes: 36 additions & 0 deletions ClipboardManager/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ClipboardManager")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ClipboardManager")]
[assembly: AssemblyCopyright("Copyright © 2024")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("cbc02de6-2154-4ad1-b9e1-c785b239d760")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# ClipboardManager

Very simple clipboard manager for copying/cutting and pasting files on windows from the commandline.
The code is very simple, only 150 lines long.

This is integrated with windows ctrl+c ctrl+v, meaning that you can copy/cut a file with ctrl+c/ctrl+x and then paste/move it from the commandline. You can also copy/cut it from the commandline and paste/move it with ctrl+v.

## Features
- Copy files
- Cut files
- Paste files
- Show clipboard content
- Integrated with windows ctrl+c ctrl+v

## Installation
Just build the project with dotnet
```pwsh
dotnet build --configuration Release
```

Then but the binary some directory that you have in `PATH`.

## Examples

Copy multiple files
```pwsh
ClipboardManager --copy ./test1.txt ../test/test2.txt
```
<br>

Cut multiple files
```pwsh
ClipboardManager --cut ./test1.txt ../test/test2.txt
```
<br>

Paste/Move the copied/cut files in the current directory
```pwsh
ClipboardManager --paste
```
<br>

Paste/Move the copied/cut files in the current directory and overwrite the existing file with the same name if exists
```pwsh
ClipboardManager --paste -f
```
<br>

Paste/Move the copied/cut files in a specified directory
```pwsh
ClipboardManager --paste ./some_dir
```
<br>

Show copied files from clipboard
```pwsh
ClipboardManager --show
```

0 comments on commit 5f78b5b

Please sign in to comment.