2017-04-11 30 views
3

我编写了一个小程序来跟踪我的剪贴板活动并使用反应香蕉和System.Clipboard将其打印到终端。从剪贴板中读取权限被拒绝

module Main where 

import Reactive.Banana 
import Reactive.Banana.Frameworks 
import System.Clipboard 
import Data.Maybe(fromJust) 

main :: IO() 
main = do 
    sources <- (,) <$> newAddHandler <*> newAddHandler 
    network <- setupNetwork sources 
    actuate network 
    s <- getClipboardString 
    loop s sources 

loop s (epop, epush) = do 
    c <- getClipboardString 
    if s /= c then 
     snd epush [fromJust c] 
    else 
     loop s (epop, epush) 

setupNetwork (epop, epush) = compile $ do 
    ePop <- fromAddHandler $ fst epop 
    ePush <- fromAddHandler $ fst epush 

    bStack <- accumB [""] $ (++) <$> ePush 
    eStack <- changes bStack 

    reactimate' $ fmap print <$> eStack 

当我运行它时,我移动到另一个窗口(如chrome)并复制一些文本。当我这样做时,我得到Main.hs: CloseClipboard: invalid argument (Thread does not have a clipboard open.)。我在Windows上运行这个。 任何帮助将是伟大的!

干杯

+0

适用于Windows 10 64bit,stackage 1.3.2,ghci 8.0.1。 ''直接在ghci工作中做getClipboardString'吗? –

+0

是的,当我在ghci中使用剪贴板功能时,一切都按预期工作。我会比较今天晚些时候的版本,看看它是不是原因, –

+0

@ja。你能给我你在终端上输入的命令吗?我的版本与您的版本相同,但仍然无效。 –

回答

0

经过一些研究,我相信我找到了问题的原因。发生了什么事情是,当我将新文本复制到剪贴板时,程序锁定了程序,因此不会发生其他更改。在此锁定时间内,我的程序试图访问剪贴板并发生错误。为了解决这个问题,我使用Either使用try来自Control.Exception将呼叫打包为getClipboardString,然后模式匹配错误。

c <- try getClipboardString :: IO (Either SomeException (Maybe String)) 
case c of 
    Left err -> loop s (epop, epush) --ignore 
    Right clip -> --do something usefull