我的目标是打开一台通过USB连接的打印机CreateFile(然后发出一些WriteFiles和ReadFiles).
如果打印机是LPT打印机,我会这样做CreateFile("LPT1:", ...).但对于USB打印机,必须传递一个特殊的设备路径CreateFile才能打开该打印机.
我能够找到的这个设备路径是通过SetupDiGetClassDevs- > SetupDiEnumDeviceInterfaces- > SetupDiGetDeviceInterfaceDetail- > DevicePathmember检索的,如下所示:
\\?\usb#vid_0a5f&pid_0027#46a072900549#{28d78fad-5a12-11d1-ae5b-0000f803a8c2}
一切都很好,但我输入的是人类可读的打印机名称,如图所示Devices and Printers.这些SetupDi*功能似乎没有使用它们,它们只对设备实例ID进行操作.所以现在的问题是如何从打印机名称获取设备实例IDOpenPrinter.
这不难观察到,上述的GUID部分是GUID_DEVINTERFACE_USBPRINT和\\?\usb是固定的,所以唯一的位,我是在真正感兴趣vid_0a5f&pid_0027#46a072900549#.我可以在打印机属性对话框中手动查找此路径:
转至设备和打印机
右键单击打印机
属性
切换到硬件选项卡
选择打印设备,例如ZDesigner LP2844-Z
属性
切换到详细信息选项卡
从下拉列表中选择"父级".
但我不知道如何以编程方式执行此操作,前提是唯一给出的是打印机名称,如"设备和打印机"面板中所示.
PS 1:我对打开打印机OpenPrinter然后使用WritePrinter/ 不感兴趣ReadPrinter.已经完成,工作正常,但现在的目标是不同的.
PS 2:我可以通过一种更简单的方法将可读的打印机名称转换为可以传递给的东西CreateFile.
PS 3:这个问题,我已经发布了答案,与我最终想要做的事情非常相关.
PS 4:反过来也很好:如果可以从 …
我在Windows中的大部分日常编程工作现在都是各种I/O操作(管道,控制台,文件,套接字......).我很清楚从不同类型的句柄读取和写入的不同方法(同步,异步等待事件完成,等待文件HANDLE,I/O完成端口和可警告的I/O).我们使用其中许多.
对于我们的一些应用程序,只有一种方法来处理所有句柄是非常有用的.我的意思是,程序可能不知道它收到了什么样的句柄,我们想要使用,比方说,I/O完成端口.
首先我会问:
我们假设我有一个句柄:
HANDLE h;
Run Code Online (Sandbox Code Playgroud)
我从某个地方收到了I/O进程.有没有简单可靠的方法来找出它创建的标志?有问题的主要标志是FILE_FLAG_OVERLAPPED.
到目前为止,我所知道的唯一方法是尝试将这样的句柄注册到I/O完成端口(使用CreateIoCompletionPort()).如果成功,则使用FILE_FLAG_OVERLAPPED创建句柄.但是之后只能使用I/O完成端口,因为如果不关闭它HANDLE h本身就不能从中取消注册句柄.
提供一种简单的方法来确定存在FILE_FLAG_OVERLAPPED,我的第二个问题就出现了:
有没有办法如何将这样的标志添加到现有的句柄?这将使最初为同步操作打开的句柄打开以进行异步操作.有没有办法如何创建相反的(删除FILE_FLAG_OVERLAPPED从异步创建同步句柄)?
通过MSDN阅读和google搜索后,我没有找到任何直接的方法.至少会有一些技巧可以做同样的事吗?就像使用CreateFile()函数或类似的东西以相同的方式重新创建句柄一样?某些东西甚至部分记录或根本没有记录?
我需要这个的主要地方是确定进程应该从第三方应用程序发送给它的句柄读取/写入的方式(或改变方式).我们无法控制第三方产品如何创建其句柄.
亲爱的Windows大师:请帮助!
带着敬意
马丁
有什么区别,在什么情况下,哪一方面会以某种方式证明是优越的?
我想从字符串创建一个文本文件.目前我正在使用一个函数,它接受一个数组并使其成为一个字符串然后使用该字符串我想创建一个用户下载的本地文本文件.我尝试过使用这种方法
function createFile(){ //creates a file using the fileLIST list
var output= 'Name \t Status\n'+ fileLIST[0][0].name+'\t'+fileLIST[0][1]+'\n';
var Previous = fileLIST[0];
for (var i=1; i<fileLIST.length; i++)
if (fileLIST[i][1] =='none' || fileLIST[i][1] == Previous[1])
continue
else {
Previous = fileLIST[i]
output = output + fileLIST[i][0].name +'\t'+fileLIST[i][1] + '\n';}
window.open("data:text/json;charset=utf-8," + escape(output));//should create file
display(); }
Run Code Online (Sandbox Code Playgroud)
我使用chrome作为我的浏览器.我也更喜欢JS或HTML5的答案.
先感谢您
我正在使用CreateFile()打开一个串口.我有一个测试用例(太复杂而无法重新分配),它始终导致CreateFile()返回INVALID_HANDLE_VALUE和GetLastError()返回ERROR_SUCCESS.通过它的外观,只有当一个线程在另一个端口关闭它的同一时间打开端口时,才会出现此错误.打开端口的线程会遇到此问题.
我不知道这是否有所不同,但稍后在代码中我使用CreateIoCompletionPort将端口与CompletionPort相关联.
这是我的代码:
HANDLE port = CreateFile(L"\\\\.\\COM1",
GENERIC_READ | GENERIC_WRITE,
0, // must be opened with exclusive-access
0, // default security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
FILE_FLAG_OVERLAPPED, // overlapped I/O
0); // hTemplate must be NULL for comm devices
if (port == INVALID_HANDLE_VALUE)
{
DWORD errorCode = GetLastError();
cerr << L"CreateFile() failed with error: " << errorCode << endl;
}
Run Code Online (Sandbox Code Playgroud)
我很确定这种事情不应该发生.我做错了吗?如何让API返回正确的结果?
更多细节:此代码取自我开发的串行端口库:JPeripheral
这是实际的(未经过规范化的)源代码:
JLong SerialChannel::nativeOpen(String …Run Code Online (Sandbox Code Playgroud) 我正在使用带有IR接收器的WinLIRC连接到Windows 7 x64上的串行端口COM1.WinLIRC添加到Startup文件夹(开始 - >所有应用程序 - >启动),所以每次登录时都会启动.很多时候(但不是所有时间)我看到初始化错误消息WinLIRC,持续一段时间(几分钟)如果我重试初始化,并在一些重试后,它正确初始化并正常工作.如果我从启动中删除它并在任何其他时刻手动启动它启动没有错误.
我已经在这里和那里下载了WinLIRC源代码并添加了MessageBox调用,因此我可以看到初始化期间发生的情况并发现CreateFile调用失败:
if((hPort=CreateFile(
settings.port,GENERIC_READ | GENERIC_WRITE,
0,0,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,0))==INVALID_HANDLE_VALUE)
{
char buffer[256];
sprintf_s(buffer, "CreateFile(%s) failed with %d", settings.port, GetLastError());
MessageBox(NULL, buffer, "debug", MB_OK);
hPort=NULL;
return false;
}
Run Code Online (Sandbox Code Playgroud)
我看到消息框说"CreateFile(COM1)失败了5",5是根据此链接 "拒绝访问"错误的错误代码.
所以问题是为什么在启动Windows之后打开COM端口会出现这样的错误并在几秒钟或几分钟之后正常进行?
更新:COM端口是真实的.
Update2:关于之前打开串口的其他应用程序WinLIRC.我做了以下操作:我将Process Explorer放到Startup文件夹中,因此它也会在登录时启动,然后重新启动.一旦进程浏览器启动,我运行"查找句柄或Dll"对话框,将"Serial0"放入输入并点击"搜索".到那时,WinLIRC已经显示消息框,说"CreateFile(COM1)失败了5".然后我等到进程资源管理器搜索结束,看到它什么也没找到,然后尝试重新初始化WinLIRC并再次失败.所以我建议不是其他应用程序打开串口的情况.如果有人能提出更好的检查方法,我会很高兴地重新检查.
当我在WinLIRC运行时在进程资源管理器中搜索"Serial0"时,它会找到该winlirc.exe进程,因此看起来它是正确的搜索术语.
Update3:关于串行鼠标驱动程序.它不是在设备管理器中列出,所以我没能有禁用它,但是我发现这对如何禁用指令sermouse服务,并没有帮助.
Update4:我还忘了提一件事.只有在我启动PC后很快登录才会发生这种情况.如果我在登录屏幕上将窗口保留几分钟并稍后登录,则WinLIRC会始终初始化而不会出现任何问题.
Update5:不幸的是,我无法访问出现此问题的计算机,因此我无法再进行实验了.
我在sdcard上创建文件夹和文件时遇到问题.
这是代码:
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/folder");
boolean success;
if (!folder.exists()) {
success = folder.mkdirs();
}
File obdt = new File(folder, "file.txt");
try {
success = obdt.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
使用此代码,我希望在SD卡的文件夹folder中创建该文件Download夹,并在此文件中file.我希望用户可以访问该文件.所以我想把它放在一个共享文件夹中.
该success变量是true,当我再次运行该代码的文件夹已经存在,并且犯规进来,如果块.
但我无法在文件资源管理器中的SD卡上看到创建的文件夹和文件.
信息:getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()退货storage/sdcard/Download
我和Galaxy Nexus一起工作.
我正在尝试在文件夹中创建一个文件夹,首先我检查该目录是否存在并在必要时创建它:
name = "User1"
if not os.path.exists("/pdf_files/%s" % name):
os.makedirs('/pdf_files/%s' % name )
Run Code Online (Sandbox Code Playgroud)
问题是我收到了一个错误: OSError: [Errno 13] Permission denied: '/pdf_files'
这个名为的文件夹:pdf_file我创建的文件夹具有所有权限:drwxrwxrwx或'777'
我搜索了这个,我看到了一些解决方案,但没有一个解决了我的问题.有人能帮助我吗?
我试图阻止我的进程中的第三方DLL读取我打开的文件,我发现它是......好吧,不可能.
无论我做什么,无论我指定什么共享标志,他们的呼叫似乎总是成功!
以下是Process Monitor的截图 - 第一个CreateFile电话是我的,剩下的是他们的:
这怎么可能呢?为什么"共享模式:无"对我说谎,我该如何防止这种情况?
下面的代码是一个重现问题的示例:
#include <stdio.h>
#include <Windows.h>
int main()
{
LPCTSTR file = TEXT("C:\\Test1234.xml");
HANDLE hFile1 =
CreateFile(file, FILE_READ_ATTRIBUTES, 0, NULL, OPEN_ALWAYS, 0, NULL);
HANDLE hFile2 =
CreateFile(file, FILE_READ_DATA, 0, NULL, OPEN_ALWAYS, 0, NULL);
DWORD n;
BYTE buf[1];
printf("%d\n", ReadFile(hFile2, buf, sizeof(buf), &n, NULL));
CloseHandle(hFile1);
CloseHandle(hFile2);
DeleteFile(file);
}
Run Code Online (Sandbox Code Playgroud) createfile ×10
winapi ×6
file ×2
serial-port ×2
android ×1
asynchronous ×1
c ×1
directory ×1
download ×1
fopen ×1
getlasterror ×1
html5 ×1
iocp ×1
javascript ×1
php ×1
printing ×1
python ×1
sd-card ×1
synchronous ×1
windows ×1