比如你卖软件, 非常贵的软件但又非常好用. 一套一套卖, 每一套指明说是只能同时一个人用(一台机器), 当然你可以写在合同里, 大公司则会去遵守, 但是一些小公司则可能想着, 装在性能较好的 Windows 服务器上, 那么, 多个用户可以同时登陆并启动相同的软件. 这样你就亏大了, 得限制.
同时, 你又想让同一用户可以同时启动相同软件, 因为这样可以方便同时处理多个工程.
最简单的方法就是调用 Win32 API 来在 Global 命名空间下 创建 Mutex 对象. 这个API就是 CreateMutex (CreateMutexAANSI版本, CreateMutexW Unicode版本).
下面的C++代码就能够实现这么一个功能. 注意的是不要使用这个GUID, 因为别人也可能会用到, 最好是自己在 Visual Studio – Tools – Create GUID 生成一个新的GUID.
1 2 3 4 5 6 7 8 9 10 11 | int _tmain(int argc, _TCHAR* argv[]) { if ( ::CreateMutexW( NULL, FALSE, L"Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B" ) != NULL ) { std::wcout << L"Mutex acquired. GLE = " << GetLastError() << std::endl; // Continue execution } else { std::wcout << "Mutex not acquired. GLE = " << GetLastError() << std::endl; // Exit application } _getch(); return 0; } |
int _tmain(int argc, _TCHAR* argv[]) { if ( ::CreateMutexW( NULL, FALSE, L"Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B" ) != NULL ) { std::wcout << L"Mutex acquired. GLE = " << GetLastError() << std::endl; // Continue execution } else { std::wcout << "Mutex not acquired. GLE = " << GetLastError() << std::endl; // Exit application } _getch(); return 0; }
第一个参数是结构属性, 第二个参数指明了 Ownership, 第三个参数就是 Mutex 对象的名称. 下面是 .NET 托管的 C# 代码.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | using System.Runtime.InteropServices; public class HelloACM { [StructLayout(LayoutKind.Sequential)] public class SECURITY_ATTRIBUTES { public int nLength; public int lpSecurityDescriptor; public int bInheritHandle; } [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern int CreateMutex(SECURITY_ATTRIBUTES lpMutexAttributes, bool bInitialOwner, string lpName); public static int Main(string[] args) { // Avoid Multiple Instances of Different Users BUT Allow Multiple Instances on Single User Session if (CreateMutex(null, false, "Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B") == 0) { // Multiple Instances from One Single User are Allowed. MessageBox.Show("The Software is already running in other sessions."); return -1; } } } |
using System.Runtime.InteropServices; public class HelloACM { [StructLayout(LayoutKind.Sequential)] public class SECURITY_ATTRIBUTES { public int nLength; public int lpSecurityDescriptor; public int bInheritHandle; } [System.Runtime.InteropServices.DllImport("kernel32.dll")] private static extern int CreateMutex(SECURITY_ATTRIBUTES lpMutexAttributes, bool bInitialOwner, string lpName); public static int Main(string[] args) { // Avoid Multiple Instances of Different Users BUT Allow Multiple Instances on Single User Session if (CreateMutex(null, false, "Global\\F4CD32D1-3B3B-4AA0-AB76-273FFA455E1B") == 0) { // Multiple Instances from One Single User are Allowed. MessageBox.Show("The Software is already running in other sessions."); return -1; } } }
这也是软件保护的一种.
参考文献
1. StackOverflow: http://stackoverflow.com/questions/28240354/how-to-avoid-multiple-instances-of-different-users-but-allow-multiple-instances
2. CreateMutex API MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/ms682411.aspx
3. Kernel Object NameSpace MSDN: https://msdn.microsoft.com/en-us/library/windows/desktop/aa382954.aspx
强烈推荐
- 英国代购-畅购英伦
- TopCashBack 返现 (英国购物必备, 积少成多, 我2年来一共得了3000多英镑)
- Quidco 返现 (也是很不错的英国返现网站, 返现率高)
- 注册就送10美元, 免费使用2个月的 DigitalOcean 云主机(性价比超高, 每月只需5美元)
- 注册就送10美元, 免费使用4个月的 Vultr 云主机(性价比超高, 每月只需2.5美元)
- 注册就送10美元, 免费使用2个月的 阿里 云主机(性价比超高, 每月只需4.5美元)
- 注册就送20美元, 免费使用4个月的 Linode 云主机(性价比超高, 每月只需5美元) (折扣码: PodCastInit2022)
- PlusNet 英国光纤(超快, 超划算! 用户名 doctorlai)
- 刷了美国运通信用卡一年得到的积分 换了 485英镑
- 注册就送50英镑 – 英国最便宜最划算的电气提供商
- 能把比特币莱特币变现的银行卡! 不需要手续费就可以把虚拟货币法币兑换
微信公众号: 小赖子的英国生活和资讯 JustYYUK