diff --git a/source/RobotAPI/interface/skills/SkillManagerInterface.ice b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
index 04ed44b5411d5268760165e85e0091940b42e35e..85135d7b5e2328db4fe0ef84864e3bd1c8c65366 100644
--- a/source/RobotAPI/interface/skills/SkillManagerInterface.ice
+++ b/source/RobotAPI/interface/skills/SkillManagerInterface.ice
@@ -92,6 +92,8 @@ module armarx
 
             module dti
             {
+                sequence<provider::dto::AbortSkillResult> AbortSkillResultList;
+
                 interface SkillManagerInterface extends
                     callback::dti::SkillProviderCallbackInterface
                 {
@@ -127,8 +129,10 @@ module armarx
 
                     // notify a skill to stop ASAP.
                     provider::dto::AbortSkillResult abortSkill(dto::SkillExecutionID executionId);
-                    provider::dto::AbortSkillResult abortSkillAsync(
-                        dto::SkillExecutionID executionId);
+                    provider::dto::AbortSkillResult abortSkillAsync(dto::SkillExecutionID executionId);
+                    // notify all skills directly via ice interface instead of ugly workarounds in both c++ and python
+                    AbortSkillResultList abortAllSkills();
+                    AbortSkillResultList abortAllSkillsAsync();
                 };
             }
         }
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
index 0f53619d63f4eb4d0aede40e39c6f86501c8f28f..8eb23a8d3ed7ed3daf77131ac4ad7ca9c5d88972 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.cpp
@@ -674,6 +674,71 @@ namespace armarx
         return ret;
     }
 
+    std::vector<skills::provider::dto::AbortSkillResult> SkillManagerComponentPluginUser::abortAllSkills(const Ice::Current &current)
+    {
+        ARMARX_IMPORTANT << "Stopping all running executions.";
+
+        std::vector<skills::provider::dto::AbortSkillResult> results;
+
+         skills::manager::dto::SkillStatusUpdateMap executions;
+
+        // we ALWAYS want the newest information when stopping all!
+        // e.g. there is some new skill not known to the GUI which we explicitely want to stop too.
+        // the stop-all function is often used in an emergency, so we'll live with the extra call...
+        try
+        {
+            executions = this->getSkillExecutionStatuses(current);
+        }
+        catch (...) // if any error occurs, we use the snapshot as backup. better to miss a skill
+            // than to not do anything.
+        {
+            executions =  this->getSkillExecutionStatuses(current);
+        }
+
+        for (auto& [executionId, status] : executions)
+        {
+            // select all running executions...
+            if (status.status != armarx::skills::core::dto::Execution::Aborted and status.status != armarx::skills::core::dto::Execution::Failed)
+            {
+                // ... and kill them.
+                results.push_back(this->abortSkill(executionId, current));
+            }
+        }
+        return results;
+    }
+
+    std::vector<skills::provider::dto::AbortSkillResult> SkillManagerComponentPluginUser::abortAllSkillsAsync(const Ice::Current &current)
+    {
+        ARMARX_IMPORTANT << "Stopping all running executions.";
+        std::vector<skills::provider::dto::AbortSkillResult> results;
+
+        skills::manager::dto::SkillStatusUpdateMap executions;
+
+        // we ALWAYS want the newest information when stopping all!
+        // e.g. there is some new skill not known to the GUI which we explicitely want to stop too.
+        // the stop-all function is often used in an emergency, so we'll live with the extra call...
+        try
+        {
+            executions = this->getSkillExecutionStatuses(current);
+        }
+        catch (...) // if any error occurs, we use the snapshot as backup. better to miss a skill
+            // than to not do anything.
+        {
+            executions =  this->getSkillExecutionStatuses(current);
+        }
+
+        for (auto& [executionId, status] : executions)
+        {
+            // select all running executions...
+            if (status.status != armarx::skills::core::dto::Execution::Aborted and status.status != armarx::skills::core::dto::Execution::Failed)
+            {
+                // ... and kill them.
+                results.push_back(this->abortSkillAsync(executionId, current));
+            }
+        }
+        return results;
+    }
+
     void
     SkillManagerComponentPluginUser::updateStatusForSkill(
         const skills::provider::dto::SkillStatusUpdate& statusUpdate,
diff --git a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
index be6e9fefa6f684209e5c43fdf3250c0e3b250925..0f55c17edf973ac2151959ea5c50e7c875bfefa3 100644
--- a/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
+++ b/source/RobotAPI/libraries/skills/manager/SkillManagerComponentPlugin.h
@@ -121,6 +121,10 @@ namespace armarx
         abortSkillAsync(const skills::manager::dto::SkillExecutionID& id,
                         const Ice::Current& current) override;
 
+        std::vector<skills::provider::dto::AbortSkillResult> abortAllSkills(const Ice::Current& current) override;
+
+        std::vector<skills::provider::dto::AbortSkillResult> abortAllSkillsAsync(const Ice::Current& current) override;
+
 
         skills::manager::dto::SkillDescriptionMap
         getSkillDescriptions(const Ice::Current& current) override;