То, что предоставлено в данной заметке не является документированным способом и получено на основе анализирования состава мьютексов, создаваемых и используемых AutoCAD в процессе своей работы. Способ применим как к acad.exe, так и к accoreconsole.exe. Проверялся с AutoCAD 2009-2016 x64, а так же с AutoCAD 2008 x86, запущенном в Windows x64. Решение продемонстрировано в двух вариантах: C++ и C#.
В .NET получить процессы по имени можно при помощи статического метода Process.GetProcessesByName("acad"). Однако, если переименовать любой EXE файл в acad.exe, то будучи запущенным, он тоже попадёт в выборку, возврашаемую этим методом, хотя на самом деле это не процесс AutoCAD.
Конечно же, приведённый в этой заметке код не является "серебрянной пулей", т.к. всегда можно программно создать Mutex с указанным в нашем коде именем... Однако, обозначенный мною вариант проверки не удастся обмануть простым переименованием любого EXE файла в acad.exe или accoreconsole.exe, поэтому он, как мне кажется, имеет право на жизнь...
Как это сделать на C++:
/* © Andrey Bushman, 2015
http://bushman-andrey.blogspot.ru/2015/11/acadexe-accoreconsoleexe.html
This is the quick way of checking is any AutoCAD launched (acad.exe
or accoreconsole.exe) or not. I've checked my code for the usual
AutoCAD 2009-2016 x64. But I haven't their x86 versions, I haven't
older AutoCAD versions, and I haven't their vertical products,
therefore I can't check my code for these versions.
Additionally, Alexander Rivilis checked this code for AutoCAD 2008 x86
which was launched in Windows x64.
NOTE
Visual C++ Redistributable for Visual Studio (your version) must be
installed on the target computers.
*/
#include<Windows.h>
#include<iostream>
#include<exception>
#include<string>
#include<tchar.h>
#include<strsafe.h>
using namespace std;
#define UNEXPECTED_EXCEPTION 1
#define UNKNOWN_ERROR 2
BOOL IsLaunchedAnyAutoCAD();
int wmain(int argc, wchar_t *argv[])
try {
// setlocale(LC_ALL, "Russian");
SetConsoleTitle(TEXT("Is any AutoCAD launched?"));
BOOL result = IsLaunchedAnyAutoCAD();
if (result) {
wcout << L"Any AutoCAD is launched." << endl;
}
else {
wcout << L"Any AutoCAD is not launched." << endl;
}
wcout << L"Press 'x' for exit..." << endl;
wchar_t c;
wcin >> c;
}
catch (exception ex) {
wcerr << ex.what() << endl;
return UNEXPECTED_EXCEPTION;
}
catch(...){
wcerr << L"Unknown error." << endl;
return UNKNOWN_ERROR;
}
BOOL IsLaunchedAnyAutoCAD() {
BOOL result = FALSE;
LPCTSTR anyAcadMutexName = TEXT(
// This works for AutoCAD 2008 and newer (I haven't older
// AutoCAD versions, therefore I can't check it for them).
"Global\\8C84DAD6-9865-400e-A6E3-686A61C16968"
// This is for AutoCAD 2009 and newer
// "Local\\AcadProfileStorage_54519085-6DDA-4070-BB93-3A095D7E1140"
);
HANDLE hAnyAcadMutex = OpenMutex(READ_CONTROL, FALSE, anyAcadMutexName);
if (NULL != hAnyAcadMutex) {
result = TRUE;
CloseHandle(hAnyAcadMutex);
}
return (result);
}
Как это сделать на C#:
/* © Andrey Bushman, 2015
http://bushman-andrey.blogspot.ru/2015/11/acadexe-accoreconsoleexe.html
This is the quick way of checking is any AutoCAD launched (acad.exe
or accoreconsole.exe) or not. I've checked my code for the usual
AutoCAD 2009-2016 x64. But I haven't their x86 versions, I haven't
older AutoCAD versions, and I haven't their vertical products,
therefore I can't check my code for these versions.
Additionally, Alexander Rivilis checked this code for AutoCAD 2008 x86
which was launched in Windows x64.
*/
using System;
using System.Threading;
namespace Bushman.Sandbox.AutoCAD
{
class Program
{
static Boolean IsAnyAutoCadLaunched()
{
try
{
Mutex m = Mutex.OpenExisting(
// This works for AutoCAD 2008 and newer (I haven't older
// AutoCAD versions, therefore I can't check it for them).
"Global\\8C84DAD6-9865-400e-A6E3-686A61C16968"
// This is for AutoCAD 2009 and newer
// "Local\\AcadProfileStorage_54519085-6DDA-4070-BB93-3A095D7E1140"
);
m.Close();
return true;
}
catch
{
return false;
}
}
static void Main(string[] args)
{
String msg = IsAnyAutoCadLaunched() ? "Any AutoCAD is launched." :
"Any AutoCAD is not launched.";
Console.WriteLine(msg);
Console.WriteLine("Press any key for exit...");
Console.ReadKey();
}
}
}
В .NET получить процессы по имени можно при помощи статического метода Process.GetProcessesByName("acad"). Однако, если переименовать любой EXE файл в acad.exe, то будучи запущенным, он тоже попадёт в выборку, возврашаемую этим методом, хотя на самом деле это не процесс AutoCAD.
Конечно же, приведённый в этой заметке код не является "серебрянной пулей", т.к. всегда можно программно создать Mutex с указанным в нашем коде именем... Однако, обозначенный мною вариант проверки не удастся обмануть простым переименованием любого EXE файла в acad.exe или accoreconsole.exe, поэтому он, как мне кажется, имеет право на жизнь...
Как это сделать на C++:
/* © Andrey Bushman, 2015
http://bushman-andrey.blogspot.ru/2015/11/acadexe-accoreconsoleexe.html
This is the quick way of checking is any AutoCAD launched (acad.exe
or accoreconsole.exe) or not. I've checked my code for the usual
AutoCAD 2009-2016 x64. But I haven't their x86 versions, I haven't
older AutoCAD versions, and I haven't their vertical products,
therefore I can't check my code for these versions.
Additionally, Alexander Rivilis checked this code for AutoCAD 2008 x86
which was launched in Windows x64.
NOTE
Visual C++ Redistributable for Visual Studio (your version) must be
installed on the target computers.
*/
#include<Windows.h>
#include<iostream>
#include<exception>
#include<string>
#include<tchar.h>
#include<strsafe.h>
using namespace std;
#define UNEXPECTED_EXCEPTION 1
#define UNKNOWN_ERROR 2
BOOL IsLaunchedAnyAutoCAD();
int wmain(int argc, wchar_t *argv[])
try {
// setlocale(LC_ALL, "Russian");
SetConsoleTitle(TEXT("Is any AutoCAD launched?"));
BOOL result = IsLaunchedAnyAutoCAD();
if (result) {
wcout << L"Any AutoCAD is launched." << endl;
}
else {
wcout << L"Any AutoCAD is not launched." << endl;
}
wcout << L"Press 'x' for exit..." << endl;
wchar_t c;
wcin >> c;
}
catch (exception ex) {
wcerr << ex.what() << endl;
return UNEXPECTED_EXCEPTION;
}
catch(...){
wcerr << L"Unknown error." << endl;
return UNKNOWN_ERROR;
}
BOOL IsLaunchedAnyAutoCAD() {
BOOL result = FALSE;
LPCTSTR anyAcadMutexName = TEXT(
// This works for AutoCAD 2008 and newer (I haven't older
// AutoCAD versions, therefore I can't check it for them).
"Global\\8C84DAD6-9865-400e-A6E3-686A61C16968"
// This is for AutoCAD 2009 and newer
// "Local\\AcadProfileStorage_54519085-6DDA-4070-BB93-3A095D7E1140"
);
HANDLE hAnyAcadMutex = OpenMutex(READ_CONTROL, FALSE, anyAcadMutexName);
if (NULL != hAnyAcadMutex) {
result = TRUE;
CloseHandle(hAnyAcadMutex);
}
return (result);
}
Как это сделать на C#:
/* © Andrey Bushman, 2015
http://bushman-andrey.blogspot.ru/2015/11/acadexe-accoreconsoleexe.html
This is the quick way of checking is any AutoCAD launched (acad.exe
or accoreconsole.exe) or not. I've checked my code for the usual
AutoCAD 2009-2016 x64. But I haven't their x86 versions, I haven't
older AutoCAD versions, and I haven't their vertical products,
therefore I can't check my code for these versions.
Additionally, Alexander Rivilis checked this code for AutoCAD 2008 x86
which was launched in Windows x64.
*/
using System;
using System.Threading;
namespace Bushman.Sandbox.AutoCAD
{
class Program
{
static Boolean IsAnyAutoCadLaunched()
{
try
{
Mutex m = Mutex.OpenExisting(
// This works for AutoCAD 2008 and newer (I haven't older
// AutoCAD versions, therefore I can't check it for them).
"Global\\8C84DAD6-9865-400e-A6E3-686A61C16968"
// This is for AutoCAD 2009 and newer
// "Local\\AcadProfileStorage_54519085-6DDA-4070-BB93-3A095D7E1140"
);
m.Close();
return true;
}
catch
{
return false;
}
}
static void Main(string[] args)
{
String msg = IsAnyAutoCadLaunched() ? "Any AutoCAD is launched." :
"Any AutoCAD is not launched.";
Console.WriteLine(msg);
Console.WriteLine("Press any key for exit...");
Console.ReadKey();
}
}
}
Комментариев нет:
Отправить комментарий